diff --git a/.github/test-spec.yml b/.github/test-spec.yml new file mode 100644 index 000000000000..1d3e04fe75b0 --- /dev/null +++ b/.github/test-spec.yml @@ -0,0 +1,266 @@ +# This is the Jenkins ci variant of the .github/labler.yaml + +"CI-run-zephyr-twister": + - any: + - "!.github/**/*" + - "!doc/**/*" + - "!CODEOWNERS" + - "!LICENSE" + - "!**/*.rst" + - "!VERSION" + - "!submanifests/**/*" + - "!MAINTAINERS.yml" + - "!version.h.in" + - "!Jenkinsfile" + - "!**/*.md" + +"CI-iot-zephyr-lwm2m-test": + - "drivers/console/**/*" + - "drivers/flash/**/*" + - "subsys/dfu/boot/**/*" + - "subsys/net/ip/**/*" + - "subsys/net/lib/http/**/*" + - "subsys/net/lib/lwm2m//**/*" + - "subsys/net/**/*" + +"CI-iot-samples-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/**/*" + - "subsys/net/lib/**/*" + +"CI-iot-libraries-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/socket_ncs.h" + - "subsys/testsuite/ztest/**/*" + +"CI-lwm2m-test": +# Not necessary to run tests on changes to this repo. + +"CI-boot-dfu-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" + +"CI-tfm-test": + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "modules/trusted-firmware-m/**/*" + - "samples/tfm_integration/**/*" + +"CI-ble-test": + - any: + - "drivers/bluetooth/**/*" + - any: + - "dts/arm/nordic/nrf5*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + - any: + - "include/zephyr/bluetooth/**/*" + - "!include/zephyr/bluetooth/mesh/**/*" + - any: + - "samples/bluetooth/**/*" + - "!samples/bluetooth/mesh/**/*" + - "!samples/bluetooth/mesh_demo/**/*" + - "!samples/bluetooth/mesh_provisioner/**/*" + - any: + - "tests/bluetooth/**/*" + - "!tests/bluetooth/mesh/**/*" + - "!tests/bluetooth/mesh_shell/**/*" + - "!tests/bluetooth/audio/**/*" + +"CI-mesh-test": + - "subsys/bluetooth/mesh/**/*" + - "include/zephyr/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh_demo/**/*" + - "samples/bluetooth/mesh_provisioner/**/*" + - "tests/bluetooth/mesh/**/*" + - "tests/bluetooth/mesh_shell/**/*" + +"CI-zigbee-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + +"CI-thingy91-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "arch/x86/core/**/*" + - "arch/x86/include/**/*" + - "drivers/console/**/*" + - "drivers/ethernet/**/*" + - "drivers/flash/**/*" + - "drivers/hwinfo/**/*" + - "drivers/interrupt_controller/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/timer/**/*" + - "include/**/*" + - "kernel/**/*" + - "lib/libc/common/source/stdlib/**/*" + - "lib/libc/newlib/**/*" + - "lib/libc/picolibc/**/*" + - "lib/os/**/*" + - "lib/posix/**/*" + - "misc/**/*" + - "modules/mbedtls/**/*" + - "soc/x86/ia32/**/*" + - "subsys/fs/fcb/**/*" + - "subsys/logging/**/*" + - "subsys/net/**/*" + - "subsys/random/**/*" + - "subsys/settings/include/**/*" + - "subsys/settings/src/**/*" + - "subsys/stats/**/*" + - "subsys/storage/flash_map/**/*" + - "subsys/storage/stream/**/*" + - "subsys/tracing/**/*" + +"CI-desktop-test": + - "**/*" + +"CI-crypto-test": + - "boards/arm/nrf52840dk_nrf52840/**/*" + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "drivers/serial/**/*" + - "dts/arm/nordic/nrf52840*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "include/drivers/serial/**/*" + - "modules/mbedtls/**/*" + +"CI-fem-test": + - "**/*" + +"CI-rs-test": + - "**/*" + +"CI-thread-test": + - "include/zephyr/net/**/*" + - "modules/mbedtls/**/*" + - "modules/openthread/**/*" + - "samples/net/openthread/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-nfc-test": + - "**/*" + +"CI-matter-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "drivers/net/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + +"CI-find-my-test": + - "**/*" + +"CI-gazell-test": + - "**/*" + +"CI-rpc-test": + - "**/*" + +"CI-modemshell-test": + - "include/net/**/*" + - "include/posix/**/*" + - "include/shell/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "subsys/shell/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-positioning-test": + - "include/net/**/*" + - "include/posix/**/*" + - "drivers/net/**/*" + - "drivers/wifi/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-cloud-test": + - "include/zephyr/dfu/**/*" + - "include/zephyr/net/**/*" + - "include/zephyr/posix/**/*" + - "include/zephyr/settings/**/*" + - "drivers/led/**/*" + - "drivers/net/**/*" + - "drivers/sensor/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "lib/posix/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-wifi": + - "subsys/net/l2/wifi/**/*" + - "subsys/net/l2/ethernet/**/*" + +"CI-sidewalk-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + +"CI-audio-test": + - "boards/arm/nrf5340_audio_dk_nrf5340/**/*" + - "drivers/flash/**/*" + - "drivers/spi/**/*" + - "drivers/gpio/**/*" + - "drivers/i2c/**/*" + - "drivers/watchdog/**/*" + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/bluetooth/audio/**/*" + - "subsys/bluetooth/host/**/*" + - "subsys/dfu/**/*" + - "subsys/fs/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "subsys/sd/**/*" + - "subsys/storage/**/*" + - "subsys/task_wdt/**/*" + - "subsys/usb/**/*" + - "subsys/zbus/**/*" + +"CI-pmic-samples-test": + - "samples/shields/npm1300_ek/**/*" + - "boards/shields/npm1300_ek/**/*" + - "**/**npm1300**/**" + - "drivers/regulator/regulator_common.c" + - "drivers/regulator/regulator_shell.c" + - "drivers/gpio/gpio_shell.c" + - "drivers/sensor/sensor_shell.c" diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 0aa8d5cd690d..34b4b8595a9e 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -8,8 +8,7 @@ concurrency: jobs: clang-build: - if: github.repository_owner == 'zephyrproject-rtos' - runs-on: zephyr-runner-linux-x64-4xlarge + runs-on: ubuntu-latest container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' @@ -19,11 +18,13 @@ jobs: fail-fast: false matrix: platform: ["native_posix"] + subset: [1, 2, 3, 4, 5] env: ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.3 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 }} + MATRIX_SIZE: 5 outputs: report_needed: ${{ steps.twister.outputs.report_needed }} steps: @@ -86,7 +87,7 @@ jobs: id: cache-ccache uses: zephyrproject-rtos/action-s3-cache@v1.2.0 with: - key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.platform }}-ccache + key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.subset }}-ccache path: /github/home/.cache/ccache aws-s3-bucket: ccache.zephyrproject.org aws-access-key-id: ${{ vars.AWS_CCACHE_ACCESS_KEY_ID }} @@ -99,6 +100,16 @@ jobs: test -d github/home/.cache/ccache && rm -rf /github/home/.cache/ccache && mv github/home/.cache/ccache /github/home/.cache/ccache ccache -M 10G -s + - name: Build test plan with Twister + id: twister_test_plan + 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 -p native_posix -c origin/${BASE_REF}.. + + - name: Run Tests with Twister id: twister run: | @@ -112,7 +123,7 @@ jobs: if [ -s testplan.json ]; then echo "report_needed=1" >> $GITHUB_OUTPUT # Full twister but with options based on changes - ./scripts/twister --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 + ./scripts/twister --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 --subset ${{matrix.subset}}/${MATRIX_SIZE} else # if nothing is run, skip reporting step echo "report_needed=0" >> $GITHUB_OUTPUT @@ -127,7 +138,7 @@ jobs: if: always() && steps.twister.outputs.report_needed != 0 uses: actions/upload-artifact@v3 with: - name: Unit Test Results (Subset ${{ matrix.platform }}) + name: Unit Test Results (Subset ${{ matrix.subset }}) path: twister-out/twister.xml clang-build-results: diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml new file mode 100644 index 000000000000..9e0323f94987 --- /dev/null +++ b/.github/workflows/commit-tags.yml @@ -0,0 +1,31 @@ +name: Commit tags + +on: pull_request + +jobs: + commit_tags: + runs-on: ubuntu-22.04 + name: Run commit tags checks on patch series (PR) + steps: + - name: Update PATH for west + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Checkout the code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Install python dependencies + run: | + pip3 install setuptools + pip3 install wheel + pip3 install gitlint + + - name: Run the commit tags + uses: nrfconnect/action-commit-tags@main + with: + target: '.' + baserev: origin/${{ github.base_ref }} + revrange: 'none' diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index de1decb2cc65..036729418cb4 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -38,8 +38,8 @@ jobs: git config --global user.name "Your Name" git remote -v # 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) + #[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ + #(echo "::error ::Merge commits not allowed, rebase instead";false) git rebase origin/${BASE_REF} # debug git log --pretty=oneline | head -n 10 @@ -57,8 +57,8 @@ jobs: # debug ls -la git log --pretty=oneline | head -n 10 - ./scripts/ci/check_compliance.py --annotate -e KconfigBasic \ - -c origin/${BASE_REF}.. + ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e Kconfig \ + -e KconfigBasicNoModules -e ModulesMaintainers -c origin/${BASE_REF}.. - name: upload-results uses: actions/upload-artifact@v3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 164d82fde0e8..97bcd98d0d74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1806,8 +1806,15 @@ endif() # Generate and use MCUboot related artifacts as needed. if(CONFIG_BOOTLOADER_MCUBOOT) get_target_property(signing_script zephyr_property_target SIGNING_SCRIPT) + if(NOT signing_script) - set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) + zephyr_get(signing_script VAR SIGNING_SCRIPT SYSBUILD) + + if(signing_script) + set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${signing_script}) + else() + set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) + endif() endif() endif() diff --git a/CODEOWNERS b/CODEOWNERS index 8872e7381c54..2c8b9db39617 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,6 +18,7 @@ # component or code. This file is going to be deprecated and currently only had # entries that are not covered by the MAINTAINERS file. +/.github/test-spec.yml @nrfconnect/ncs-test-leads /soc/arm/aspeed/ @aspeeddylan /soc/arm/atmel_sam/common/*_sam4l_*.c @nandojve /soc/arm/atmel_sam/sam3x/ @ioannisg diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000000..3b9cf0022399 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,5 @@ +@Library("CI_LIB") _ + +def pipeline = new ncs.sdk_zephyr.Main() + +pipeline.run(JOB_NAME) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 97d0ec0222fa..d7623c89137f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -707,7 +707,6 @@ Documentation: - doc/images/Zephyr-Kite-in-tree.png - doc/index-tex.rst - doc/index.rst - - doc/kconfig.rst - doc/known-warnings.txt - doc/templates/sample.tmpl - doc/templates/board.tmpl @@ -2473,7 +2472,7 @@ GD32 Platforms: - dts/*/gigadevice/ - dts/bindings/*/*gd32* - soc/arm/gigadevice/ - - soc/riscv/riscv-privileged/gd32vf103/ + - soc/riscv/gd_gd32/ - scripts/west_commands/*/*gd32* labels: - "platform: GD32" @@ -2851,7 +2850,7 @@ ITE Platforms: - drivers/*/*it8xxx2*.c - dts/bindings/*/*ite* - dts/riscv/ite/ - - soc/riscv/riscv-ite/ + - soc/riscv/ite_ec/ labels: - "platform: ITE" diff --git a/arch/arc/core/arc_smp.c b/arch/arc/core/arc_smp.c index 9fb43c411524..1aa61be53f05 100644 --- a/arch/arc/core/arc_smp.c +++ b/arch/arc/core/arc_smp.c @@ -145,7 +145,7 @@ void arch_sched_ipi(void) } } -static int arc_smp_init(void) +int arch_smp_init(void) { struct arc_connect_bcr bcr; @@ -188,6 +188,5 @@ static int arc_smp_init(void) return 0; } - -SYS_INIT(arc_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index 75a64ea90eba..4afe6c06ab50 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -268,9 +268,6 @@ choice config FP_HARDABI bool "Floating point Hard ABI" - # TF-M build system does not build the NS app and libraries correctly with Hard ABI. - # This limitation should be removed in the next TF-M synchronization. - depends on !TFM_BUILD_NS help This option selects the Floating point ABI in which hardware floating point instructions are generated and uses FPU-specific calling diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index 2aeb36c1735a..c17f2fa048fc 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -245,7 +245,7 @@ void arch_sched_ipi(void) broadcast_ipi(SGI_SCHED_IPI); } -static int arm_smp_init(void) +int arch_smp_init(void) { cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR()); @@ -259,6 +259,6 @@ static int arm_smp_init(void) return 0; } -SYS_INIT(arm_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm/core/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig index 95e05604783d..61dd3dbba3c9 100644 --- a/arch/arm/core/cortex_m/Kconfig +++ b/arch/arm/core/cortex_m/Kconfig @@ -283,7 +283,20 @@ config ARMV8_1_M_MVEF supporting the M-Profile Vector Extension (MVE) floating-point instruction set. -menu "ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33 options" +config ARMV8_1_M_PMU + bool + help + This option is enabled when the CPU implements ARMv8-M Performance + Monitoring Unit (PMU). + +config ARMV8_M_PMU_EVENTCNT + int "Number of event counters in the Performance Monitoring Unit" + depends on ARMV8_1_M_PMU + range 2 8 + help + The number of event counters implemented. + +menu "ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33/M55 options" depends on ARMV6_M_ARMV8_M_BASELINE || ARMV7_M_ARMV8_M_MAINLINE config GEN_ISR_TABLES diff --git a/arch/arm/core/mpu/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c index 6af62f840782..cfe1230c907e 100644 --- a/arch/arm/core/mpu/arm_mpu_regions.c +++ b/arch/arm/core/mpu/arm_mpu_regions.c @@ -8,6 +8,9 @@ #include #include +#if USE_PARTITION_MANAGER +#include +#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -21,6 +24,14 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", +#if USE_PARTITION_MANAGER + PM_SRAM_ADDRESS, +#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) + REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), +#else + REGION_RAM_ATTR(REGION_SRAM_SIZE)), +#endif +#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -28,6 +39,8 @@ static const struct arm_mpu_region mpu_regions[] = { #else REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif + +#endif /* USE_PARTITION_MANAGER */ }; const struct arm_mpu_config mpu_config = { diff --git a/arch/arm64/core/prep_c.c b/arch/arm64/core/prep_c.c index c12d5e7d1c43..510476d2ef7a 100644 --- a/arch/arm64/core/prep_c.c +++ b/arch/arm64/core/prep_c.c @@ -69,6 +69,7 @@ void z_arm64_prep_c(void) CODE_UNREACHABLE; } + #if CONFIG_MP_MAX_NUM_CPUS > 1 extern FUNC_NORETURN void z_arm64_secondary_start(void); void z_arm64_secondary_prep_c(void) diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index e67032eb2a48..043e07eb3054 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -279,7 +279,7 @@ void arch_spin_relax(void) } #endif -static int arm64_smp_init(void) +int arch_smp_init(void) { cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR()); @@ -302,6 +302,6 @@ static int arm64_smp_init(void) return 0; } -SYS_INIT(arm64_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index a1cefcbdf43a..a816d1c55017 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -47,6 +47,12 @@ config INCLUDE_RESET_VECTOR Include the reset vector stub, which initializes the stack and prepares for running C code. +config RISCV_PRIVILEGED + bool + select ARCH_HAS_RAMFUNC_SUPPORT if XIP + help + Option selected by SoCs implementing the RISC-V privileged ISA. + config RISCV_SOC_HAS_ISR_STACKING bool depends on !USERSPACE @@ -147,13 +153,32 @@ config RISCV_SOC_OFFSETS in offsets.h. The last one should not end in a semicolon. See gen_offset.h for more details. +config RISCV_HAS_PLIC + bool + depends on RISCV_PRIVILEGED + help + Does the SOC provide support for a Platform Level Interrupt Controller (PLIC). + +config RISCV_HAS_CLIC + bool + depends on RISCV_PRIVILEGED + help + Does the SOC provide support for a Core-Local Interrupt Controller (CLIC). + +config RISCV_SOC_EXCEPTION_FROM_IRQ + bool + help + Option selected by SoCs that require a custom mechanism to check if + an exception is the result of an interrupt or not. If selected, + __soc_is_irq() needs to be implemented by the SoC. + config RISCV_SOC_INTERRUPT_INIT bool "SOC-based interrupt initialization" help Enable SOC-based interrupt initialization (call soc_interrupt_init, within _IntLibInit when enabled) -config RISCV_SOC_MCAUSE_EXCEPTION_MASK +config RISCV_MCAUSE_EXCEPTION_MASK hex default 0x7FFFFFFFFFFFFFFF if 64BIT default 0x7FFFFFFF @@ -168,11 +193,6 @@ config RISCV_GENERIC_TOOLCHAIN Allow SOCs that have custom extended riscv ISA to still compile with generic riscv32 toolchain. -config RISCV_HAS_CPU_IDLE - bool "Does SOC has CPU IDLE instruction" - help - Does SOC has CPU IDLE instruction - config GEN_ISR_TABLES default y @@ -333,7 +353,7 @@ config RISCV_TRAP_HANDLER_ALIGNMENT The minimum alignment is 4 bytes according to the Spec. config GEN_IRQ_VECTOR_TABLE - select RISCV_VECTORED_MODE if SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_VECTORED_MODE if RISCV_PRIVILEGED config ARCH_HAS_SINGLE_THREAD_SUPPORT default y if !SMP diff --git a/arch/riscv/core/cpu_idle.c b/arch/riscv/core/cpu_idle.c index 0c7f5f3dac78..0d8e4fedeb2f 100644 --- a/arch/riscv/core/cpu_idle.c +++ b/arch/riscv/core/cpu_idle.c @@ -5,24 +5,18 @@ */ #include - -/* - * In RISC-V there is no conventional way to handle CPU power save. - * Each RISC-V SOC handles it in its own way. - * Hence, by default, arch_cpu_idle and arch_cpu_atomic_idle functions just - * unlock interrupts and return to the caller, without issuing any CPU power - * saving instruction. - * - * Nonetheless, define the default arch_cpu_idle and arch_cpu_atomic_idle - * functions as weak functions, so that they can be replaced at the SOC-level. - */ +#include void __weak arch_cpu_idle(void) { + sys_trace_idle(); irq_unlock(MSTATUS_IEN); + __asm__ volatile("wfi"); } void __weak arch_cpu_atomic_idle(unsigned int key) { + sys_trace_idle(); irq_unlock(key); + __asm__ volatile("wfi"); } diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index 171497ff0cac..6e8831f1026f 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -167,7 +167,7 @@ void _Fault(z_arch_esf_t *esf) __asm__ volatile("csrr %0, mtval" : "=r" (mtval)); #endif - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; LOG_ERR(""); LOG_ERR(" mcause: %ld, %s", mcause, cause_str(mcause)); #ifndef CONFIG_SOC_OPENISA_RV32M1_RISCV32 diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index e0ef1374bf15..f95b099a4da5 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -10,6 +10,10 @@ #include #include +#ifdef CONFIG_RISCV_HAS_PLIC +#include +#endif + LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); FUNC_NORETURN void z_irq_spurious(const void *unused) @@ -20,11 +24,11 @@ FUNC_NORETURN void z_irq_spurious(const void *unused) mcause = csr_read(mcause); - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; LOG_ERR("Spurious interrupt detected! IRQ: %ld", mcause); #if defined(CONFIG_RISCV_HAS_PLIC) - if (mcause == RISCV_MACHINE_EXT_IRQ) { + if (mcause == RISCV_IRQ_MEXT) { unsigned int save_irq = riscv_plic_get_irq(); const struct device *save_dev = riscv_plic_get_dev(); diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index c36679ae6db9..982e6777b367 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "asm_macros.inc" @@ -50,7 +51,9 @@ /* imports */ GDATA(_sw_isr_table) +#ifdef CONFIG_RISCV_SOC_EXCEPTION_FROM_IRQ GTEXT(__soc_is_irq) +#endif GTEXT(__soc_handle_irq) GTEXT(_Fault) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE @@ -90,7 +93,8 @@ GTEXT(_isr_wrapper) * what standard behavior is defined). Hence, the arch level code expects * the following functions to be provided at the SOC level: * - * - __soc_is_irq: decide if we're handling an interrupt or an exception + * - __soc_is_irq (optional): decide if we're handling an interrupt or an + exception * - __soc_handle_irq: handle SoC-specific details for a pending IRQ * (e.g. clear a pending bit in a SoC-specific register) * @@ -283,10 +287,14 @@ no_fp: /* increment _current->arch.exception_depth */ * function (that needs to be implemented by each SOC). The result is * returned via register a0 (1: interrupt, 0 exception) */ +#ifdef CONFIG_RISCV_SOC_EXCEPTION_FROM_IRQ jal ra, __soc_is_irq - - /* If a0 != 0, jump to is_interrupt */ bnez a0, is_interrupt +#else + csrr t0, mcause + srli t0, t0, RISCV_MCAUSE_IRQ_POS + bnez t0, is_interrupt +#endif /* * If the exception is the result of an ECALL, check whether to @@ -294,22 +302,22 @@ no_fp: /* increment _current->arch.exception_depth */ * to report the exception. */ csrr t0, mcause - li t2, SOC_MCAUSE_EXP_MASK + li t2, CONFIG_RISCV_MCAUSE_EXCEPTION_MASK and t0, t0, t2 /* - * If mcause == SOC_MCAUSE_ECALL_EXP, handle system call from + * If mcause == RISCV_EXC_ECALLM, handle system call from * kernel thread. */ - li t1, SOC_MCAUSE_ECALL_EXP + li t1, RISCV_EXC_ECALLM beq t0, t1, is_kernel_syscall #ifdef CONFIG_USERSPACE /* - * If mcause == SOC_MCAUSE_USER_ECALL_EXP, handle system call + * If mcause == RISCV_EXC_ECALLU, handle system call * for user mode thread. */ - li t1, SOC_MCAUSE_USER_ECALL_EXP + li t1, RISCV_EXC_ECALLU beq t0, t1, is_user_syscall #endif /* CONFIG_USERSPACE */ @@ -527,7 +535,7 @@ on_irq_stack: /* Get IRQ causing interrupt */ csrr a0, mcause - li t0, SOC_MCAUSE_EXP_MASK + li t0, CONFIG_RISCV_MCAUSE_EXCEPTION_MASK and a0, a0, t0 /* diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 7730138a3769..96982341b1a7 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -16,7 +16,6 @@ #include #include #include -#include #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE #include @@ -25,6 +24,8 @@ #include #endif +#include + /* struct _callee_saved member offsets */ GEN_OFFSET_SYM(_callee_saved_t, sp); GEN_OFFSET_SYM(_callee_saved_t, ra); diff --git a/arch/riscv/core/prep_c.c b/arch/riscv/core/prep_c.c index 8b9b118b24cd..b486b4949d89 100644 --- a/arch/riscv/core/prep_c.c +++ b/arch/riscv/core/prep_c.c @@ -20,6 +20,10 @@ #include #include +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void); +#endif + /** * * @brief Prepare to and run C code diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 6154450e58d2..99f67f57eccf 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include volatile struct { @@ -22,6 +23,10 @@ volatile void *riscv_cpu_sp; extern void __start(void); +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void); +#endif + void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) { @@ -67,14 +72,15 @@ void z_riscv_secondary_cpu_init(int hartid) z_riscv_pmp_init(); #endif #ifdef CONFIG_SMP - irq_enable(RISCV_MACHINE_SOFT_IRQ); + irq_enable(RISCV_IRQ_MSOFT); #endif riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg); } #ifdef CONFIG_SMP -#define MSIP(hartid) ((volatile uint32_t *)RISCV_MSIP_BASE)[hartid] +#define MSIP_BASE 0x2000000UL +#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid] static atomic_val_t cpu_pending_ipi[CONFIG_MP_MAX_NUM_CPUS]; #define IPI_SCHED 0 @@ -104,7 +110,7 @@ void z_riscv_flush_fpu_ipi(unsigned int cpu) } #endif -static void ipi_handler(const void *unused) +static void sched_ipi_handler(const void *unused) { ARG_UNUSED(unused); @@ -151,14 +157,13 @@ void arch_spin_relax(void) } #endif -static int riscv_smp_init(void) +int arch_smp_init(void) { - IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 0, ipi_handler, NULL, 0); - irq_enable(RISCV_MACHINE_SOFT_IRQ); + IRQ_CONNECT(RISCV_IRQ_MSOFT, 0, sched_ipi_handler, NULL, 0); + irq_enable(RISCV_IRQ_MSOFT); return 0; } - -SYS_INIT(riscv_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif /* CONFIG_SMP */ diff --git a/arch/x86/core/intel64/irq.c b/arch/x86/core/intel64/irq.c index a73042717462..09b1961585cb 100644 --- a/arch/x86/core/intel64/irq.c +++ b/arch/x86/core/intel64/irq.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -154,7 +155,7 @@ void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) #if defined(CONFIG_SMP) -void z_x86_ipi_setup(void) +int arch_smp_init(void) { /* * z_sched_ipi() doesn't have the same signature as a typical ISR, so @@ -166,8 +167,11 @@ void z_x86_ipi_setup(void) /* TLB shootdown handling */ x86_irq_funcs[CONFIG_TLB_IPI_VECTOR - IV_IRQS] = z_x86_tlb_ipi; + return 0; } +SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + /* * it is not clear exactly how/where/why to abstract this, as it * assumes the use of a local APIC (but there's no other mechanism). diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index ee095efe33d1..8f7618495a90 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -74,7 +74,7 @@ FUNC_NORETURN void z_x86_prep_c(void *arg) #endif #if defined(CONFIG_SMP) - z_x86_ipi_setup(); + arch_smp_init(); #endif z_cstart(); diff --git a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi index 200db7f94c7a..3d31ede313fe 100644 --- a/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi +++ b/boards/arm/arduino_nano_33_ble/arduino_nano_33_ble-common.dtsi @@ -189,6 +189,10 @@ arduino_spi: &spi2 { status = "okay"; }; +&gpiote { + status = "okay"; +}; + &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; diff --git a/boards/arm/b_u585i_iot02a/CMakeLists.txt b/boards/arm/b_u585i_iot02a/CMakeLists.txt index dde738046651..f6ca91f1a73b 100644 --- a/boards/arm/b_u585i_iot02a/CMakeLists.txt +++ b/boards/arm/b_u585i_iot02a/CMakeLists.txt @@ -10,6 +10,6 @@ endif() if(CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands #Execute post build script postbuild.sh - COMMAND $/postbuild.sh ${COMPILER_FULL_PATH} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index ae1e57aba8e8..6b3b72554fff 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -16,4 +16,15 @@ config SPI_STM32_INTERRUPT config USE_DT_CODE_PARTITION default y if TRUSTED_EXECUTION_NONSECURE +if BUILD_WITH_TFM + +# Initial Attestation key provisioned by the BL1 bootloader +config TFM_INITIAL_ATTESTATION_KEY + default y + +config TFM_DUMMY_PROVISIONING + default n + +endif # BUILD_WITH_TFM + endif # BOARD_B_U585I_IOT02A diff --git a/boards/arm/b_u585i_iot02a/doc/index.rst b/boards/arm/b_u585i_iot02a/doc/index.rst index 3c794b4de792..5512a95f16dd 100644 --- a/boards/arm/b_u585i_iot02a/doc/index.rst +++ b/boards/arm/b_u585i_iot02a/doc/index.rst @@ -346,14 +346,14 @@ can be generated using ``b_u585i_iot02a_ns`` as build target. $ west build -b b_u585i_iot02a_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/postbuild.sh`` bash script is run automatically in a post-build step to make some required flash layout changes. Once the build is completed, run the following script to initialize the option bytes. .. code-block:: bash - $ build/tfm/regression.sh + $ build/tfm/api_ns/regression.sh Finally, to flash the board, run: diff --git a/boards/arm/bl5340_dvk/CMakeLists.txt b/boards/arm/bl5340_dvk/CMakeLists.txt index 541334195dd1..863c8bb599e0 100644 --- a/boards/arm/bl5340_dvk/CMakeLists.txt +++ b/boards/arm/bl5340_dvk/CMakeLists.txt @@ -9,7 +9,7 @@ zephyr_library_sources(bl5340_dvk_cpunet_reset.c) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/bl654_usb/bl654_usb.dts b/boards/arm/bl654_usb/bl654_usb.dts index 80600290dbff..fa814f4b80e4 100644 --- a/boards/arm/bl654_usb/bl654_usb.dts +++ b/boards/arm/bl654_usb/bl654_usb.dts @@ -59,6 +59,10 @@ status = "okay"; }; +&gpiote { + status = "okay"; +}; + &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; diff --git a/boards/arm/nrf52840_mdk/doc/index.rst b/boards/arm/nrf52840_mdk/doc/index.rst index fce05bee5937..6e0b24b65f2b 100644 --- a/boards/arm/nrf52840_mdk/doc/index.rst +++ b/boards/arm/nrf52840_mdk/doc/index.rst @@ -7,7 +7,7 @@ Overview ******** The nRF52840-MDK is a versatile, easy-to-use IoT hardware platform for -Bluetooth 5, Bluetooth mesh, Thread, IEEE 802.15.4, ANT and 2.4GHz proprietary +Bluetooth 5, Bluetooth Mesh, Thread, IEEE 802.15.4, ANT and 2.4GHz proprietary applications using the nRF52840 SoC. The development kit comes with a fully integrated debugger (also known as diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index dcee7b0db5fd..60c3ecf55a12 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -149,18 +149,18 @@ &gpio0 { status = "okay"; - gpio-reserved-ranges = <0 11>, <17 7>, <26 6>; - gpio-line-names = "", "", "", "", "", "", "", "", - "", "", "", "BUTTON1", "BUTTON2", "LED1", "LED2", "LED3", - "LED4", "", "", "", "", "", "", "", - "BUTTON3", "BUTTON4", "", "", "", "", "", ""; + gpio-reserved-ranges = <0 2>, <6 1>, <8 3>, <17 7>; + gpio-line-names = "XL1", "XL2", "AREF", "A0", "A1", "RTS", "TXD", + "CTS", "RXD", "NFC1", "NFC2", "BUTTON1", "BUTTON2", "LED1", + "LED2", "LED3", "LED4", "QSPI CS", "RESET", "QSPI CLK", + "QSPI DIO0", "QSPI DIO1", "QSPI DIO2", "QSPI DIO3","BUTTON3", + "BUTTON4", "SDA", "SCL", "A2", "A3", "A4", "A5"; }; &gpio1 { status = "okay"; - gpio-reserved-ranges = <0 1>, <9 1>, <12 4>; gpio-line-names = "", "D0", "D1", "D2", "D3", "D4", "D5", "D6", - "D7", "", "D8", "D9", "", "", "", ""; + "D7", "", "D8", "D9", "D10", "D11", "D12", "D13"; }; &uart0 { diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt index c950fd917246..fa1c1ba14d93 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt +++ b/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt @@ -8,7 +8,7 @@ if ((CONFIG_BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340_AUDIO_ if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c index 4368ca303fc1..f9082e6ca400 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c @@ -10,8 +10,7 @@ #include #include - -#include +#include LOG_MODULE_REGISTER(nrf5340_audio_dk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -25,11 +24,11 @@ static int core_config(void) { nrf_gpiote_latency_t latency; - latency = nrfx_gpiote_latency_get(); + latency = nrf_gpiote_latency_get(NRF_GPIOTE); if (latency != NRF_GPIOTE_LATENCY_LOWPOWER) { LOG_DBG("Setting gpiote latency to low power"); - nrfx_gpiote_latency_set(NRF_GPIOTE_LATENCY_LOWPOWER); + nrf_gpiote_latency_set(NRF_GPIOTE, NRF_GPIOTE_LATENCY_LOWPOWER); } return 0; diff --git a/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt index 8ba3238c40bb..5128462d70cf 100644 --- a/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt +++ b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt @@ -8,7 +8,7 @@ zephyr_library_sources(nrf5340_cpunet_reset.c) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board new file mode 100644 index 000000000000..b76cfce6800b --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54H20PDK_NRF54H20_CPUAPP + bool "nRF54H20 PDK nRF54H20 Application MCU" + depends on SOC_NRF54H20_ENGA_CPUAPP + +config BOARD_NRF54H20PDK_NRF54H20_CPURAD + bool "nRF54H20 PDK nRF54H20 Radio MCU" + depends on SOC_NRF54H20_ENGA_CPURAD diff --git a/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig new file mode 100644 index 000000000000..954276ec8299 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "nrf54h20pdk_nrf54h20_cpuapp" if BOARD_NRF54H20PDK_NRF54H20_CPUAPP + default "nrf54h20pdk_nrf54h20_cpurad" if BOARD_NRF54H20PDK_NRF54H20_CPURAD + +if BOARD_NRF54H20PDK_NRF54H20_CPUAPP || BOARD_NRF54H20PDK_NRF54H20_CPURAD + +# Data cache is disabled due to a HW issue in the EngA SoC revision. +config DCACHE + default n + +endif # BOARD_NRF54H20PDK_NRF54H20_CPUAPP || BOARD_NRF54H20PDK_NRF54H20_CPURAD diff --git a/boards/arm/nrf54h20pdk_nrf54h20/board.cmake b/boards/arm/nrf54h20pdk_nrf54h20/board.cmake new file mode 100644 index 000000000000..4c63f1dd05ee --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp b/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp new file mode 100644 index 000000000000..bcda6b0732b3 Binary files /dev/null and b/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp differ diff --git a/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst b/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst new file mode 100644 index 000000000000..985e8d36d887 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst @@ -0,0 +1,148 @@ +.. _nrf54h20pdk_nrf54h20: + +nRF54H20 PDK +############ + +Overview +******** + +The nRF54H20 PDK is a single-board preview development kit for evaluation +and development on the Nordic nRF54H20 System-on-Chip (SoC). + +The nRF54H20 is a multicore SoC with: + +* an Arm Cortex-M33 core with DSP instructions, FPU, and Armv8-M Security + Extensions, running at up to 320 MHz, referred to as the **application core** +* an Arm Cortex-M33 core with DSP instructions, FPU, and Armv8-M Security + Extensions, running at up to 256 MHz, referred to as the **radio core**. + +The ``nrf54h20pdk_nrf54h20_cpuapp`` build target provides support for +the application core on the nRF54H20 SoC. +The ``nrf54h20pdk_nrf54h20_cpurad`` build target provides support for +the radio core on the nRF54H20 SoC. + +nRF54H20 SoC provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`GPIOTE (General Purpose Input Output tasks and events)` +* :abbr:`GRTC (Global real-time counter)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* MRAM +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf54h20pdk_nrf54h20.webp + :align: center + :alt: nRF54H20 PDK + + nRF54H20 PDK (Credit: Nordic Semiconductor) + +Hardware +******** + +nRF54H20 PDK has two crystal oscillators: + +* High-frequency 32 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +Supported Features +================== + +The nrf54h20pdk_nrf54h20_cpuapp board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIOTE | on-chip | gpio | ++-----------+------------+----------------------+ +| GRTC | on-chip | system clock | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ + +The nrf54h20pdk_nrf54h20_cpurad board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIOTE | on-chip | gpio | ++-----------+------------+----------------------+ +| GRTC | on-chip | system clock | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Connections and IOs +=================== + +LEDs +---- + +* LED1 (green) = P9.0 +* LED2 (green) = P9.1 +* LED3 (green) = P9.2 +* LED4 (green) = P9.3 + +Push buttons +------------ + +* BUTTON1 = P0.8 +* BUTTON2 = P0.9 +* BUTTON3 = P0.10 +* BUTTON4 = P0.11 +* RESET (SW1) + +Programming and Debugging +************************* + +Applications for both the ``nrf54h20pdk_nrf54h20_cpuapp`` and +``nrf54h20pdk_nrf54h20_cpurad`` targets 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 :ref:`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 nRF54H20 PDK, complete the following steps: + +First, connect the nRF54H20 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: nrf54h20pdk_nrf54h20_cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF54H20 PDK +************************************************ + +There are 2 samples that allow you to test that the buttons (switches) and LEDs +on the board are working properly with Zephyr: + +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts`. diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi new file mode 100644 index 000000000000..00f28fad9f18 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + reserved-memory { + cpuppr_ram3x_region: memory@2fc00000 { + compatible = "nordic,owned-memory"; + reg = <0x2fc00000 DT_SIZE_K(28)>; + status = "disabled"; + perm-read; + perm-write; + perm-execute; + }; + + ram3x_dma_region: memory@2fc07000 { + compatible = "nordic,owned-memory"; + reg = <0x2fc07000 DT_SIZE_K(4)>; + status = "disabled"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2fc07000 0x1000>; + + cpuapp_dma_region: memory@680 { + compatible = "zephyr,memory-region"; + reg = <0x680 DT_SIZE_K(2)>; + status = "disabled"; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM3x_APP"; + }; + + cpurad_dma_region: memory@e80 { + compatible = "zephyr,memory-region"; + reg = <0xe80 0x80>; + status = "disabled"; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM3x_RAD"; + }; + }; + }; +}; + +&mram1x { + cpurad_rx_partitions: cpurad-rx-partitions { + compatible = "nordic,owned-partitions", "fixed-partitions"; + status = "disabled"; + perm-read; + perm-execute; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + + cpurad_slot0_partition: partition@66000 { + reg = <0x66000 DT_SIZE_K(256)>; + }; + }; + + cpuapp_rx_partitions: cpuapp-rx-partitions { + compatible = "nordic,owned-partitions", "fixed-partitions"; + status = "disabled"; + perm-read; + perm-execute; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_slot0_partition: partition@a6000 { + reg = <0xa6000 DT_SIZE_K(512)>; + }; + + cpuppr_code_partition: partition@126000 { + reg = <0x126000 DT_SIZE_K(28)>; + }; + }; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi new file mode 100644 index 000000000000..d3b791203223 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart135_default: uart135_default { + group1 { + psels = , + ; + }; + + group2 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart135_sleep: uart135_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; + + /omit-if-no-ref/ uart136_default: uart136_default { + group1 { + psels = , + ; + }; + + group2 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart136_sleep: uart136_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts new file mode 100644 index 000000000000..359c1f843076 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpuapp"; + model = "Nordic nRF54H20 PDK nRF54H20 Application MCU"; + + chosen { + zephyr,console = &uart136; + zephyr,code-partition = &cpuapp_slot0_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpuapp_ram0; + }; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + + button2: button_2 { + gpios = <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + + button3: button_3 { + gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio9 0 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + + led1: led_1 { + gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + + led2: led_2 { + gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + + led3: led_3 { + gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; +}; + +&ram3x_dma_region { + status = "okay"; +}; + +&cpuapp_dma_region { + status = "okay"; +}; + +&cpuapp_rx_partitions { + status = "okay"; +}; + +&cpuppr_vpr { + source-memory = <&cpuppr_code_partition>; + execution-memory = <&cpuppr_ram3x_region>; +}; + +&gpiote130 { + status = "okay"; + owned-channels = <0 1 2 3 4 5 6 7>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio9 { + status = "okay"; +}; + +&grtc { + status = "okay"; + child-owned-channels = <5 6>; + nonsecure-channels = <5 6>; + owned-channels = <4 5 6>; +}; + +&uart135 { + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + status = "okay"; + memory-regions = <&cpuapp_dma_region>; + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml new file mode 100644 index 000000000000..a364c2863d37 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpuapp +name: nRF54H20-PDK-nRF54H20-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 32 +flash: 368 +supported: + - gpio diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig new file mode 100644 index 000000000000..1f7ef38a7fc6 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPUAPP=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPUAPP=y + +CONFIG_USE_DT_CODE_PARTITION=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) region is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=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/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts new file mode 100644 index 000000000000..02213d886455 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpurad"; + model = "Nordic nRF54H20 PDK nRF54H20 Radio MCU"; + + chosen { + zephyr,console = &uart135; + zephyr,code-partition = &cpurad_slot0_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpurad_ram0; + }; +}; + +&ram3x_dma_region { + status = "okay"; +}; + +&cpurad_dma_region { + status = "okay"; +}; + +&cpurad_rx_partitions { + status = "okay"; +}; + +&grtc { + status = "okay"; + child-owned-channels = <8 9 10 11 12>; + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>, + <108 NRF_DEFAULT_IRQ_PRIORITY>; + nonsecure-channels = <8 9 10 11 12>; + owned-channels = <7 8 9 10 11 12 13 14>; +}; + +&uart135 { + status = "okay"; + memory-regions = <&cpurad_dma_region>; + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml new file mode 100644 index 000000000000..d1c8548d07d0 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpurad +name: nRF54H20-PDK-nRF54H20-Radio +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 32 +flash: 368 +supported: + - gpio diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig new file mode 100644 index 000000000000..254d8656e611 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPURAD=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPURAD=y + +CONFIG_USE_DT_CODE_PARTITION=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) region is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board new file mode 100644 index 000000000000..d95fe51009f3 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54L15PDK_NRF54L15_CPUAPP + bool "nRF54L15 PDK nRF54L15 Application MCU" + depends on SOC_NRF54L15_ENGA_CPUAPP diff --git a/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig new file mode 100644 index 000000000000..532ea07c859b --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP + +config BOARD + default "nrf54l15pdk_nrf54l15_cpuapp" + +config BT_CTLR + default BT + +endif # BOARD_NRF54L15PDK_NRF54L15_CPUAPP diff --git a/boards/arm/nrf54l15pdk_nrf54l15/board.cmake b/boards/arm/nrf54l15pdk_nrf54l15/board.cmake new file mode 100644 index 000000000000..378b7bcdb572 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/board.cmake @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp b/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp new file mode 100644 index 000000000000..80fb2060a077 Binary files /dev/null and b/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp differ diff --git a/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst b/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst new file mode 100644 index 000000000000..fa896f98398c --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst @@ -0,0 +1,134 @@ +.. _nrf54l15pdk_nrf54l15: + +nRF54L15 PDK +############ + +Overview +******** + +The nRF54L15 Preview Development Kit hardware provides +support for the Nordic Semiconductor nRF54L15 Arm Cortex-M33 CPU and +the following devices: + +* :abbr:`SAADC (Successive Approximation Analog to Digital Converter)` +* CLOCK +* RRAM +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`TWIM (I2C-compatible two-wire interface master with EasyDMA)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* :abbr:`GRTC (Global real-time counter)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf54l15pdk_nrf54l15.webp + :align: center + :alt: nRF54L15 PDK + + nRF54L15 PDK (Credit: Nordic Semiconductor) + +Hardware +******** + +nRF54L15 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 nrf54l15pdk_nrf54l15 board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| SAADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| RRAM | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| TWIM | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| GRTC | on-chip | counter | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Programming and Debugging +************************* + +Applications for the ``nrf54l15pdk_nrf54l15_cpuapp`` 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 +======== + +As an example, this section shows how to build and flash the :ref:`hello_world` +application. + +.. warning:: + + When programming the device, you might get an error similar to the following message:: + + ERROR: The operation attempted is unavailable due to readback protection in + ERROR: your device. Please use --recover to unlock the device. + + This error occurs when readback protection is enabled. + To disable the readback protection, you must *recover* your device. + + Enter the following command to recover the core:: + + west flash --recover + + The ``--recover`` command erases the flash memory and then writes a small binary into + the recovered flash memory. + This binary prevents the readback protection from enabling itself again after a pin + reset or power cycle. + +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 nRF54L15 PDK, complete the following steps: + +First, connect the nRF54L15 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: nrf54l15pdk_nrf54l15_cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF54L15 PDK +************************************************ + +Test the nRF54L15 PDK with a :zephyr:code-sample:`blinky` sample. diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi new file mode 100644 index 000000000000..02b02bc81715 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart20_default: uart20_default { + group1 { + psels = , + ; + }; + }; + + uart20_sleep: uart20_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart30_default: uart30_default { + group1 { + psels = , + ; + }; + }; + + uart30_sleep: uart30_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts new file mode 100644 index 000000000000..1e0245f6cc36 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi" +#include + +/ { + model = "Nordic nRF54L15 PDK nRF54L15 Application MCU"; + compatible = "nordic,nrf54l15pdk_nrf54l15-cpuapp"; + + chosen { + zephyr,console = &uart20; + zephyr,shell-uart = &uart20; + zephyr,sram = &sram0; + zephyr,flash = &rram0; + zephyr,code-partition = &slot0_partition; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpio1 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + button2: button_2 { + gpios = <&gpio2 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + button3: button_3 { + gpios = <&gpio2 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + watchdog0 = &wdt30; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&lfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15500>; +}; + +&hfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15000>; +}; + +&uart20 { + status = "okay"; + 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"; +}; + +&grtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; + +&rram0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0 DT_SIZE_K(64)>; + }; + storage_partition: partition@f2000 { + label = "storage"; + reg = <0xf2000 DT_SIZE_K(24)>; + }; + }; +}; + +&clock { + status = "okay"; +}; diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml new file mode 100644 index 000000000000..de5ce29d162b --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54l15pdk_nrf54l15_cpuapp +name: nRF54l15-PDK-nRF54l15-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 256 +flash: 1536 +supported: + - gpio + - i2c + - spi + - watchdog + - i2s diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig new file mode 100644 index 000000000000..bc74c3eeb336 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54LX=y +CONFIG_SOC_NRF54L15_ENGA_CPUAPP=y +CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUAPP=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 + +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +CONFIG_SOC_NRF_FORCE_CONSTLAT=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y diff --git a/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake b/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake new file mode 100644 index 000000000000..4fe5b260db37 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_check_revision(FORMAT MAJOR.MINOR.PATCH + VALID_REVISIONS 0.2.0 + DEFAULT_REVISION 0.2.0) diff --git a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig index 0ece4f9a2ac1..378a58fb6e38 100644 --- a/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig +++ b/boards/arm/nrf9131ek_nrf9131/Kconfig.defconfig @@ -8,6 +8,22 @@ if BOARD_NRF9131EK_NRF9131 || BOARD_NRF9131EK_NRF9131_NS config BOARD default "nrf9131ek_nrf9131" + +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF9131EK_NRF9131_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/nrf9151dk_nrf9151/Kconfig.board b/boards/arm/nrf9151dk_nrf9151/Kconfig.board new file mode 100644 index 000000000000..92352ddc16fa --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/Kconfig.board @@ -0,0 +1,14 @@ +# nRF9151 DK NRF9151 board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9151_LACA + +config BOARD_NRF9151DK_NRF9151 + bool "nRF9151 DK NRF9151" + +config BOARD_NRF9151DK_NRF9151_NS + bool "nRF9151 DK NRF9151 non-secure" + +endif # SOC_NRF9151_LACA diff --git a/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig b/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig new file mode 100644 index 000000000000..3cbff101d636 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig @@ -0,0 +1,47 @@ +# nRF9151 DK NRF9151 board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF9151DK_NRF9151 || BOARD_NRF9151DK_NRF9151_NS + +config BOARD + default "nrf9151dk_nrf9151" + +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + depends on BOARD_NRF9151DK_NRF9151 && TRUSTED_EXECUTION_SECURE + +if BOARD_NRF9151DK_NRF9151_NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_NRF9151DK_NRF9151_NS + +config BT_HCI_VS + default y if BT + +config BT_WAIT_NOP + default BT && $(dt_nodelabel_enabled,nrf5340_reset) + +config I2C + default $(dt_compat_on_bus,$(DT_COMPAT_NXP_PCAL6408A),i2c) + +endif # BOARD_NRF9151DK_NRF9151 || BOARD_NRF9151DK_NRF9151_NS diff --git a/boards/arm/nrf9151dk_nrf9151/board.cmake b/boards/arm/nrf9151dk_nrf9151/board.cmake new file mode 100644 index 000000000000..a3126c941d98 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/board.cmake @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_NRF9151DK_NRF9151_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() + +# TODO: change to nRF9151_xxAA when such device is available in JLink +board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9151dk_nrf9151/doc/index.rst b/boards/arm/nrf9151dk_nrf9151/doc/index.rst new file mode 100644 index 000000000000..4c02e7ed372d --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/doc/index.rst @@ -0,0 +1,203 @@ +.. _nrf9151dk_nrf9151: + +nRF9151 DK +########## + +Overview +******** + +The nRF9151 DK (PCA10171) is a single-board development kit for evaluation and +development on the nRF9151 SiP for DECT NR+ and LTE-M/NB-IoT with GNSS. The nrf9151dk_nrf9151 +board configuration provides support for the Nordic Semiconductor nRF9151 ARM +Cortex-M33F CPU with ARMv8-M Security Extension 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)` +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter with EasyDMA)` +* :abbr:`WDT (Watchdog Timer)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` + +More information about the board can be found at the +`nRF9151 DK website`_. The `Nordic Semiconductor Infocenter`_ +contains the processor's information and the datasheet. + + +Hardware +******** + +nRF9151 DK has two external oscillators. The frequency of +the slow clock is 32.768 kHz. The frequency of the main clock +is 32 MHz. + +Supported Features +================== + +The nrf9151dk_nrf9151 board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| FLASH | external | spi | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIO | external | i2c | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | nRF53 | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + + +.. _nrf9151dk_additional_hardware: + +Other hardware features have not been enabled yet for this board. +See `nRF9151 DK website`_ and `Nordic Semiconductor Infocenter`_ +for a complete list of nRF9151 DK board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.0 +* LED2 (green) = P0.1 +* LED3 (green) = P0.4 +* LED4 (green) = P0.5 + +Push buttons and Switches +------------------------- + +* BUTTON1 = P0.8 +* BUTTON2 = P0.9 +* SWITCH1 = P0.18 +* SWITCH2 = P0.19 +* BOOT = SW5 = boot/reset + +Security components +=================== + +- Implementation Defined Attribution Unit (`IDAU`_). The IDAU is implemented + with the System Protection Unit and is used to define secure and non-secure + memory maps. By default, all of the memory space (Flash, SRAM, and + peripheral address space) is defined to be secure accessible only. +- Secure boot. + + +Programming and Debugging +************************* + +nrf9151dk_nrf9151 supports the Armv8m Security Extension, and by default boots +in the Secure state. + +Building Secure/Non-Secure Zephyr applications with Arm |reg| TrustZone |reg| +============================================================================= + +The process requires the following steps: + +1. Build the Secure Zephyr application using ``-DBOARD=nrf9151dk_nrf9151`` and + ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the application project configuration file. +2. Build the Non-Secure Zephyr application using ``-DBOARD=nrf9151dk_nrf9151_ns``. +3. Merge the two binaries together. + +When building a Secure/Non-Secure application, the Secure application will +have to set the IDAU (SPU) configuration to allow Non-Secure access to all +CPU resources utilized by the Non-Secure application firmware. SPU +configuration shall take place before jumping to the Non-Secure application. + +Building a Secure only application +================================== + +Build the Zephyr app in the usual way (see :ref:`build_an_application` +and :ref:`application_run`), using ``-DBOARD=nrf9151dk_nrf9151``. + +Flashing +======== + +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`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the nRF9151 DK +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: nrf9151dk_nrf9151 + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + + +Testing the LEDs and buttons in the nRF9151 DK +********************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +* :zephyr:code-sample:`blinky` +* :zephyr:code-sample:`button` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi`. + +References +********** + +.. target-notes:: + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _nRF9151 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF9151-DK +.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml b/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml new file mode 100644 index 000000000000..2b51125312cf --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO used to reset nRF5340 on nRF9151 DK + +compatible: "nordic,nrf9151dk-nrf5340-reset" + +include: base.yaml + +properties: + status: + required: true + + gpios: + type: phandle-array + required: true + description: | + GPIO to use as nRF5340 reset line: output in nRF9151, input in nRF5340. diff --git a/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi new file mode 100644 index 000000000000..20f7d2406a57 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pcal6408a { + status = "okay"; +}; + +&button0 { + gpios = <&pcal6408a 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button1 { + gpios = <&pcal6408a 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button2 { + gpios = <&pcal6408a 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button3 { + gpios = <&pcal6408a 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; diff --git a/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi new file mode 100644 index 000000000000..d80c509d2152 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pcal6408a { + status = "okay"; +}; + +&led0 { + gpios = <&pcal6408a 4 GPIO_ACTIVE_HIGH>; +}; + +&led1 { + gpios = <&pcal6408a 5 GPIO_ACTIVE_HIGH>; +}; + +&led2 { + gpios = <&pcal6408a 6 GPIO_ACTIVE_HIGH>; +}; + +&led3 { + gpios = <&pcal6408a 7 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts new file mode 100644 index 000000000000..8c3b49214343 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9151dk_nrf9151_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/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml new file mode 100644 index 000000000000..3ad90fea76d9 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml @@ -0,0 +1,22 @@ +identifier: nrf9151dk_nrf9151 +name: nRF9151-DK-NRF9151 +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 88 +flash: 1024 +supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - gpio + - i2c + - pwm + - spi + - watchdog + - counter +vendor: nordic diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi new file mode 100644 index 000000000000..a1680e830f4e --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + 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; + }; + }; + + i2c2_default: i2c2_default { + group1 { + psels = , + ; + }; + }; + + i2c2_sleep: i2c2_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = ; + }; + }; + + pwm0_sleep: pwm0_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/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi new file mode 100644 index 000000000000..958e864c63cd --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "nrf9151dk_nrf9151_common-pinctrl.dtsi" +#include + +/ { + model = "Nordic nRF9151 DK NRF9151"; + compatible = "nordic,nrf9151-dk-nrf9151"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led1: led_1 { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led2: led_2 { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + led3: led_3 { + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + label = "Green LED 4"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + button2: button_2 { + gpios = <&gpio0 18 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + button3: button_3 { + gpios = <&gpio0 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 4"; + zephyr,code = ; + }; + }; + + nrf5340_reset: gpio-reset { + compatible = "nordic,nrf9151dk-nrf5340-reset"; + status = "disabled"; + gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; + }; + + 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 &gpio0 14 0>, /* A0 */ + <1 0 &gpio0 15 0>, /* A1 */ + <2 0 &gpio0 16 0>, /* A2 */ + <3 0 &gpio0 17 0>, /* A3 */ + <4 0 &gpio0 18 0>, /* A4 */ + <5 0 &gpio0 19 0>, /* A5 */ + <6 0 &gpio0 0 0>, /* D0 */ + <7 0 &gpio0 1 0>, /* D1 */ + <8 0 &gpio0 2 0>, /* D2 */ + <9 0 &gpio0 3 0>, /* D3 */ + <10 0 &gpio0 4 0>, /* D4 */ + <11 0 &gpio0 5 0>, /* D5 */ + <12 0 &gpio0 6 0>, /* D6 */ + <13 0 &gpio0 7 0>, /* D7 */ + <14 0 &gpio0 8 0>, /* D8 */ + <15 0 &gpio0 9 0>, /* D9 */ + <16 0 &gpio0 10 0>, /* D10 */ + <17 0 &gpio0 11 0>, /* D11 */ + <18 0 &gpio0 12 0>, /* D12 */ + <19 0 &gpio0 13 0>, /* D13 */ + <20 0 &gpio0 30 0>, /* D14 */ + <21 0 &gpio0 31 0>; /* D15 */ + }; + + arduino_adc: analog-connector { + compatible = "arduino,uno-adc"; + #io-channel-cells = <1>; + io-channel-map = <0 &adc 1>, /* A0 = P0.14 = AIN1 */ + <1 &adc 2>, /* A1 = P0.15 = AIN2 */ + <2 &adc 3>, /* A2 = P0.16 = AIN3 */ + <3 &adc 4>, /* A3 = P0.17 = AIN4 */ + <4 &adc 5>, /* A4 = P0.18 = AIN5 */ + <5 &adc 6>; /* A5 = P0.19 = AIN6 */ + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + pwm-led0 = &pwm_led0; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + bootloader-led0 = &led0; + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; + watchdog0 = &wdt0; + spi-flash0 = &gd25wb256; + }; +}; + +&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"; +}; + +arduino_serial: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_i2c: &i2c2 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + pinctrl-names = "default", "sleep"; + clock-frequency = ; + + pcal6408a: pcal6408a@21 { + compatible = "nxp,pcal6408a"; + status = "disabled"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + int-gpios = <&gpio0 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_spi: &spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>, /* D10 */ + <&gpio0 20 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; + + gd25wb256: gd25wb256e3ir@1 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <1>; + spi-max-frequency = <8000000>; + size = <268435456>; + has-dpd; + t-enter-dpd = <3000>; + t-exit-dpd = <40000>; + sfdp-bfp = [ + e5 20 f3 ff ff ff ff 0f 44 eb 08 6b 08 3b 42 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 44 7a c9 fe 83 67 26 62 ec 82 18 44 + 7a 75 7a 75 04 c4 d5 5c 00 06 74 00 08 50 00 01 + ]; + jedec-id = [c8 65 19]; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x10000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@50000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@85000 { + label = "image-1"; + }; + slot1_ns_partition: partition@c5000 { + label = "image-1-nonsecure"; + }; + storage_partition: partition@fa000 { + label = "storage"; + reg = <0x000fa000 0x00006000>; + }; + }; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_modem: image_modem@20016000 { + /* Modem (shared) memory */ + }; + + sram0_ns: image_ns@20020000 { + /* Non-Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "nrf9151dk_nrf9151_partition_conf.dtsi" diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig new file mode 100644 index 000000000000..7afe5ac7aa99 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9151_LACA=y +CONFIG_BOARD_NRF9151DK_NRF9151=y + +# 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/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts new file mode 100644 index 000000000000..a41c4aad3882 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9151dk_nrf9151_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/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml new file mode 100644 index 000000000000..c5d4fe925415 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml @@ -0,0 +1,20 @@ +identifier: nrf9151dk_nrf9151_ns +name: nRF9151-DK-NRF9151-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 128 +flash: 192 +supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - i2c + - pwm + - watchdog + - netif:modem +vendor: nordic diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig new file mode 100644 index 000000000000..949ef39f856d --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9151_LACA=y +CONFIG_BOARD_NRF9151DK_NRF9151_NS=y + +# 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/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi new file mode 100644 index 000000000000..b209608a725b --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for nRF9151dk_nrf9151. + * + * Zephyr build for nRF9151 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot0_ns_partition { + reg = <0x00050000 0x35000>; +}; + +&slot1_partition { + reg = <0x00085000 0x40000>; +}; + +&slot1_ns_partition { + reg = <0x000c5000 0x35000>; +}; + +/* Default SRAM planning when building for nRF9151 with + * ARM TrustZone-M support + * - Lowest 88 kB SRAM allocated to Secure image (sram0_s). + * - 40 kB SRAM reserved for and used by the modem library + * (sram0_modem). This memory is Non-Secure. + * - Upper 128 kB allocated to Non-Secure image (sram0_ns). + * When building with TF-M, both sram0_modem and sram0_ns + * are allocated to the Non-Secure image. + */ + +&sram0_s { + reg = <0x20000000 DT_SIZE_K(88)>; +}; + +&sram0_modem { + reg = <0x20016000 DT_SIZE_K(40)>; +}; + +&sram0_ns { + reg = <0x20020000 DT_SIZE_K(128)>; +}; diff --git a/boards/arm/nrf9151dk_nrf9151/pre_dt_board.cmake b/boards/arm/nrf9151dk_nrf9151/pre_dt_board.cmake new file mode 100644 index 000000000000..c8267afd1b47 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - flash-controller@39000 & kmu@39000 +# - power@5000 & clock@5000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/arm/nucleo_l552ze_q/CMakeLists.txt b/boards/arm/nucleo_l552ze_q/CMakeLists.txt index d170d283e99d..260ecca27072 100644 --- a/boards/arm/nucleo_l552ze_q/CMakeLists.txt +++ b/boards/arm/nucleo_l552ze_q/CMakeLists.txt @@ -10,6 +10,6 @@ endif() if (CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands #Execute post build script postbuild.sh - COMMAND $/postbuild.sh ${COMPILER_FULL_PATH} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst index 51675477af41..fbf77de1c44f 100644 --- a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst +++ b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst @@ -338,7 +338,7 @@ can be generated using ``nucleo_l552ze_q_ns`` as build target. $ west build -b nucleo_l552ze_q_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/postbuild.sh`` bash script is run automatically in a post-build step to make some required flash layout changes. Once the build is completed, run the following script to initialize the option bytes. diff --git a/boards/arm/nucleo_u575zi_q/doc/index.rst b/boards/arm/nucleo_u575zi_q/doc/index.rst index 0de2c364ecf8..e7035dd497a9 100644 --- a/boards/arm/nucleo_u575zi_q/doc/index.rst +++ b/boards/arm/nucleo_u575zi_q/doc/index.rst @@ -308,7 +308,7 @@ can be generated using ``nucleo_u575zi_q_ns`` as build target. $ west build -b nucleo_u575zi_q_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/postbuild.sh`` bash script is run automatically in a post-build step to make some required flash layout changes. Once the build is completed, run the following script to initialize the option bytes. diff --git a/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt index c79a4b7b4e75..7c2da293e200 100644 --- a/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt +++ b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt @@ -9,6 +9,6 @@ endif() if(CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands #Execute post build script postbuild.sh - COMMAND $/postbuild.sh ${COMPILER_FULL_PATH} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/nucleo_u5a5zj_q/doc/index.rst b/boards/arm/nucleo_u5a5zj_q/doc/index.rst index f877be5c1685..154dbd325799 100644 --- a/boards/arm/nucleo_u5a5zj_q/doc/index.rst +++ b/boards/arm/nucleo_u5a5zj_q/doc/index.rst @@ -342,7 +342,7 @@ can be generated using ``nucleo_u5a5zj_q_ns`` as build target. $ west build -b nucleo_u5a5zj_q_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/postbuild.sh`` bash script is run automatically in a post-build step to make some required flash layout changes. Once the build is completed, run the following script to initialize the option bytes. diff --git a/boards/arm/stm32l562e_dk/CMakeLists.txt b/boards/arm/stm32l562e_dk/CMakeLists.txt index dde738046651..f6ca91f1a73b 100644 --- a/boards/arm/stm32l562e_dk/CMakeLists.txt +++ b/boards/arm/stm32l562e_dk/CMakeLists.txt @@ -10,6 +10,6 @@ endif() if(CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands #Execute post build script postbuild.sh - COMMAND $/postbuild.sh ${COMPILER_FULL_PATH} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/stm32l562e_dk/doc/index.rst b/boards/arm/stm32l562e_dk/doc/index.rst index 5a4f5845617f..0eb2aa7630ca 100644 --- a/boards/arm/stm32l562e_dk/doc/index.rst +++ b/boards/arm/stm32l562e_dk/doc/index.rst @@ -340,7 +340,7 @@ can be generated using ``stm32l562e_dk_ns`` as build target. $ west build -b stm32l562e_dk_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/postbuild.sh`` bash script is run automatically in a post-build step to make some required flash layout changes. Once the build is completed, run the following script to initialize the option bytes. diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index 708d9a05d51e..45869075487e 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -8,6 +8,12 @@ if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS config BOARD default "thingy53_nrf5340_cpuapp" +config BOOTLOADER_MCUBOOT + default y if !MCUBOOT + +config BOARD_ENABLE_CPUNET + default y if !MCUBOOT + # Code Partition: # # For the secure version of the board the firmware is linked at the beginning @@ -135,6 +141,13 @@ endif # LOG endif # BOARD_SERIAL_BACKEND_CDC_ACM +# By default, a USB CDC ACM instance is already enabled in the board's DTS. +# It is not necessary for nRF Connect SDK to add another instance if MCUBoot +# bootloader is built as a child image. +config MCUBOOT_USB_SUPPORT + bool + default n + endif # BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS if BOARD_THINGY53_NRF5340_CPUNET diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml new file mode 100644 index 000000000000..7a48d51ec334 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml @@ -0,0 +1,55 @@ +app: + address: 0x10200 + region: flash_primary + size: 0xdfe00 +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml new file mode 100644 index 000000000000..70ffe6d9c124 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml @@ -0,0 +1,73 @@ +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +tfm_secure: + address: 0x10000 + size: 0xc000 + span: [mcuboot_pad, tfm] +tfm_nonsecure: + address: 0x1c000 + size: 0xd4000 + span: [app] +tfm: + address: 0x10200 + region: flash_primary + size: 0xbe00 +app: + address: 0x1c000 + region: flash_primary + size: 0xd4000 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - tfm + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - tfm + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +nonsecure_storage: + address: 0xf0000 + size: 0x10000 + span: [settings_storage] +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi index 694a6960584e..54efd588cf7a 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi @@ -16,6 +16,7 @@ zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; + nordic,pm-ext-flash = &mx25r64; }; buttons { diff --git a/boards/posix/nrf_bsim/Kconfig b/boards/posix/nrf_bsim/Kconfig index 7d67c44d284a..d85b497f671b 100644 --- a/boards/posix/nrf_bsim/Kconfig +++ b/boards/posix/nrf_bsim/Kconfig @@ -6,7 +6,7 @@ if SOC_SERIES_BSIM_NRFXX # used by Nordic SoCs, so to make the symbols defined in this file available for # the simulated nrf5x_bsim boards, which use the POSIX architecture, the file # must be read also from here. -source "soc/arm/nordic_nrf/Kconfig.peripherals" +source "soc/common/nordic_nrf/Kconfig.peripherals" endif # SOC_SERIES_BSIM_NRFXX diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 6993048248c5..0ee4c6ee2c17 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -93,4 +93,7 @@ config UART_CONSOLE endif # CONSOLE +config UART_NRFX_UARTE_LEGACY_SHIM + default y + endif # SOC_SERIES_BSIM_NRFXX diff --git a/boards/posix/nrf_bsim/board_soc.h b/boards/posix/nrf_bsim/board_soc.h index 1b7e7a85c0cf..d75a187aa610 100644 --- a/boards/posix/nrf_bsim/board_soc.h +++ b/boards/posix/nrf_bsim/board_soc.h @@ -29,6 +29,7 @@ #include #include #include "cmsis.h" +#include "soc_nrf_common.h" #if defined(CONFIG_BOARD_NRF52_BSIM) #define OFFLOAD_SW_IRQ SWI0_EGU0_IRQn diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index 36cbf9691b3d..c5ec3c95af57 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -45,9 +45,11 @@ }; chosen { + zephyr,entropy = &rng_hci; zephyr,flash = &flash0; zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; + zephyr,ieee802154 = &ieee802154; }; soc { diff --git a/boards/posix/nrf_bsim/soc/pinctrl_soc.h b/boards/posix/nrf_bsim/soc/pinctrl_soc.h new file mode 100644 index 000000000000..f0be0443d5b8 --- /dev/null +++ b/boards/posix/nrf_bsim/soc/pinctrl_soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H +#define BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H + +/* We reuse the real SOC's header: */ +#include "../soc/common/nordic_nrf/pinctrl_soc.h" + +#endif /* BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H */ diff --git a/boards/posix/nrf_bsim/soc/soc_nrf_common.h b/boards/posix/nrf_bsim/soc/soc_nrf_common.h new file mode 100644 index 000000000000..a77778de6530 --- /dev/null +++ b/boards/posix/nrf_bsim/soc/soc_nrf_common.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H +#define BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H + +/* We reuse the real SOC's header: */ +#include "../soc/arm/nordic_nrf/common/soc_nrf_common.h" + +#endif /* BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H */ diff --git a/boards/riscv/adp_xc7k_ae350/Kconfig.board b/boards/riscv/adp_xc7k_ae350/Kconfig.board index 085eb9696a8c..5b58e01fbfdb 100644 --- a/boards/riscv/adp_xc7k_ae350/Kconfig.board +++ b/boards/riscv/adp_xc7k_ae350/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_ADP_XC7K_AE350 bool "Andes ADP-XC7K AE350 Platform" - depends on SOC_RISCV_ANDES_AE350 + depends on SOC_ANDES_AE350 diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig index 3f7f1f727c6c..edbe7118c643 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_ANDES_V5=y -CONFIG_SOC_RISCV_ANDES_AE350=y +CONFIG_SOC_SERIES_ANDES_AE350=y +CONFIG_SOC_ANDES_AE350=y CONFIG_BOARD_ADP_XC7K_AE350=y CONFIG_XIP=n CONFIG_CONSOLE=y diff --git a/boards/riscv/beaglev_fire/Kconfig.board b/boards/riscv/beaglev_fire/Kconfig.board new file mode 100644 index 000000000000..55b59d4ac922 --- /dev/null +++ b/boards/riscv/beaglev_fire/Kconfig.board @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BEAGLEV_FIRE + bool "Beagleboard BeagleV-Fire" + depends on SOC_POLARFIRE + select 64BIT + select SCHED_IPI_SUPPORTED + select CPU_HAS_FPU_DOUBLE_PRECISION diff --git a/boards/riscv/beaglev_fire/Kconfig.defconfig b/boards/riscv/beaglev_fire/Kconfig.defconfig new file mode 100644 index 000000000000..df89660bcb65 --- /dev/null +++ b/boards/riscv/beaglev_fire/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "beaglev_fire" + depends on BOARD_BEAGLEV_FIRE diff --git a/boards/riscv/beaglev_fire/beaglev_fire.dts b/boards/riscv/beaglev_fire/beaglev_fire.dts new file mode 100644 index 000000000000..df956f5c8f2f --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "BeagleV-Fire"; + compatible = "beagle,beaglev-fire", "microchip,mpfs"; + aliases { + }; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram1; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + clock-frequency = <150000000>; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/boards/riscv/beaglev_fire/beaglev_fire.yaml b/boards/riscv/beaglev_fire/beaglev_fire.yaml new file mode 100644 index 000000000000..64d34b454f80 --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire.yaml @@ -0,0 +1,12 @@ +identifier: beaglev_fire +name: Beagleboard BeagleV-Fire +type: mcu +arch: riscv64 +toolchain: + - zephyr +ram: 3840 +testing: + ignore_tags: + - net + - bluetooth +vendor: beagle diff --git a/boards/riscv/beaglev_fire/beaglev_fire_defconfig b/boards/riscv/beaglev_fire/beaglev_fire_defconfig new file mode 100644 index 000000000000..3b264d6c2880 --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire_defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_POLARFIRE=y +CONFIG_SOC_POLARFIRE=y +CONFIG_MPFS_HAL=n +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_BOARD_BEAGLEV_FIRE=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_RISCV_SOC_INTERRUPT_INIT=y +CONFIG_RISCV_HAS_PLIC=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_FPU=n diff --git a/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp b/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp new file mode 100644 index 000000000000..a4ba6b0d98e9 Binary files /dev/null and b/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp differ diff --git a/boards/riscv/beaglev_fire/doc/img/board-booting.png b/boards/riscv/beaglev_fire/doc/img/board-booting.png new file mode 100644 index 000000000000..5be27ddfbb17 Binary files /dev/null and b/boards/riscv/beaglev_fire/doc/img/board-booting.png differ diff --git a/boards/riscv/beaglev_fire/doc/index.rst b/boards/riscv/beaglev_fire/doc/index.rst new file mode 100644 index 000000000000..88808145c9bf --- /dev/null +++ b/boards/riscv/beaglev_fire/doc/index.rst @@ -0,0 +1,85 @@ +.. _beaglev_fire: + +BeagleV®-Fire +############# + +Overview +******** + +BeagleV®-Fire is a revolutionary single-board computer (SBC) powered by the Microchip’s +PolarFire® MPFS025T 5x core RISC-V System on Chip (SoC) with FPGA fabric. BeagleV®-Fire opens up new +horizons for developers, tinkerers, and the open-source community to explore the vast potential of +RISC-V architecture and FPGA technology. It has the same P8 & P9 cape header pins as BeagleBone +Black allowing you to stack your favorite BeagleBone cape on top to expand it’s capability. +Built around the powerful and energy-efficient RISC-V instruction set architecture (ISA) along with +its versatile FPGA fabric, BeagleV®-Fire SBC offers unparalleled opportunities for developers, +hobbyists, and researchers to explore and experiment with RISC-V technology. + +.. image:: img/BeagleV-Fire-Front-Annotated-768x432.webp + :align: center + :alt: beaglev_fire + +Building +======== + +Applications for the ``beaglev_fire`` board configuration can be built as usual: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: beaglev_fire + :goals: build + +Debugging +========= + +In order to upload the application to the device, you'll need OpenOCD and GDB +with RISC-V support. +You can get them as a part of SoftConsole SDK. +Download and installation instructions can be found on +`Microchip's SoftConsole website +`_. + +You will also require a Debugger such as Microchip's FlashPro5/6. + +Connect to BeagleV-Fire UART debug port using a 3.3v USB to UART bridge. +Now you can run ``tio `` in a terminal window to access the UART debug port connection. Once you +are connected properly you can press the Reset button which will show you a progress bar like: + +.. image:: img/board-booting.png + :align: center + :alt: beaglev_fire + +Once you see that progress bar on your screen you can start pressing any button (0-9/a-z) which +will interrupt the Hart Software Services from booting its payload. + +With the necessary tools installed, you can connect to the board using OpenOCD. +from a different terminal, run: + +.. code-block:: bash + + /openocd/bin/openocd --file \ + /openocd/share/openocd/scripts/board/microsemi-riscv.cfg + + +Leave it running, and in a different terminal, use GDB to upload the binary to +the board. You can use the RISC-V GDB from the Zephyr SDK. +launch GDB: + +.. code-block:: bash + + /riscv64-zephyr-elf/bin/riscv64-zephyr-elf-gdb + + + +Here is the GDB terminal command to connect to the device +and load the binary: + +.. code-block:: bash + + set arch riscv:rv64 + set mem inaccessible-by-default off + file + target extended-remote localhost:3333 + load + break main + continue diff --git a/boards/riscv/esp32c3_devkitm/doc/index.rst b/boards/riscv/esp32c3_devkitm/doc/index.rst index 6d21b2918c39..26f1521e0874 100644 --- a/boards/riscv/esp32c3_devkitm/doc/index.rst +++ b/boards/riscv/esp32c3_devkitm/doc/index.rst @@ -18,7 +18,7 @@ The features include the following: - 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz - 400 KB of internal RAM - 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth mesh +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh - Various peripherals: - 12-bit ADC with up to 6 channels diff --git a/boards/riscv/esp32c3_luatos_core/doc/index.rst b/boards/riscv/esp32c3_luatos_core/doc/index.rst index c943931a9e63..fae8e2eb178b 100644 --- a/boards/riscv/esp32c3_luatos_core/doc/index.rst +++ b/boards/riscv/esp32c3_luatos_core/doc/index.rst @@ -18,7 +18,7 @@ The features include the following: - 32-bit core RISC-V microcontroller with a maximum clock speed of 160 MHz - 400 KB of internal RAM - 802.11b/g/n/e/i -- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth mesh +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh - Various peripherals: - 12-bit ADC with up to 6 channels diff --git a/boards/riscv/hifive1/Kconfig.board b/boards/riscv/hifive1/Kconfig.board index b5b326494411..d2f40472f244 100644 --- a/boards/riscv/hifive1/Kconfig.board +++ b/boards/riscv/hifive1/Kconfig.board @@ -2,4 +2,4 @@ config BOARD_HIFIVE1 bool "HiFive1 target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/hifive1/hifive1_defconfig b/boards/riscv/hifive1/hifive1_defconfig index d37ded2bb25a..8e4e8e21c1a2 100644 --- a/boards/riscv/hifive1/hifive1_defconfig +++ b/boards/riscv/hifive1/hifive1_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_HIFIVE1=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/hifive1_revb/Kconfig.board b/boards/riscv/hifive1_revb/Kconfig.board index d4c5b99ce726..b0bf1edd156b 100644 --- a/boards/riscv/hifive1_revb/Kconfig.board +++ b/boards/riscv/hifive1_revb/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE1_REVB bool "HiFive1 Rev B target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/hifive1_revb/hifive1_revb_defconfig b/boards/riscv/hifive1_revb/hifive1_revb_defconfig index 4f691bd94354..b2119eecae9b 100644 --- a/boards/riscv/hifive1_revb/hifive1_revb_defconfig +++ b/boards/riscv/hifive1_revb/hifive1_revb_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_HIFIVE1_REVB=y CONFIG_GPIO=y CONFIG_PINCTRL=y diff --git a/boards/riscv/hifive_unleashed/Kconfig.board b/boards/riscv/hifive_unleashed/Kconfig.board index 4766e0ea7929..f6c623e99281 100644 --- a/boards/riscv/hifive_unleashed/Kconfig.board +++ b/boards/riscv/hifive_unleashed/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE_UNLEASHED bool "HiFive Unleashed target" - depends on SOC_RISCV_SIFIVE_FU540 + depends on SOC_SIFIVE_FREEDOM_U540 diff --git a/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig b/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig index 15c9e60d5527..51d324d457d3 100644 --- a/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig +++ b/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FU540=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_U500=y +CONFIG_SOC_SIFIVE_FREEDOM_U540=y CONFIG_BOARD_HIFIVE_UNLEASHED=y CONFIG_CONSOLE=y CONFIG_GPIO=y diff --git a/boards/riscv/hifive_unmatched/Kconfig.board b/boards/riscv/hifive_unmatched/Kconfig.board index cf6ac1c83920..bb303cc3aac4 100644 --- a/boards/riscv/hifive_unmatched/Kconfig.board +++ b/boards/riscv/hifive_unmatched/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE_UNMATCHED bool "HiFive Unmatched target" - depends on SOC_RISCV_SIFIVE_FU740 + depends on SOC_SIFIVE_FREEDOM_U740 diff --git a/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig b/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig index 654fdc1bf2a6..be13ed103586 100644 --- a/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig +++ b/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FU740=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_U700=y +CONFIG_SOC_SIFIVE_FREEDOM_U740=y CONFIG_BOARD_HIFIVE_UNMATCHED=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig b/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig index f082e4a7bada..6866e3f633b9 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig +++ b/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2023 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_SERIES_ITE_IT8XXX2=y CONFIG_SOC_IT8XXX2=y CONFIG_SOC_IT82202_AX=y CONFIG_BOARD_IT82XX2_EVB=y diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig index 21967527f8ea..38a44d6f8f3d 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_SERIES_ITE_IT8XXX2=y CONFIG_SOC_IT8XXX2=y CONFIG_BOARD_IT8XXX2_EVB=y CONFIG_BOOT_DELAY=1 diff --git a/boards/riscv/m2gl025_miv/Kconfig.board b/boards/riscv/m2gl025_miv/Kconfig.board index 51c2f9d8de31..9f81fad406f3 100644 --- a/boards/riscv/m2gl025_miv/Kconfig.board +++ b/boards/riscv/m2gl025_miv/Kconfig.board @@ -2,4 +2,4 @@ config BOARD_M2GL025_MIV bool "Microchip M2GL025 IGLOO2 dev board with Mi-V CPU" - depends on SOC_RISCV32_MIV + depends on SOC_MIV diff --git a/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig b/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig index 8c944a10a749..e33765680d54 100644 --- a/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig +++ b/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_MIV=y -CONFIG_SOC_RISCV32_MIV=y +CONFIG_SOC_SERIES_MIV=y +CONFIG_SOC_MIV=y CONFIG_BOARD_M2GL025_MIV=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/mpfs_icicle/Kconfig.board b/boards/riscv/mpfs_icicle/Kconfig.board index 297f4ce4bc75..e772b82d7f58 100644 --- a/boards/riscv/mpfs_icicle/Kconfig.board +++ b/boards/riscv/mpfs_icicle/Kconfig.board @@ -3,7 +3,7 @@ config BOARD_MPFS_ICICLE bool "Microchip PolarFire SoC ICICLE kit" - depends on SOC_MPFS + depends on SOC_POLARFIRE select 64BIT select SCHED_IPI_SUPPORTED select CPU_HAS_FPU_DOUBLE_PRECISION diff --git a/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig b/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig index 5c41649cb3ea..00b44f7a6d5a 100644 --- a/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig +++ b/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2020-2021 Microchip Technology Inc # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV64_MIV=y -CONFIG_SOC_MPFS=y +CONFIG_SOC_SERIES_POLARFIRE=y +CONFIG_SOC_POLARFIRE=y CONFIG_MPFS_HAL=n CONFIG_BASE64=y CONFIG_INCLUDE_RESET_VECTOR=y diff --git a/boards/riscv/neorv32/Kconfig.board b/boards/riscv/neorv32/Kconfig.board index eee37f4a8c39..6d85ebb2e402 100644 --- a/boards/riscv/neorv32/Kconfig.board +++ b/boards/riscv/neorv32/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_NEORV32 bool "NEORV32 Processor (SoC)" - depends on SOC_SERIES_NEORV32 + depends on SOC_NEORV32 diff --git a/boards/riscv/neorv32/neorv32_defconfig b/boards/riscv/neorv32/neorv32_defconfig index 17e9b8038cec..7dc8a74ffff1 100644 --- a/boards/riscv/neorv32/neorv32_defconfig +++ b/boards/riscv/neorv32/neorv32_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_NEORV32=y +CONFIG_SOC_NEORV32=y CONFIG_SOC_NEORV32_ISA_C=y CONFIG_BOARD_NEORV32=y CONFIG_SERIAL=y diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board new file mode 100644 index 000000000000..9bbbba60dd43 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54H20PDK_NRF54H20_CPUPPR + bool "nRF54H20 PDK nRF54H20 PPR MCU" + depends on SOC_NRF54H20_ENGA_CPUPPR diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig new file mode 100644 index 000000000000..256976d65190 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "nrf54h20pdk_nrf54h20_cpuppr" + depends on BOARD_NRF54H20PDK_NRF54H20_CPUPPR diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake b/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake new file mode 100644 index 000000000000..4c63f1dd05ee --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts new file mode 100644 index 000000000000..83aface6f5c1 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpuppr"; + model = "Nordic nRF54H20 PDK nRF54H20 Peripheral Processor MCU"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &uart135; + zephyr,code-partition = &cpuppr_code_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpuppr_ram3x_region; + }; +}; + +&grtc { + status = "okay"; + owned-channels = <5>; +}; + +&uart135 { + status = "okay"; + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml new file mode 100644 index 000000000000..274be865c36e --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpuppr +name: nRF54H20-PDK-nRF54H20-PPR +type: mcu +arch: riscv +toolchain: + - zephyr +ram: 28 +flash: 28 +supported: + - gpio diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig new file mode 100644 index 000000000000..fb3dca2266de --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPUPPR=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPUPPR=y + +CONFIG_XIP=n + +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake b/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake new file mode 100644 index 000000000000..5e0fecebdc86 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Allow common DTS files to be included from the other board directory. +# To be removed after HWMv2 (#51831), once both directories can be merged into one. +string(REGEX REPLACE "/riscv/(.*$)" "/arm/\\1" BOARD_DIR_ARM "${BOARD_DIR}") +list(APPEND DTS_EXTRA_CPPFLAGS -isystem "${BOARD_DIR_ARM}") diff --git a/boards/riscv/opentitan_earlgrey/Kconfig.board b/boards/riscv/opentitan_earlgrey/Kconfig.board index ec7f735b442b..544c02b1b2ae 100644 --- a/boards/riscv/opentitan_earlgrey/Kconfig.board +++ b/boards/riscv/opentitan_earlgrey/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_OPENTITAN_EARLGREY bool "OpenTitan Earl Grey Target" - depends on SOC_RISCV_OPENTITAN + depends on SOC_OPENTITAN diff --git a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig index 79299c3892f9..886e439b88ac 100644 --- a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig +++ b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig @@ -1,8 +1,7 @@ # Copyright (c) 2023 by Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_OPENTITAN=y -CONFIG_SOC_RISCV_OPENTITAN=y +CONFIG_SOC_OPENTITAN=y CONFIG_BOARD_OPENTITAN_EARLGREY=y CONFIG_XIP=y CONFIG_SERIAL=y diff --git a/boards/riscv/qemu_riscv32/Kconfig.board b/boards/riscv/qemu_riscv32/Kconfig.board index 989fa13b4531..7c94b59455cc 100644 --- a/boards/riscv/qemu_riscv32/Kconfig.board +++ b/boards/riscv/qemu_riscv32/Kconfig.board @@ -22,7 +22,7 @@ config BOARD_QEMU_RISCV32_SMP config BOARD_QEMU_RISCV32_XIP bool "QEMU RISCV32 XIP target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 select QEMU_TARGET select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig index f50d82dcb76c..946e679a6e81 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig index eef7d03e356d..90f87ef6b988 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32_SMP=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig index 2cd0b2cbecbb..948fa909a085 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_QEMU_RISCV32_XIP=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig b/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig index ef4d6273cfbd..1f1c46acb10c 100644 --- a/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig +++ b/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32E=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig index 6f51da3c5924..6bfc46ac907a 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV64=y CONFIG_PRIVILEGED_STACK_SIZE=2048 diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig index 78b5b74de9ab..265d84a1ded8 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV64_SMP=y CONFIG_PRIVILEGED_STACK_SIZE=2048 diff --git a/boards/riscv/riscv32_virtual/Kconfig.board b/boards/riscv/riscv32_virtual/Kconfig.board new file mode 100644 index 000000000000..c8722acb384b --- /dev/null +++ b/boards/riscv/riscv32_virtual/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RISCV32_VIRTUAL + bool "riscv32_virtual" + depends on SOC_RISCV32_VIRTUAL_RENODE diff --git a/boards/riscv/riscv32_virtual/Kconfig.defconfig b/boards/riscv/riscv32_virtual/Kconfig.defconfig new file mode 100644 index 000000000000..840b10fd5944 --- /dev/null +++ b/boards/riscv/riscv32_virtual/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "riscv32_virtual" + depends on BOARD_RISCV32_VIRTUAL diff --git a/boards/riscv/riscv32_virtual/board.cmake b/boards/riscv/riscv32_virtual/board.cmake new file mode 100644 index 000000000000..cc177a69ce9e --- /dev/null +++ b/boards/riscv/riscv32_virtual/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +set(SUPPORTED_EMU_PLATFORMS renode) +set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/riscv32_virtual.resc) +set(RENODE_UART sysbus.uart0) diff --git a/boards/riscv/riscv32_virtual/doc/index.rst b/boards/riscv/riscv32_virtual/doc/index.rst new file mode 100644 index 000000000000..a53384f53319 --- /dev/null +++ b/boards/riscv/riscv32_virtual/doc/index.rst @@ -0,0 +1,56 @@ +.. _riscv32-virtual: + +RISCV32 Virtual +############### + +Overview +******** + +The RISCV32 Virtual board is a virtual platform made with Renode as an alternative to QEMU. +Contrary to QEMU, the peripherals of this platform can be easily configured by editing the +``riscv32_virtual.repl`` script and the devicetree files accordingly, this allows certain hardware +configurations that only exist in proprietary boards/SoCs to be tested in upstream CI. + +Programming and debugging +************************* + +Building +======== + +Applications for the ``riscv32_virtual`` board configuration can be built as usual +(see :ref:`build_an_application`): + +.. zephyr-app-commands:: + :board: riscv32_virtual + :goals: build + +Flashing +======== + +While this board is emulated and you can't "flash" it, you can use this +configuration to run basic Zephyr applications and kernel tests in the Renode +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: riscv32_virtual + :goals: run + +This will build an image with the synchronization sample app, boot it using +Renode, and display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.5.0-1511-g56f73bde0fb0 *** + thread_a: Hello World from cpu 0 on riscv32_virtual! + thread_b: Hello World from cpu 0 on riscv32_virtual! + thread_a: Hello World from cpu 0 on riscv32_virtual! + thread_b: Hello World from cpu 0 on riscv32_virtual! + +Exit Renode by pressing :kbd:`CTRL+C`. + +Debugging +========= + +Refer to the detailed overview about :ref:`application_debugging`. diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual.dts b/boards/riscv/riscv32_virtual/riscv32_virtual.dts new file mode 100644 index 000000000000..326b97575180 --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Renode RISCV32 Virtual target"; + compatible = "renode,riscv32-virtual"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,sram = &sram0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual.yaml b/boards/riscv/riscv32_virtual/riscv32_virtual.yaml new file mode 100644 index 000000000000..11cefb035df8 --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual.yaml @@ -0,0 +1,16 @@ +identifier: riscv32_virtual +name: Renode RISC-V 32-bit Virtual Board +type: mcu +arch: riscv32 +toolchain: + - zephyr +ram: 4096 +flash: 4096 +simulation: renode +simulation_exec: renode +testing: + ignore_tags: + - net + - bluetooth +supported: + - uart diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig b/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig new file mode 100644 index 000000000000..4dcad0a7ea10 --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_RISCV32_VIRTUAL_RENODE=y +CONFIG_BOARD_RISCV32_VIRTUAL=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=n +CONFIG_XIP=y + +# Workaround for incorrect SYS_CLOCK_HW_CYCLES_PER_SEC +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 diff --git a/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl b/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl new file mode 100644 index 000000000000..e0df808631b6 --- /dev/null +++ b/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl @@ -0,0 +1,33 @@ +// Copyright (c) 2023 Meta +// SPDX-License-Identifier: Apache-2.0 + +flash: Memory.MappedMemory @ sysbus 0x80000000 + size: 0x400000 + +ddr: Memory.MappedMemory @ sysbus 0x80400000 + size: 0x400000 + +uart0: UART.NS16550 @ sysbus 0x10000000 + IRQ -> plic0@10 + +uart1: UART.NS16550 @ sysbus 0x10000100 + IRQ -> plic1@10 + +cpu: CPU.RiscV32 @ sysbus + cpuType: "rv32imac_zicsr_zifencei" + privilegeArchitecture: PrivilegeArchitecture.Priv1_10 + timeProvider: clint + +plic0: IRQControllers.PlatformLevelInterruptController @ sysbus 0x0C000000 + 0 -> cpu@11 + numberOfSources: 1023 + numberOfContexts: 1 + +plic1: IRQControllers.PlatformLevelInterruptController @ sysbus 0x08000000 + 0 -> cpu@4 + numberOfSources: 1023 + numberOfContexts: 1 + +clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x02000000 + [0,1] -> cpu@[3,7] + frequency: 4000000 diff --git a/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc b/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc new file mode 100644 index 000000000000..87e327287b61 --- /dev/null +++ b/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc @@ -0,0 +1,17 @@ +:name: RISCV32-Virtual +:description: This script is prepared to run Zephyr on a Renode RISCV32 board. + +$name?="RISCV32-Virtual" + +using sysbus +mach create $name +machine LoadPlatformDescription $ORIGIN/riscv32_virtual.repl + +showAnalyzer uart0 +cpu PerformanceInMips 4 + +macro reset +""" + sysbus LoadELF $bin +""" +runMacro $reset diff --git a/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board b/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board index 34f852dc0ecb..cc9e7b4f935d 100644 --- a/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board +++ b/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_SPARKFUN_RED_V_THINGS_PLUS bool "SparkFun RED-V Things Plus board" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig index de3d18bcfded..8cf24ffbe09f 100644 --- a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig +++ b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2022 TOKITA Hiroshi # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_SPARKFUN_RED_V_THINGS_PLUS=y CONFIG_GPIO=y CONFIG_PINCTRL=y diff --git a/boards/riscv/titanium_ti60_f225/Kconfig.board b/boards/riscv/titanium_ti60_f225/Kconfig.board index d6ed41ffc79d..bac70816b205 100644 --- a/boards/riscv/titanium_ti60_f225/Kconfig.board +++ b/boards/riscv/titanium_ti60_f225/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_TITANIUM_TI60_F225 bool "Board with Efinix Sapphire riscv SoC" - depends on SOC_SERIES_EFINIX_SAPPHIRE + depends on SOC_EFINIX_SAPPHIRE diff --git a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig index 096980b864ec..0608a8e89537 100644 --- a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig +++ b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_EFINIX_SAPPHIRE=y +CONFIG_SOC_EFINIX_SAPPHIRE=y CONFIG_BOARD_TITANIUM_TI60_F225=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/tlsr9518adk80d/Kconfig.board b/boards/riscv/tlsr9518adk80d/Kconfig.board index bd36cb0e481f..971b34dc13b4 100644 --- a/boards/riscv/tlsr9518adk80d/Kconfig.board +++ b/boards/riscv/tlsr9518adk80d/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_TLSR9518ADK80D bool "Telink B91 Platform" - depends on SOC_RISCV_TELINK_B91 + depends on SOC_TELINK_TLSR9518 diff --git a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig index fe5cfbe8c2eb..c4cfdfea718e 100644 --- a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig +++ b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_TELINK_B91=y -CONFIG_SOC_RISCV_TELINK_B91=y +CONFIG_SOC_SERIES_TELINK_TLSR951X=y +CONFIG_SOC_TELINK_TLSR9518=y CONFIG_BOARD_TLSR9518ADK80D=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index a116977ce8ce..7e639043bce2 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -128,3 +128,7 @@ if(CONFIG_USB_HOST_STACK) zephyr_iterable_section(NAME usbh_contex GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME usbh_class_data GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) endif() + +if(CONFIG_DEVICE_MUTABLE) + zephyr_iterable_section(NAME device_mutable GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +endif() diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 632e9a724229..1a78b3ebd022 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -147,6 +147,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} TOOLCHAIN_HAS_NEWLIB=${_local_TOOLCHAIN_HAS_NEWLIB} TOOLCHAIN_HAS_PICOLIBC=${_local_TOOLCHAIN_HAS_PICOLIBC} + HIDE_CHILD_PARENT_CONFIG=${SYSBUILD} EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index a093d46691fd..06e1642f3629 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -243,3 +243,7 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() + +if(ZEPHYR_NRF_MODULE_DIR) + include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) +endif() diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 550d236a2f4a..6f8950c5f64a 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -59,6 +59,7 @@ function(zephyr_process_snippets) # Set SNIPPET_ROOT. list(APPEND SNIPPET_ROOT ${APPLICATION_SOURCE_DIR}) list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) + list(APPEND SNIPPET_ROOT ${ZEPHYR_NRF_MODULE_DIR}) unset(real_snippet_root) foreach(snippet_dir ${SNIPPET_ROOT}) # The user might have put a symbolic link in here, for example. diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 8c3951428181..053965e26e30 100644 --- a/doc/_extensions/zephyr/domain.py +++ b/doc/_extensions/zephyr/domain.py @@ -80,6 +80,9 @@ class ConvertCodeSampleNode(SphinxTransform): default_priority = 100 def apply(self): + if not self.config.zephyr_domain_apply_transforms: + return + matcher = NodeMatcher(CodeSampleNode) for node in self.document.traverse(matcher): self.convert_node(node) @@ -140,6 +143,9 @@ class ProcessRelatedCodeSamplesNode(SphinxPostTransform): default_priority = 5 # before ReferencesResolver def run(self, **kwargs: Any) -> None: + if not self.config.zephyr_domain_apply_transforms: + return + matcher = NodeMatcher(RelatedCodeSamplesNode) for node in self.document.traverse(matcher): id = node["id"] # the ID of the node is the name of the doxygen group for which we @@ -249,7 +255,7 @@ class ZephyrDomain(Domain): directives = {"code-sample": CodeSampleDirective} object_types: Dict[str, ObjType] = { - "code-sample": ObjType("code sample", "code-sample"), + "code-sample": ObjType("code-sample", "code-sample"), } initial_data: Dict[str, Any] = {"code-samples": {}} @@ -267,9 +273,9 @@ def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: def get_objects(self): for _, code_sample in self.data["code-samples"].items(): yield ( + code_sample["id"], code_sample["name"], - code_sample["name"], - "code sample", + "code-sample", code_sample["docname"], code_sample["id"], 1, @@ -308,10 +314,16 @@ class CustomDoxygenGroupDirective(DoxygenGroupDirective): def run(self) -> List[Node]: nodes = super().run() - return [RelatedCodeSamplesNode(id=self.arguments[0]), *nodes] + + if self.config.zephyr_domain_apply_transforms: + return [RelatedCodeSamplesNode(id=self.arguments[0]), *nodes] + else: + return nodes def setup(app): + app.add_config_value("zephyr_domain_apply_transforms", False, "env") + app.add_domain(ZephyrDomain) app.add_transform(ConvertCodeSampleNode) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 6ba75ce5ab7c..2c992436c87a 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -53,7 +53,7 @@ from get_maintainer import Maintainers -MAINTAINERS : Final[Maintainers] = Maintainers() +MAINTAINERS : Final[Maintainers] = Maintainers(filename=f"{ZEPHYR_BASE}/MAINTAINERS.yml") __version__ = "0.1.0" diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 57dd7828978c..cc7658a1664b 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -7,8 +7,7 @@ The :ref:`menuconfig and guiconfig interfaces ` can be used to test out configurations during application development. This page explains how to make settings permanent. -All Kconfig options can be searched in the :ref:`Kconfig search page -`. +All Kconfig options can be searched in the Kconfig search page. .. note:: @@ -115,8 +114,7 @@ Assignments in configuration files are only respected if the dependencies for the symbol are satisfied. A warning is printed otherwise. To figure out what the dependencies of a symbol are, use one of the :ref:`interactive configuration interfaces ` (you can jump directly to a symbol with -:kbd:`/`), or look up the symbol in the :ref:`Kconfig search page -`. +:kbd:`/`), or look up the symbol in the Kconfig search page. .. _initial-conf: diff --git a/doc/conf.py b/doc/conf.py index 85488318a0a9..4bab42dcc90f 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -302,6 +302,10 @@ "build/dts/api/compatibles/**/*", ] +# -- Options for zephyr.domain -------------------------------------------- + +zephyr_domain_apply_transforms = True + # -- Options for sphinx.ext.graphviz -------------------------------------- graphviz_dot = os.environ.get("DOT_EXECUTABLE", "dot") diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 457aa5b68953..f234ff7cedce 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -3,14 +3,14 @@ Bluetooth Mesh Profile ###################### -The Bluetooth mesh profile adds secure wireless multi-hop communication for +The Bluetooth Mesh profile adds secure wireless multi-hop communication for Bluetooth Low Energy. This module implements the `Bluetooth Mesh Profile Specification v1.0.1 `_. Implementation of the `Bluetooth Mesh Protocol Specification v1.1 `_ is in experimental state. -Read more about Bluetooth mesh on the +Read more about Bluetooth Mesh on the `Bluetooth SIG Website `_. .. toctree:: diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 2af8e6a03b8a..cb02028b697b 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -3,7 +3,7 @@ Access layer ############ -The access layer is the application's interface to the Bluetooth mesh network. +The access layer is the application's interface to the Bluetooth Mesh network. The access layer provides mechanisms for compartmentalizing the node behavior into elements and models, which are implemented by the application. @@ -113,7 +113,7 @@ number within one publication interval. Extended models =============== -The Bluetooth mesh specification allows the mesh models to extend each other. +The Bluetooth Mesh specification allows the mesh models to extend each other. When a model extends another, it inherits that model's functionality, and extension can be used to construct complex models out of simple ones, leveraging the existing model functionality to avoid defining new opcodes. @@ -222,6 +222,54 @@ They are used to represent the new content of the mirrored pages when the Compos change after a firmware update. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata` for details. +Delayable messages +================== + +The delayable message functionality is enabled with Kconfig option +:kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG`. +This is an optional functionality that implements specification recommendations for +messages that are transmitted by a model in a response to a received message, also called +response messages. + +Response messages should be sent with the following random delays: + +* Between 20 and 50 milliseconds if the received message was sent + to a unicast address +* Between 20 and 500 milliseconds if the received message was sent + to a group or virtual address + +The delayable message functionality is triggered if the :c:member:`bt_mesh_msg_ctx.rnd_delay` +flag is set. +The delayable message functionality stores messages in the local memory while they are +waiting for the random delay expiration. + +If the transport layer doesn't have sufficient memory to send a message at the moment +the random delay expires, the message is postponed for another 10 milliseconds. +If the transport layer cannot send a message for any other reason, the delayable message +functionality raises the :c:member:`bt_mesh_send_cb.start` callback with a transport layer +error code. + +If the delayable message functionality cannot find enough free memory to store an incoming +message, it will send messages with delay close to expiration to free memory. + +When the mesh stack is suspended or reset, messages not yet sent are removed and +the :c:member:`bt_mesh_send_cb.start` callback is raised with an error code. + +Delayable publications +====================== + +The delayable publication functionality implements the specification recommendations for message +publication delays in the following cases: + +* Between 20 to 500 milliseconds when the Bluetooth Mesh stack starts or when the publication is + triggered by the :c:func:`bt_mesh_model_publish` function +* Between 20 to 50 milliseconds for periodically published messages + +This feature is optional and enabled with the :kconfig:option:`CONFIG_BT_MESH_DELAYABLE_PUBLICATION` +Kconfig option. When enabled, each model can enable or disable the delayable publication by setting +the :c:member:`bt_mesh_model_pub.delayable` bit field to ``1`` or ``0`` correspondingly. This bit +field can be changed at any time. + API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/blob.rst b/doc/connectivity/bluetooth/api/mesh/blob.rst index 31f452895605..8395026afe4e 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob.rst @@ -5,7 +5,7 @@ BLOB Transfer models The Binary Large Object (BLOB) Transfer models implement the Bluetooth Mesh Binary Large Object Transfer Model specification version 1.0 and provide functionality for sending large binary objects -from a single source to many Target nodes over the Bluetooth mesh network. It is the underlying +from a single source to many Target nodes over the Bluetooth Mesh network. It is the underlying transport method for the :ref:`bluetooth_mesh_dfu`, but may be used for other object transfer purposes. The implementation is in experimental state. @@ -50,7 +50,7 @@ structure of the BLOB, and applications are free to define any encoding or compr on the data itself. The BLOB transfer protocol does not provide any built-in integrity checks, encryption or -authentication of the BLOB data. However, the underlying encryption of the Bluetooth mesh protocol +authentication of the BLOB data. However, the underlying encryption of the Bluetooth Mesh protocol provides data integrity checks and protects the contents of the BLOB from third parties using network and application level encryption. @@ -68,7 +68,7 @@ Chunks ------ Each block is divided into chunks. A chunk is the smallest data unit in the BLOB transfer, and must -fit inside a single Bluetooth mesh access message excluding the opcode (379 bytes or less). The +fit inside a single Bluetooth Mesh access message excluding the opcode (379 bytes or less). The mechanism for transferring chunks depends on the transfer mode. When operating in Push BLOB Transfer Mode, the chunks are sent as unacknowledged packets from the diff --git a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst index 25b90c281c49..b4193d503347 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst @@ -67,7 +67,7 @@ Target nodes having the BLOB Transfer Server model subscribe to this group addre Using group addresses for transferring the BLOBs can generally increase the transfer speed, as the BLOB Transfer Client sends each message to all Target nodes at the same time. However, sending -large, segmented messages to group addresses in Bluetooth mesh is generally less reliable than +large, segmented messages to group addresses in Bluetooth Mesh is generally less reliable than sending them to unicast addresses, as there is no transport layer acknowledgment mechanism for groups. This can lead to longer recovery periods at the end of each block, and increases the risk of losing Target nodes. Using group addresses for BLOB transfers will generally only pay off if the diff --git a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst index 918b9493ff9a..0d13e92148e7 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst @@ -77,7 +77,7 @@ Transfer recovery ***************** The state of the BLOB transfer is stored persistently. If a reboot occurs, the BLOB Transfer Server -will attempt to recover the transfer. When the Bluetooth mesh subsystem is started (for instance by +will attempt to recover the transfer. When the Bluetooth Mesh subsystem is started (for instance by calling :c:func:`bt_mesh_init`), the BLOB Transfer Server will check for aborted transfers, and call the :c:member:`recover ` callback if there is any. In the recover callback, the user must provide a BLOB stream to use for the rest of the transfer. If the recover diff --git a/doc/connectivity/bluetooth/api/mesh/cfg.rst b/doc/connectivity/bluetooth/api/mesh/cfg.rst index 01d3c9ca2e52..e178984210d6 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg.rst @@ -6,7 +6,7 @@ Runtime Configuration The runtime configuration API allows applications to change their runtime configuration directly, without going through the Configuration models. -Bluetooth mesh nodes should generally be configured by a central network +Bluetooth Mesh nodes should generally be configured by a central network configurator device with a :ref:`bluetooth_mesh_models_cfg_cli` model. Each mesh node instantiates a :ref:`bluetooth_mesh_models_cfg_srv` model that the Configuration Client can communicate with to change the node configuration. In some diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst index bf84edc6b86c..300c8ee3bc1d 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst @@ -3,7 +3,7 @@ Configuration Client #################### -The Configuration Client model is a foundation model defined by the Bluetooth mesh +The Configuration Client model is a foundation model defined by the Bluetooth Mesh specification. It provides functionality for configuring most parameters of a mesh node, including encryption keys, model configuration and feature enabling. diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst index 84f174df88bd..8f595bf9b11a 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst @@ -3,7 +3,7 @@ Configuration Server #################### -The Configuration Server model is a foundation model defined by the Bluetooth mesh +The Configuration Server model is a foundation model defined by the Bluetooth Mesh specification. The Configuration Server model controls most parameters of the mesh node. It does not have an API of its own, but relies on a :ref:`bluetooth_mesh_models_cfg_cli` to control it. @@ -14,7 +14,7 @@ mesh node. It does not have an API of its own, but relies on a should be set through Kconfig, and the Heartbeat feature should be controlled through the :ref:`bluetooth_mesh_heartbeat` API. -The Configuration Server model is mandatory on all Bluetooth mesh nodes, and +The Configuration Server model is mandatory on all Bluetooth Mesh nodes, and must only be instantiated on the primary element. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/core.rst b/doc/connectivity/bluetooth/api/mesh/core.rst index b9fdd164257e..94e2b8a6e5ef 100644 --- a/doc/connectivity/bluetooth/api/mesh/core.rst +++ b/doc/connectivity/bluetooth/api/mesh/core.rst @@ -3,7 +3,7 @@ Core #### -The core provides functionality for managing the general Bluetooth mesh +The core provides functionality for managing the general Bluetooth Mesh state. .. _bluetooth_mesh_lpn: @@ -117,7 +117,7 @@ Advertisement identity All mesh stack bearers advertise data with the :c:macro:`BT_ID_DEFAULT` local identity. The value is preset in the mesh stack implementation. When Bluetooth® Low Energy (LE) -and Bluetooth mesh coexist on the same device, the application should allocate and +and Bluetooth Mesh coexist on the same device, the application should allocate and configure another local identity for Bluetooth LE purposes before starting the communication. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 9cf55e244d6d..6718b3ea0ce9 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -3,16 +3,16 @@ Device Firmware Update (DFU) ############################ -Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth +Bluetooth Mesh supports the distribution of firmware images across a mesh network. The Bluetooth mesh DFU subsystem implements the Bluetooth Mesh Device Firmware Update Model specification version 1.0. The implementation is in experimental state. -Bluetooth mesh DFU implements a distribution mechanism for firmware images, and does not put any +Bluetooth Mesh DFU implements a distribution mechanism for firmware images, and does not put any restrictions on the size, format or usage of the images. The primary design goal of the subsystem is -to provide the qualifiable parts of the Bluetooth mesh DFU specification, and leave the usage, +to provide the qualifiable parts of the Bluetooth Mesh DFU specification, and leave the usage, firmware validation and deployment to the application. -The DFU specification is implemented in the Zephyr Bluetooth mesh DFU subsystem as three separate +The DFU specification is implemented in the Zephyr Bluetooth Mesh DFU subsystem as three separate models: .. toctree:: @@ -28,7 +28,7 @@ Overview DFU roles ========= -The Bluetooth mesh DFU subsystem defines three different roles the mesh nodes have to assume in the +The Bluetooth Mesh DFU subsystem defines three different roles the mesh nodes have to assume in the distribution of firmware images: Target node @@ -47,20 +47,20 @@ Distributor image to the Target nodes. Initiator - The Initiator role is typically implemented by the same device that implements the Bluetooth mesh + The Initiator role is typically implemented by the same device that implements the Bluetooth Mesh :ref:`Provisioner ` and :ref:`Configurator ` roles. The Initiator needs a full overview of the potential Target nodes and their firmware, and will control (and initiate) all firmware updates. The - Initiator role is not implemented in the Zephyr Bluetooth mesh DFU subsystem. + Initiator role is not implemented in the Zephyr Bluetooth Mesh DFU subsystem. .. figure:: images/dfu_roles_mesh.svg :align: center :alt: Graphic overview of the DFU roles mesh nodes can have during the process of image distribution - DFU roles and the associated Bluetooth mesh models + DFU roles and the associated Bluetooth Mesh models -Bluetooth mesh applications may combine the DFU roles in any way they'd like, and even take on +Bluetooth Mesh applications may combine the DFU roles in any way they'd like, and even take on multiple instances of the same role by instantiating the models on separate elements. For instance, the Distributor and Initiator role can be combined by instantiating the :ref:`bluetooth_mesh_dfu_cli` on the Initiator node and calling its API directly. @@ -76,7 +76,7 @@ Firmware Update Client model directly, e.g. over a serial protocol. Stages ====== -The Bluetooth mesh DFU process is designed to act in three stages: +The Bluetooth Mesh DFU process is designed to act in three stages: Upload stage First, the image is uploaded to a Distributor in a mesh network by an external entity, such as a @@ -131,7 +131,7 @@ Firmware metadata Target node. The firmware metadata is optional, and its maximum length is determined by :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA_MAXLEN`. - The Bluetooth mesh DFU subsystem in Zephyr provides its own metadata format + The Bluetooth Mesh DFU subsystem in Zephyr provides its own metadata format (:c:struct:`bt_mesh_dfu_metadata`) together with a set of related functions that can be used by an end product. The support for it is enabled using the :kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` option. The format of the metadata is presented in @@ -299,7 +299,7 @@ following steps: node firmware image index and the firmware image metadata. Each Target node performs a metadata check and prepares their BLOB Transfer Server model for the transfer, before sending a status response to the Firmware Update Client, indicating if the firmware update will have any effect on - the Bluetooth mesh state of the node. + the Bluetooth Mesh state of the node. #. The Distributor's BLOB Transfer Client model transfers the firmware image to all Target nodes. #. Once the BLOB transfer has been received, the Target nodes' applications verify that the firmware is valid by performing checks such as signature verification or image checksums against the image diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst index 2642dec8cc95..105bdecb86cc 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst @@ -16,7 +16,7 @@ Firmware images The Firmware Update Server holds a list of all the updatable firmware images on the device. The full list shall be passed to the server through the ``_imgs`` parameter in -:c:macro:`BT_MESH_DFU_SRV_INIT`, and must be populated before the Bluetooth mesh subsystem is +:c:macro:`BT_MESH_DFU_SRV_INIT`, and must be populated before the Bluetooth Mesh subsystem is started. Each firmware image in the image list must be independently updatable, and should have its own firmware ID. @@ -33,9 +33,9 @@ application is described below: .. figure:: images/dfu_srv.svg :align: center - :alt: Bluetooth mesh Firmware Update Server transfer + :alt: Bluetooth Mesh Firmware Update Server transfer - Bluetooth mesh Firmware Update Server transfer + Bluetooth Mesh Firmware Update Server transfer Transfer check ============== @@ -118,7 +118,7 @@ updated image. When the transfer applies to the mesh application itself, the device might have to reboot as part of the swap. This restart can be performed from inside the apply callback, or done asynchronously. After booting up with the new firmware, the firmware image table should be updated before the -Bluetooth mesh subsystem is started. +Bluetooth Mesh subsystem is started. The Distributor will read out the firmware image table to confirm that the transfer was successfully applied. If the metadata check indicated that the device would become unprovisioned, the Target node diff --git a/doc/connectivity/bluetooth/api/mesh/health_srv.rst b/doc/connectivity/bluetooth/api/mesh/health_srv.rst index 84c543b4766f..6f7b1fc3f335 100644 --- a/doc/connectivity/bluetooth/api/mesh/health_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/health_srv.rst @@ -21,7 +21,7 @@ necessarily damaging to the device. Errors indicate conditions that are outside of the node's design limits, and may have caused invalid behavior or permanent damage to the device. -Fault values ``0x01`` to ``0x7f`` are reserved for the Bluetooth mesh +Fault values ``0x01`` to ``0x7f`` are reserved for the Bluetooth Mesh specification, and the full list of specification defined faults are available in :ref:`bluetooth_mesh_health_faults`. Fault values ``0x80`` to ``0xff`` are vendor specific. The list of faults are always reported with a company ID to @@ -57,6 +57,6 @@ API reference Health faults ============= -Fault values defined by the Bluetooth mesh specification. +Fault values defined by the Bluetooth Mesh specification. .. doxygengroup:: bt_mesh_health_faults diff --git a/doc/connectivity/bluetooth/api/mesh/heartbeat.rst b/doc/connectivity/bluetooth/api/mesh/heartbeat.rst index 16c2bfa78407..706625849c15 100644 --- a/doc/connectivity/bluetooth/api/mesh/heartbeat.rst +++ b/doc/connectivity/bluetooth/api/mesh/heartbeat.rst @@ -3,7 +3,7 @@ Heartbeat ######### -The Heartbeat feature provides functionality for monitoring Bluetooth mesh nodes +The Heartbeat feature provides functionality for monitoring Bluetooth Mesh nodes and determining the distance between nodes. The Heartbeat feature is configured through the :ref:`bluetooth_mesh_models_cfg_srv` model. diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst index 0eca28f1b2ae..96189e21dd31 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst @@ -3,7 +3,7 @@ Large Composition Data Client ############################# -The Large Composition Data Client model is a foundation model defined by the Bluetooth mesh +The Large Composition Data Client model is a foundation model defined by the Bluetooth Mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_CLI` option. diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst index f96436138b7d..f67b31c27f83 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst @@ -3,7 +3,7 @@ Large Composition Data Server ############################# -The Large Composition Data Server model is a foundation model defined by the Bluetooth mesh +The Large Composition Data Server model is a foundation model defined by the Bluetooth Mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_LARGE_COMP_DATA_SRV` option. diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index 3f5f94152ce3..94c3914ca53c 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -6,7 +6,7 @@ Mesh models Foundation models ***************** -The Bluetooth mesh specification defines foundation models that can be +The Bluetooth Mesh specification defines foundation models that can be used by network administrators to configure and diagnose mesh nodes. .. toctree:: @@ -34,7 +34,7 @@ used by network administrators to configure and diagnose mesh nodes. Model specification models ************************** -In addition to the foundation models defined in the Bluetooth mesh specification, the Bluetooth Mesh +In addition to the foundation models defined in the Bluetooth Mesh specification, the Bluetooth Mesh Model Specification defines several models, some of which are implemented in Zephyr: .. toctree:: diff --git a/doc/connectivity/bluetooth/api/mesh/msg.rst b/doc/connectivity/bluetooth/api/mesh/msg.rst index ae8b968198af..614d2604d908 100644 --- a/doc/connectivity/bluetooth/api/mesh/msg.rst +++ b/doc/connectivity/bluetooth/api/mesh/msg.rst @@ -3,7 +3,7 @@ Message ####### -The Bluetooth mesh message provides set of structures, macros and functions used +The Bluetooth Mesh message provides set of structures, macros and functions used for preparing message buffers, managing message and acknowledged message contexts. diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index 5fc841716ceb..e419acb7572c 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -3,7 +3,7 @@ On-Demand Private Proxy Client ############################## -The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth mesh +The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth Mesh specification. The model is optional, and is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` option. diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 700517e42833..3c2f993bb302 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -3,7 +3,7 @@ On-Demand Private Proxy Server ############################## -The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth mesh +The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth Mesh specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_SRV` option. The On-Demand Private Proxy Server model was introduced in the Bluetooth Mesh Protocol Specification diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst index 148557a4e81c..4648b4495cd4 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst @@ -3,7 +3,7 @@ Opcodes Aggregator Client ######################### -The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth mesh +The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth Mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` option. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst index cb531a4c3c8b..c9bcc8e5eb1c 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst @@ -11,7 +11,7 @@ The Private Beacon Client model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and provides functionality for configuring the :ref:`bluetooth_mesh_models_priv_beacon_srv` models. -The Private Beacons feature adds privacy to the different Bluetooth mesh +The Private Beacons feature adds privacy to the different Bluetooth Mesh beacons by periodically randomizing the beacon input data. This protects the mesh node from being tracked by devices outside the mesh network, and hides the network's IV index, IV update and the Key Refresh state. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst index 3c17cc446752..62450634a317 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst @@ -11,7 +11,7 @@ The Private Beacon Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and controls the mesh node's Private Beacon state, Private GATT Proxy state and Private Node Identity state. -The Private Beacons feature adds privacy to the different Bluetooth mesh +The Private Beacons feature adds privacy to the different Bluetooth Mesh beacons by periodically randomizing the beacon input data. This protects the mesh node from being tracked by devices outside the mesh network, and hides the network's IV index, IV update and the Key Refresh state. The Private Beacon Server diff --git a/doc/connectivity/bluetooth/api/mesh/provisioning.rst b/doc/connectivity/bluetooth/api/mesh/provisioning.rst index 36fa38927a3e..685c9dda455a 100644 --- a/doc/connectivity/bluetooth/api/mesh/provisioning.rst +++ b/doc/connectivity/bluetooth/api/mesh/provisioning.rst @@ -12,15 +12,15 @@ two devices operating in the following roles: Provisioning process. Before the provisioning process starts, the provisionee is an *unprovisioned device*. -The Provisioning module in the Zephyr Bluetooth mesh stack supports both the +The Provisioning module in the Zephyr Bluetooth Mesh stack supports both the Advertising and GATT Provisioning bearers for the provisionee role, as well as the Advertising Provisioning bearer for the provisioner role. The Provisioning process ************************ -All Bluetooth mesh nodes must be provisioned before they can participate in a -Bluetooth mesh network. The Provisioning API provides all the functionality +All Bluetooth Mesh nodes must be provisioned before they can participate in a +Bluetooth Mesh network. The Provisioning API provides all the functionality necessary for a device to become a provisioned mesh node. Provisioning is a five-step process, involving the following steps: @@ -176,7 +176,7 @@ Depending on the choice of public key exchange mechanism and authentication meth the provisioning process can be secure or insecure. On May 24th 2021, ANSSI `disclosed `_ -a set of vulnerabilities in the Bluetooth mesh provisioning protocol that showcased +a set of vulnerabilities in the Bluetooth Mesh provisioning protocol that showcased how the low entropy provided by the Blink, Vibrate, Push, Twist and Input/Output numeric OOB methods could be exploited in impersonation and MITM attacks. In response, the Bluetooth SIG has reclassified these OOB methods as diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index 823401c9571e..5e905f2c9ef7 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -3,7 +3,7 @@ Proxy ##### -The Proxy feature allows legacy devices like phones to access the Bluetooth mesh network through +The Proxy feature allows legacy devices like phones to access the Bluetooth Mesh network through GATT. The Proxy feature is only compiled in if the :kconfig:option:`CONFIG_BT_MESH_GATT_PROXY` option is set. The Proxy feature state is controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, and the initial value can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst index a0aa2b46a3ea..4f3354945c93 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst @@ -4,7 +4,7 @@ Segmentation and reassembly (SAR) ################################# Segmentation and reassembly (SAR) provides a way of handling larger upper transport layer messages -in a mesh network, with a purpose of enhancing the Bluetooth mesh throughput. The segmentation and +in a mesh network, with a purpose of enhancing the Bluetooth Mesh throughput. The segmentation and reassembly mechanism is used by the lower transport layer. The lower transport layer defines how the upper transport layer PDUs are segmented and reassembled @@ -23,7 +23,7 @@ required. Set the ``send rel`` flag (see :c:struct:`bt_mesh_msg_ctx`) to use the transmission and acknowledge single-segment segmented messages. The transport layer is able to transport up to 32 segments with its SAR mechanism, with a maximum -message (PDU) size of 384 octets. To configure message size for the Bluetooth mesh stack, use the +message (PDU) size of 384 octets. To configure message size for the Bluetooth Mesh stack, use the following Kconfig options: * :kconfig:option:`CONFIG_BT_MESH_RX_SEG_MAX` to set the maximum number of segments in an incoming message. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst index b017b53a01a8..1e2ab6c47a16 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst @@ -3,7 +3,7 @@ SAR Configuration Client ######################## -The SAR Configuration Client model is a foundation model defined by the Bluetooth mesh +The SAR Configuration Client model is a foundation model defined by the Bluetooth Mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_CLI` configuration option. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst index 2ea1446c9ea3..4280fae13506 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst @@ -3,13 +3,13 @@ SAR Configuration Server ######################## -The SAR Configuration Server model is a foundation model defined by the Bluetooth mesh +The SAR Configuration Server model is a foundation model defined by the Bluetooth Mesh specification. It is an optional model, enabled with the :kconfig:option:`CONFIG_BT_MESH_SAR_CFG_SRV` configuration option. The SAR Configuration Server model is introduced in the Bluetooth Mesh Protocol Specification version 1.1, and it supports the configuration of the -:ref:`segmentation and reassembly (SAR) ` behavior of a Bluetooth mesh node. +:ref:`segmentation and reassembly (SAR) ` behavior of a Bluetooth Mesh node. The model defines a set of states and messages for the SAR configuration. The SAR Configuration Server model defines two states, SAR Transmitter state and SAR Receiver state. diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 66bfcdf6168b..3d925f29a3eb 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -3,32 +3,32 @@ Bluetooth Mesh Shell #################### -The Bluetooth mesh shell subsystem provides a set of Bluetooth mesh shell commands for the -:ref:`shell_api` module. It allows for testing and exploring the Bluetooth mesh API through an +The Bluetooth Mesh shell subsystem provides a set of Bluetooth Mesh shell commands for the +:ref:`shell_api` module. It allows for testing and exploring the Bluetooth Mesh API through an interactive interface, without having to write an application. -The Bluetooth mesh shell interface provides access to most Bluetooth mesh features, including +The Bluetooth Mesh shell interface provides access to most Bluetooth Mesh features, including provisioning, configuration, and message sending. Prerequisites ************* -The Bluetooth mesh shell subsystem depends on the application to create the composition data and do +The Bluetooth Mesh shell subsystem depends on the application to create the composition data and do the mesh initialization. Application *********** -The Bluetooth mesh shell subsystem is most easily used through the Bluetooth mesh shell application +The Bluetooth Mesh shell subsystem is most easily used through the Bluetooth Mesh shell application under ``tests/bluetooth/mesh_shell``. See :ref:`shell_api` for information on how to connect and -interact with the Bluetooth mesh shell application. +interact with the Bluetooth Mesh shell application. Basic usage *********** -The Bluetooth mesh shell subsystem adds a single ``mesh`` command, which holds a set of +The Bluetooth Mesh shell subsystem adds a single ``mesh`` command, which holds a set of sub-commands. Every time the device boots up, make sure to call ``mesh init`` before any of the -other Bluetooth mesh shell commands can be called:: +other Bluetooth Mesh shell commands can be called:: uart:~$ mesh init @@ -82,7 +82,7 @@ Message sending =============== With an application key added (see above), the mesh node's transition parameters are all valid, and -the Bluetooth mesh shell can send raw mesh messages through the network. +the Bluetooth Mesh shell can send raw mesh messages through the network. For example, to send a Generic OnOff Set message, call:: @@ -107,7 +107,7 @@ configured network and application keys will receive and process the messages we Sending raw mesh packets is a good way to test model message handler implementations during development, as it can be done without having to implement the sending model. By default, only the -reception of the model messages can be tested this way, as the Bluetooth mesh shell only includes +reception of the model messages can be tested this way, as the Bluetooth Mesh shell only includes the foundation models. To receive a packet in the mesh node, you have to add a model with a valid opcode handler list to the composition data in ``subsys/bluetooth/mesh/shell.c``, and print the incoming message to the shell in the handler callback. @@ -115,7 +115,7 @@ incoming message to the shell in the handler callback. Parameter formats ***************** -The Bluetooth mesh shell commands are parsed with a variety of formats: +The Bluetooth Mesh shell commands are parsed with a variety of formats: .. list-table:: Parameter formats :widths: 1 4 2 @@ -139,12 +139,12 @@ The Bluetooth mesh shell commands are parsed with a variety of formats: Commands ******** -The Bluetooth mesh shell implements a large set of commands. Some of the commands accept parameters, +The Bluetooth Mesh shell implements a large set of commands. Some of the commands accept parameters, which are mentioned in brackets after the command name. For example, ``mesh lpn set ``. Mandatory parameters are marked with angle brackets (e.g. ````), and optional parameters are marked with square brackets (e.g. ``[DstAddr]``). -The Bluetooth mesh shell commands are divided into the following groups: +The Bluetooth Mesh shell commands are divided into the following groups: .. contents:: :depth: 1 @@ -282,7 +282,7 @@ Provisioning ============ To allow a device to broadcast connectable unprovisioned beacons, the -:kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the +:kconfig:option:`CONFIG_BT_MESH_PROVISIONEE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_GATT` option. ``mesh prov pb-gatt `` @@ -295,7 +295,7 @@ To allow a device to broadcast connectable unprovisioned beacons, the * ``Val``: Enable or disable provisioning with GATT To allow a device to broadcast unprovisioned beacons, the -:kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE` configuration option must be enabled, along with the +:kconfig:option:`CONFIG_BT_MESH_PROVISIONEE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_ADV` option. ``mesh prov pb-adv `` @@ -500,10 +500,10 @@ application. This shell module can be used for configuring itself and other node network. The Configuration Client uses general message parameters set by ``mesh target dst`` and ``mesh -target net`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, given that +target net`` to target specific nodes. When the Bluetooth Mesh shell node is provisioned, given that the :kconfig:option:`CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE` option is enabled with the shell provisioning context initialized, the Configuration Client model targets itself by default. -Similarly, when another node has been provisioned by the Bluetooth mesh shell, the Configuration +Similarly, when another node has been provisioned by the Bluetooth Mesh shell, the Configuration Client model targets the new node. In most common use-cases, the Configuration Client is depending on the provisioning features and the Configuration database to be fully functional. The Configuration Client always sends messages using the Device key bound to the destination address, so @@ -1645,7 +1645,7 @@ The Private Beacon Client model is an optional mesh subsystem that can be enable Opcodes Aggregator Client ------------------------- -The Opcodes Aggregator client is an optional Bluetooth mesh model that can be enabled through the +The Opcodes Aggregator client is an optional Bluetooth Mesh model that can be enabled through the :kconfig:option:`CONFIG_BT_MESH_OP_AGG_CLI` configuration option. The Opcodes Aggregator Client model is used to support the functionality of dispatching a sequence of access layer messages to nodes supporting the Opcodes Aggregator Server model. @@ -1675,7 +1675,7 @@ nodes supporting the Opcodes Aggregator Server model. Remote Provisioning Client -------------------------- -The Remote Provisioning Client is an optional Bluetooth mesh model enabled through the +The Remote Provisioning Client is an optional Bluetooth Mesh model enabled through the :kconfig:option:`CONFIG_BT_MESH_RPR_CLI` configuration option. The Remote Provisioning Client model provides support for remote provisioning of devices into a mesh network by using the Remote Provisioning Server model. diff --git a/doc/connectivity/bluetooth/bluetooth-arch.rst b/doc/connectivity/bluetooth/bluetooth-arch.rst index 9b455e680d0a..ed0cf1ea9f60 100644 --- a/doc/connectivity/bluetooth/bluetooth-arch.rst +++ b/doc/connectivity/bluetooth/bluetooth-arch.rst @@ -248,7 +248,7 @@ Each role comes with its own build-time configuration option: connection-oriented roles central implicitly enables observer role, and peripheral implicitly enables broadcaster role. Usually the first step when creating an application is to decide which roles are needed and go -from there. Bluetooth mesh is a slightly special case, requiring at +from there. Bluetooth Mesh is a slightly special case, requiring at least the observer and broadcaster roles, and possibly also the Peripheral role. This will be described in more detail in a later section. diff --git a/doc/connectivity/bluetooth/overview.rst b/doc/connectivity/bluetooth/overview.rst index fece4ade4963..1f727736b2de 100644 --- a/doc/connectivity/bluetooth/overview.rst +++ b/doc/connectivity/bluetooth/overview.rst @@ -76,7 +76,7 @@ Bluetooth stack. * Non-volatile storage support for permanent storage of Bluetooth-specific settings and data - * Bluetooth mesh support + * Bluetooth Mesh support * Relay, Friend Node, Low-Power Node (LPN) and GATT Proxy features * Both Provisioning roles and bearers supported (PB-ADV & PB-GATT) diff --git a/doc/connectivity/networking/api/coap_server.rst b/doc/connectivity/networking/api/coap_server.rst index 9a91081f4498..bd53630ad6c7 100644 --- a/doc/connectivity/networking/api/coap_server.rst +++ b/doc/connectivity/networking/api/coap_server.rst @@ -97,7 +97,7 @@ The following is an example of a CoAP resource registered with our service: coap_packet_append_payload(&response, (uint8_t *)msg, sizeof(msg)); /* Send to response back to the client */ - return coap_resource_send(resource, &response, addr, addr_len); + return coap_resource_send(resource, &response, addr, addr_len, NULL); } static int my_put(struct coap_resource *resource, struct coap_packet *request, @@ -189,7 +189,7 @@ and send state updates. An example using a temperature sensor can look like: coap_packet_append_payload_marker(&response); coap_packet_append_payload(&response, (uint8_t *)payload, strlen(payload)); - return coap_resource_send(resource, &response, addr, addr_len); + return coap_resource_send(resource, &response, addr, addr_len, NULL); } static int temp_get(struct coap_resource *resource, struct coap_packet *request, @@ -245,3 +245,4 @@ API Reference ************* .. doxygengroup:: coap_service +.. doxygengroup:: coap_mgmt diff --git a/doc/connectivity/networking/api/mqtt.rst b/doc/connectivity/networking/api/mqtt.rst index 973b61860e35..16ba69e12881 100644 --- a/doc/connectivity/networking/api/mqtt.rst +++ b/doc/connectivity/networking/api/mqtt.rst @@ -149,6 +149,7 @@ additional configuration information: tls_config->sec_tag_list = m_sec_tags; tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags); tls_config->hostname = MQTT_BROKER_HOSTNAME; + tls_config->set_native_tls = true; In this sample code, the ``m_sec_tags`` array holds a list of tags, referencing TLS credentials that the MQTT library should use for authentication. We do not specify @@ -161,6 +162,8 @@ Note, that TLS credentials referenced by the ``m_sec_tags`` array must be registered in the system first. For more information on how to do that, refer to :ref:`secure sockets documentation `. +Finally, ``set_native_tls`` can be optionally set to enable native TLS support instead of offloading TLS operations to the modem. + An example of how to use TLS with MQTT is also present in :zephyr:code-sample:`mqtt-publisher` sample application. diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index f2be0d8b5518..2cd96b3252bc 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -641,9 +641,8 @@ started. See :ref:`setting_configuration_values` for detailed documentation on setting Kconfig configuration values. The :ref:`initial-conf` section on the same page -explains how the initial configuration is derived. See :ref:`kconfig-search` -for a complete list of configuration options. -See :ref:`hardening` for security information related with Kconfig options. +explains how the initial configuration is derived. See :ref:`hardening` for +security information related with Kconfig options. The other pages in the :ref:`Kconfig section of the manual ` are also worth going through, especially if you planning to add new configuration diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index e644882191ef..f6ba54fa52ee 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -56,6 +56,18 @@ Pytest scans the given locations looking for tests, following its default `discovery rules `_ One can also pass some extra arguments to the pytest from yaml file using ``pytest_args`` keyword under ``harness_config``, e.g.: ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. +There is also an option to pass ``--pytest-args`` through Twister command line parameters. +This can be particularly useful when one wants to select a specific testcase from a test suite. +For instance, one can use a command: + +.. code-block:: console + + $ ./scripts/twister --platform native_sim -T samples/subsys/testsuite/pytest/shell \ + -s samples/subsys/testsuite/pytest/shell/sample.pytest.shell \ + --pytest-args='-k test_shell_print_version' + + +Note that ``--pytest-args`` can be passed multiple times to pass several arguments to the pytest. Helpers & fixtures ================== diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index 85968ca456a1..13204e6bb7d7 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -123,7 +123,7 @@ Zephyr offers a large and ever growing number of features including: **Bluetooth Low Energy 5.0 support** Bluetooth 5.0 compliant (ESR10) and Bluetooth Low Energy Controller support - (LE Link Layer). Includes Bluetooth mesh and a Bluetooth qualification-ready + (LE Link Layer). Includes Bluetooth Mesh and a Bluetooth qualification-ready Bluetooth controller. * Generic Access Profile (GAP) with all possible LE roles diff --git a/doc/kconfig.rst b/doc/kconfig.rst deleted file mode 100644 index 1123de2adbd9..000000000000 --- a/doc/kconfig.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -.. _kconfig-search: - -Kconfig Search -============== - -.. kconfig:search:: diff --git a/doc/kernel/timeutil.rst b/doc/kernel/timeutil.rst index d41c5b48b896..203d52ea9afd 100644 --- a/doc/kernel/timeutil.rst +++ b/doc/kernel/timeutil.rst @@ -223,7 +223,7 @@ include: - GPS time: epoch of 1980-01-06T00:00:00Z, continuous following TAI with an offset of TAI-GPS=19 s. -- Bluetooth mesh time: epoch of 2000-01-01T00:00:00Z, continuous following TAI +- Bluetooth Mesh time: epoch of 2000-01-01T00:00:00Z, continuous following TAI with an offset of -32. - UNIX Leap Time: epoch of 1970-01-01T00:00:00Z, continuous following TAI with an offset of -8. diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index c4b93e5f1507..c4cb37eaf948 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -55,6 +55,10 @@ Device Drivers and Device Tree (:github:`62994`) +* Runtime configuration is now disabled by default for Nordic UART drivers. The motivation for the + change is that this feature is rarely used and disabling it significantly reduces the memory + footprint. + Power Management ================ @@ -113,13 +117,24 @@ Bluetooth cleared on :c:func:`bt_enable`. Callbacks can now be registered before the initial call to :c:func:`bt_enable`, and should no longer be re-registered after a :c:func:`bt_disable` :c:func:`bt_enable` cycle. (:github:`63693`) -* The Bluetooth Mesh ``model`` declaration has been changed to add prefix ``const``. - The ``model->user_data``, ``model->elem_idx`` and ``model->mod_idx`` field has been changed to - the new runtime structure, replaced by ``model->rt->user_data``, ``model->rt->elem_idx`` and - ``model->rt->mod_idx`` separately. (:github:`65152`) -* The Bluetooth Mesh ``element`` declaration has been changed to add prefix ``const``. - The ``elem->addr`` field has been changed to the new runtime structure, replaced by - ``elem->rt->addr``. (:github:`65388`) +* The Bluetooth UUID has been modified to rodata in ``BT_UUID_DECLARE_16``, ``BT_UUID_DECLARE_32` + and ``BT_UUID_DECLARE_128`` as the return value has been changed to `const`. + Any pointer to a UUID must be prefixed with `const`, otherwise there will be a compilation warning. + For example change ``struct bt_uuid *uuid = BT_UUID_DECLARE_16(xx)`` to + ``const struct bt_uuid *uuid = BT_UUID_DECLARE_16(xx)``. (:github:`66136`) + +* Mesh + + * The Bluetooth Mesh ``model`` declaration has been changed to add prefix ``const``. + The ``model->user_data``, ``model->elem_idx`` and ``model->mod_idx`` field has been changed to + the new runtime structure, replaced by ``model->rt->user_data``, ``model->rt->elem_idx`` and + ``model->rt->mod_idx`` separately. (:github:`65152`) + * The Bluetooth Mesh ``element`` declaration has been changed to add prefix ``const``. + The ``elem->addr`` field has been changed to the new runtime structure, replaced by + ``elem->rt->addr``. (:github:`65388`) + * Deprecated :kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE`. This option is + replaced by new option :kconfig:option:`CONFIG_BT_MESH_PROVISIONEE` to + be aligned with Mesh Protocol Specification v1.1, section 5.4. (:github:`64252`) LoRaWAN ======= @@ -139,6 +154,32 @@ Networking ``request`` argument for :c:func:`coap_well_known_core_get` is made ``const``. (:github:`64265`) +* CoAP observer events have moved from a callback function in a CoAP resource to the Network Events + subsystem. The ``CONFIG_COAP_OBSERVER_EVENTS`` configuration option has been removed. + (:github:`65936`) + +* The CoAP public API function :c:func:`coap_pending_init` has changed. The parameter + ``retries`` is replaced with a pointer to :c:struct:`coap_transmission_parameters`. This allows to + specify retransmission parameters of the confirmable message. It is safe to pass a NULL pointer to + use default values. + (:github:`66482`) + +* The CoAP public API functions :c:func:`coap_service_send` and :c:func:`coap_resource_send` have + changed. An additional parameter pointer to :c:struct:`coap_transmission_parameters` has been + added. It is safe to pass a NULL pointer to use default values. (:github:`66540`) + +* The IGMP multicast library now supports IGMPv3. This results in a minor change to the existing + api. The :c:func:`net_ipv4_igmp_join` now takes an additional argument of the type + ``const struct igmp_param *param``. This allows IGMPv3 to exclude/include certain groups of + addresses. If this functionality is not used or available (when using IGMPv2), you can safely pass + a NULL pointer. IGMPv3 can be enabled using the Kconfig ``CONFIG_NET_IPV4_IGMPV3``. + (:github:`65293`) + +* The network stack now uses a separate IPv4 TTL (time-to-live) value for multicast packets. + Before, the same TTL value was used for unicast and multicast packets. + The IPv6 hop limit value is also changed so that unicast and multicast packets can have a + different one. (:github:`65886`) + Other Subsystems ================ diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst index 676e16fa77cd..f4d813432b14 100644 --- a/doc/releases/release-notes-3.6.rst +++ b/doc/releases/release-notes-3.6.rst @@ -52,6 +52,11 @@ Bluetooth * Mesh + * Added the delayable messages functionality to apply random delays for + the transmitted responses on the Access layer. + The functionality is enabled by the :kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG` + Kconfig option. + * Controller Boards & SoC Support @@ -149,6 +154,8 @@ Drivers and Sensors * IEEE 802.15.4 + * Removed :kconfig:option:`CONFIG_IEEE802154_SELECTIVE_TXPOWER` Kconfig option. + * Interrupt Controller * Input @@ -188,6 +195,11 @@ Networking * CoAP: + * Added new API functions: + + * :c:func:`coap_get_transmission_parameters` + * :c:func:`coap_set_transmission_parameters` + * Connection Manager: * DHCP: diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 61d0d25f6184..fde156983d30 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1176,7 +1176,7 @@ This has been fixed in main for v3.0.0 CVE-2022-1041 -------------- -Out-of-bound write vulnerability in the Bluetooth mesh core stack can be triggered during provisioning +Out-of-bound write vulnerability in the Bluetooth Mesh core stack can be triggered during provisioning This has been fixed in main for v3.1.0 @@ -1195,7 +1195,7 @@ This has been fixed in main for v3.1.0 CVE-2022-1042 -------------- -Out-of-bound write vulnerability in the Bluetooth mesh core stack can be triggered during provisioning +Out-of-bound write vulnerability in the Bluetooth Mesh core stack can be triggered during provisioning This has been fixed in main for v3.1.0 diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 72a20f47fc9f..6d1973ca0aae 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -170,7 +170,7 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, if (!repeat) { nrf_saadc_buffer_pointer_set( NRF_SAADC, - nrf_saadc_buffer_pointer_get(NRF_SAADC) + + (uint16_t *)nrf_saadc_buffer_pointer_get(NRF_SAADC) + nrf_saadc_amount_get(NRF_SAADC)); } } @@ -256,7 +256,7 @@ static int check_buffer_size(const struct adc_sequence *sequence, { size_t needed_buffer_size; - needed_buffer_size = active_channels * sizeof(nrf_saadc_value_t); + needed_buffer_size = active_channels * sizeof(uint16_t); if (sequence->options) { needed_buffer_size *= (1 + sequence->options->extra_samplings); } diff --git a/drivers/cache/CMakeLists.txt b/drivers/cache/CMakeLists.txt index 47c790f0a890..23cb11afb6a2 100644 --- a/drivers/cache/CMakeLists.txt +++ b/drivers/cache/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_CACHE_ASPEED cache_aspeed.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE cache_handlers.c) +zephyr_library_sources_ifdef(CONFIG_CACHE_NRF_CACHE cache_nrf.c) diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index 834cc49e1813..4dcb64f488ae 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -19,5 +19,6 @@ source "subsys/logging/Kconfig.template.log_config" comment "Device Drivers" source "drivers/cache/Kconfig.aspeed" +source "drivers/cache/Kconfig.nrf" endif # CACHE diff --git a/drivers/cache/Kconfig.nrf b/drivers/cache/Kconfig.nrf new file mode 100644 index 000000000000..820445db432f --- /dev/null +++ b/drivers/cache/Kconfig.nrf @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +config CACHE_NRF_CACHE + bool "nRF cache driver" + select CACHE_HAS_DRIVER + depends on HAS_NRFX && CACHE_MANAGEMENT + help + Enable support for the nRF cache driver. diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c new file mode 100644 index 000000000000..63d76a47d6ef --- /dev/null +++ b/drivers/cache/cache_nrf.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +LOG_MODULE_REGISTER(cache_nrfx, CONFIG_CACHE_LOG_LEVEL); + +#if !defined(NRF_ICACHE) && defined(NRF_CACHE) +#define NRF_ICACHE NRF_CACHE +#endif + +#define CACHE_LINE_SIZE 32 +#define CACHE_BUSY_RETRY_INTERVAL_US 10 + +static struct k_spinlock lock; + +enum k_nrf_cache_op { + /* + * Sequentially loop through all dirty lines and write those data units to + * memory. + * + * This is FLUSH in Zephyr nomenclature. + */ + K_NRF_CACHE_CLEAN, + + /* + * Mark all lines as invalid, ignoring any dirty data. + * + * This is INVALIDATE in Zephyr nomenclature. + */ + K_NRF_CACHE_INVD, + + /* + * Clean followed by invalidate + * + * This is FLUSH_AND_INVALIDATE in Zephyr nomenclature. + */ + K_NRF_CACHE_FLUSH, +}; + +static inline bool is_cache_busy(NRF_CACHE_Type *cache) +{ +#if NRF_CACHE_HAS_STATUS + return nrf_cache_busy_check(cache); +#else + return false; +#endif +} + +static inline void wait_for_cache(NRF_CACHE_Type *cache) +{ + while (is_cache_busy(cache)) { + k_busy_wait(CACHE_BUSY_RETRY_INTERVAL_US); + } +} + +static inline int _cache_all(NRF_CACHE_Type *cache, enum k_nrf_cache_op op) +{ + /* + * We really do not want to invalidate the whole cache. + */ + if (op == K_NRF_CACHE_INVD) { + return -ENOTSUP; + } + + k_spinlock_key_t key = k_spin_lock(&lock); + + /* + * Invalidating the whole cache is dangerous. For good measure + * disable the cache. + */ + nrf_cache_disable(cache); + + wait_for_cache(cache); + + switch (op) { + +#if NRF_CACHE_HAS_TASK_CLEAN + case K_NRF_CACHE_CLEAN: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANCACHE); + break; +#endif + + case K_NRF_CACHE_INVD: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATECACHE); + break; + +#if NRF_CACHE_HAS_TASK_FLUSH + case K_NRF_CACHE_FLUSH: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHCACHE); + break; +#endif + + default: + break; + } + + wait_for_cache(cache); + + nrf_cache_enable(cache); + + k_spin_unlock(&lock, key); + + return 0; +} + +static inline void _cache_line(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, uintptr_t line_addr) +{ + wait_for_cache(cache); + + nrf_cache_lineaddr_set(cache, line_addr); + + switch (op) { + +#if NRF_CACHE_HAS_TASK_CLEAN + case K_NRF_CACHE_CLEAN: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANLINE); + break; +#endif + + case K_NRF_CACHE_INVD: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATELINE); + break; + +#if NRF_CACHE_HAS_TASK_FLUSH + case K_NRF_CACHE_FLUSH: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHLINE); + break; +#endif + + default: + break; + } + + wait_for_cache(cache); +} + +static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, void *addr, + size_t size) +{ + uintptr_t line_addr = (uintptr_t)addr; + uintptr_t end_addr = line_addr + size; + + /* + * Align address to line size + */ + line_addr &= ~(CACHE_LINE_SIZE - 1); + + do { + k_spinlock_key_t key = k_spin_lock(&lock); + + _cache_line(cache, op, line_addr); + + k_spin_unlock(&lock, key); + + line_addr += CACHE_LINE_SIZE; + + } while (line_addr < end_addr); + + return 0; +} + +static inline int _cache_checks(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, void *addr, + size_t size, bool is_range) +{ + /* Check if the cache is enabled */ + if (!(cache->ENABLE & CACHE_ENABLE_ENABLE_Enabled)) { + return -EAGAIN; + } + + if (!is_range) { + return _cache_all(cache, op); + } + + /* Check for invalid address or size */ + if ((!addr) || (!size)) { + return -EINVAL; + } + + return _cache_range(cache, op, addr, size); +} + +#if defined(NRF_DCACHE) && NRF_CACHE_HAS_TASKS + +void cache_data_enable(void) +{ + nrf_cache_enable(NRF_DCACHE); +} + +void cache_data_disable(void) +{ + nrf_cache_disable(NRF_DCACHE); +} + +int cache_data_flush_all(void) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_CLEAN, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_data_invd_all(void) +{ + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_INVD, NULL, 0, false); +} + +int cache_data_flush_and_invd_all(void) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_FLUSH, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_data_flush_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_CLEAN, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +int cache_data_invd_range(void *addr, size_t size) +{ + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_INVD, addr, size, true); +} + +int cache_data_flush_and_invd_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_FLUSH, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +#else + +void cache_data_enable(void) +{ + /* Nothing */ +} + +void cache_data_disable(void) +{ + /* Nothing */ +} + +int cache_data_flush_all(void) +{ + return -ENOTSUP; +} + +int cache_data_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_data_flush_and_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_data_flush_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_data_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_data_flush_and_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +#endif /* NRF_DCACHE */ + +#if defined(NRF_ICACHE) && NRF_CACHE_HAS_TASKS + +void cache_instr_enable(void) +{ + nrf_cache_enable(NRF_ICACHE); +} + +void cache_instr_disable(void) +{ + nrf_cache_disable(NRF_ICACHE); +} + +int cache_instr_flush_all(void) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_CLEAN, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_invd_all(void) +{ + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_INVD, NULL, 0, false); +} + +int cache_instr_flush_and_invd_all(void) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_FLUSH, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_flush_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_CLEAN, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_invd_range(void *addr, size_t size) +{ + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_INVD, addr, size, true); +} + +int cache_instr_flush_and_invd_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_FLUSH, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +#else + +void cache_instr_enable(void) +{ + /* Nothing */ +} + +void cache_instr_disable(void) +{ + /* Nothing */ +} + +int cache_instr_flush_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_flush_and_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_flush_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_instr_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_instr_flush_and_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +#endif /* NRF_ICACHE */ diff --git a/drivers/console/uart_mux.c b/drivers/console/uart_mux.c index ca445a1f5b71..8ade93ef0bba 100644 --- a/drivers/console/uart_mux.c +++ b/drivers/console/uart_mux.c @@ -481,24 +481,6 @@ static int uart_mux_err_check(const struct device *dev) return -ENOTSUP; } -static int uart_mux_configure(const struct device *dev, - const struct uart_config *cfg) -{ - ARG_UNUSED(dev); - ARG_UNUSED(cfg); - - return -ENOTSUP; -} - -static int uart_mux_config_get(const struct device *dev, - struct uart_config *cfg) -{ - ARG_UNUSED(dev); - ARG_UNUSED(cfg); - - return -ENOTSUP; -} - static int uart_mux_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) { @@ -714,8 +696,6 @@ static struct uart_mux_driver_api uart_mux_driver_api = { .uart_api.poll_in = uart_mux_poll_in, .uart_api.poll_out = uart_mux_poll_out, .uart_api.err_check = uart_mux_err_check, - .uart_api.configure = uart_mux_configure, - .uart_api.config_get = uart_mux_config_get, .uart_api.fifo_fill = uart_mux_fifo_fill, .uart_api.fifo_read = uart_mux_fifo_read, .uart_api.irq_tx_enable = uart_mux_irq_tx_enable, diff --git a/drivers/disk/flashdisk.c b/drivers/disk/flashdisk.c index 6336ad4dfd03..3e43716c2b3c 100644 --- a/drivers/disk/flashdisk.c +++ b/drivers/disk/flashdisk.c @@ -420,6 +420,8 @@ static const struct disk_operations flash_disk_ops = { .ioctl = disk_flash_access_ioctl, }; +#ifndef USE_PARTITION_MANAGER +/* The non-Partition manager, DTS based generators below */ #define DT_DRV_COMPAT zephyr_flash_disk #define PARTITION_PHANDLE(n) DT_PHANDLE_BY_IDX(DT_DRV_INST(n), partition, 0) @@ -461,6 +463,82 @@ DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) "Devicetree node " DT_NODE_PATH(DT_DRV_INST(n)) \ " has cache size which is not a multiple of its sector size"); DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#else /* ifndef USE_PARTITION_MANAGER */ +/* Partition Manager based generators below */ + +/* Gets the PM_..._EXTRA_PARAM_##param value */ +#define PM_FLASH_DISK_ENTRY_EXTRA_PARAM(name, param) PM_##name##_EXTRA_PARAM_disk_##param + +/* Gets the PM_..._NAME value which is originally cased, as in yaml, partition name */ +#define PM_FLASH_DISK_ENTRY_PARTITION_NAME(name) PM_##name##_NAME + +/* Generates flashdiskN_cache variable name, where N is partition ID */ +#define PM_FLASH_DISK_CACHE_VARIABLE(n) UTIL_CAT(flashdisk, UTIL_CAT(FIXED_PARTITION_ID(n), _cache)) + +/* Generate cache buffers */ +#define CACHE_SIZE(n) (COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), (0), (1)) * \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size)) +#define DEFINE_FLASHDISKS_CACHE(n) \ + static uint8_t __aligned(4) PM_FLASH_DISK_CACHE_VARIABLE(n)[CACHE_SIZE(n)]; + +PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE) + +/* Generated single Flash Disk device data from Partition Manager partition. + * Partition is required to have type set to disk in partition definitions: + * type: disk + * and following extra params can be provided: + * extra_params: { + * name = "", + * cache_size = , + * sector_size = , + * read_only = + * } + * where: + * is mandatory device name that will be used by Disk Access and FAT FS to mount device; + * is cache r/w cache size, which is mandatory if read_only = 0 or not present, + * and should be multiple of ; + * is mandatory device sector size information, usually should be erase page size, + * for flash devices, for example 4096 bytes; + * read_only is optional, if not present then assumed false; can be 0(false) or 1(true). + */ +#define DEFINE_FLASHDISKS_DEVICE(n) \ +{ \ + .info = { \ + .ops = &flash_disk_ops, \ + .name = STRINGIFY(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, name)), \ + }, \ + .area_id = FIXED_PARTITION_ID(n), \ + .offset = FIXED_PARTITION_OFFSET(n), \ + .cache = PM_FLASH_DISK_CACHE_VARIABLE(n), \ + .cache_size = sizeof(PM_FLASH_DISK_CACHE_VARIABLE(n)), \ + .size = FIXED_PARTITION_SIZE(n), \ + .sector_size = PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size), \ +}, + +/* The bellow used PM_FOREACH_TYPE_disk is generated by Partition Manager foreach + * loop macro. The lower case _disk is type name for which the macro has been generated; + * partition entry can have multiple types set and foreach macro will be generated + * for every type found across partition definitions. + */ +static struct flashdisk_data flash_disks[] = { + PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_DEVICE) +}; + +#define VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY(n) \ + COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), \ + (/* cache-size is not used for read-only disks */), \ + (BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) != 0, \ + "Flash disk partition " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n))\ + " must have non-zero cache-size");)) +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) + +#define VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE(n) \ + BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) % \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size) == 0, \ + "Devicetree node " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n)) \ + " has cache size which is not a multiple of its sector size"); +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#endif /* USE_PARTITION_MANAGER */ static int disk_flash_init(void) { diff --git a/drivers/display/display_nrf_led_matrix.c b/drivers/display/display_nrf_led_matrix.c index dd36126a7ce3..e27fb76a92aa 100644 --- a/drivers/display/display_nrf_led_matrix.c +++ b/drivers/display/display_nrf_led_matrix.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef PWM_PRESENT #include @@ -89,6 +90,8 @@ struct display_drv_config { NRF_TIMER_Type *timer; #if USE_PWM NRF_PWM_Type *pwm; +#else + nrfx_gpiote_t gpiote; #endif uint8_t rows[ROW_COUNT]; uint8_t cols[COL_COUNT]; @@ -340,7 +343,7 @@ static void prepare_pixel_pulse(const struct device *dev, /* First timer channel is used for timing the period of pulses. */ nrf_timer_cc_set(dev_config->timer, 1 + channel_idx, pulse); - NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; + dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; #endif /* USE_PWM */ } @@ -370,7 +373,7 @@ static void timer_irq_handler(void *arg) } #else for (int i = 0; i < GROUP_SIZE; ++i) { - NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[i]] = 0; + dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0; } #endif @@ -466,7 +469,7 @@ static int instance_init(const struct device *dev) return -ENOMEM; } - err = nrfx_gpiote_channel_alloc(gpiote_ch); + err = nrfx_gpiote_channel_alloc(&dev_config->gpiote, gpiote_ch); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate GPIOTE channel."); /* Do not bother with freeing resources allocated @@ -479,7 +482,7 @@ static int instance_init(const struct device *dev) nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, nrf_timer_event_address_get(dev_config->timer, nrf_timer_compare_event_get(1 + i)), - nrf_gpiote_event_address_get(NRF_GPIOTE, + nrf_gpiote_event_address_get(dev_config->gpiote.p_reg, nrf_gpiote_out_task_get(*gpiote_ch))); nrf_ppi_channel_enable(NRF_PPI, ppi_ch); } @@ -530,6 +533,14 @@ static struct display_drv_data instance_data = { .blanking = true, }; +#if !USE_PWM +#define CHECK_GPIOTE_INST(node_id, prop, idx) \ + BUILD_ASSERT(NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) == \ + NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0), \ + "All column GPIOs must use the same GPIOTE instance"); +DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, CHECK_GPIOTE_INST) +#endif + #define GET_PIN_INFO(node_id, pha, idx) \ (DT_GPIO_PIN_BY_IDX(node_id, pha, idx) | \ (DT_PROP_BY_PHANDLE_IDX(node_id, pha, idx, port) << 5) | \ @@ -546,6 +557,9 @@ static const struct display_drv_config instance_config = { .timer = (NRF_TIMER_Type *)DT_REG_ADDR(TIMER_NODE), #if USE_PWM .pwm = (NRF_PWM_Type *)DT_REG_ADDR(PWM_NODE), +#else + .gpiote = NRFX_GPIOTE_INSTANCE( + NRF_DT_GPIOTE_INST_BY_IDX(MATRIX_NODE, col_gpios, 0)), #endif .rows = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, row_gpios, GET_PIN_INFO) }, .cols = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, GET_PIN_INFO) }, diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 99184f3b1e5a..7ca87d609446 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -28,6 +28,6 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypt if (CONFIG_BUILD_WITH_TFM) target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/drivers/entropy/Kconfig.psa_crypto b/drivers/entropy/Kconfig.psa_crypto index d06001225b05..18514a071d1c 100644 --- a/drivers/entropy/Kconfig.psa_crypto +++ b/drivers/entropy/Kconfig.psa_crypto @@ -7,6 +7,7 @@ config ENTROPY_PSA_CRYPTO_RNG bool "PSA Crypto Random source Entropy driver" depends on DT_HAS_ZEPHYR_PSA_CRYPTO_RNG_ENABLED select ENTROPY_HAS_DRIVER + select PSA_WANT_GENERATE_RANDOM default y help Enable the PSA Crypto source Entropy driver. diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index aac9830835a7..ff652f608229 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -50,4 +50,13 @@ config NORDIC_QSPI_NOR_XIP QSPI NOR flash chip is executed until the driver has been setup. This will also disable power management for the QSPI NOR flash chip. +config NORDIC_QSPI_NOR_TIMEOUT_MS + int "Timeout for QSPI operations (ms)" + default 500 + help + The QSPI peripheral operation timeout in milliseconds. + Primarily intended for long running operations such as + a flash sector erase. The 500 ms default allows for + most typical NOR flash chips to erase a sector. + endif # NORDIC_QSPI_NOR diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 28c705f6707d..c0e8c397d8e9 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -26,15 +26,15 @@ LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL); #include struct qspi_nor_data { +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + /* A semaphore to control QSPI deactivation. */ + struct k_sem count; +#endif #ifdef CONFIG_MULTITHREADING - /* The semaphore to control exclusive access on write/erase. */ - struct k_sem trans; /* The semaphore to control exclusive access to the device. */ struct k_sem sem; /* The semaphore to indicate that transfer has completed. */ struct k_sem sync; - /* The semaphore to control driver init/uninit. */ - struct k_sem count; #else /* CONFIG_MULTITHREADING */ /* A flag that signals completed transfer when threads are * not enabled. @@ -173,12 +173,6 @@ BUILD_ASSERT(DT_INST_PROP(0, address_size_32), "After entering 4 byte addressing mode, 4 byte addressing is expected"); #endif -#ifndef CONFIG_PM_DEVICE_RUNTIME -static bool qspi_initialized; -#endif - -static int qspi_device_init(const struct device *dev); -static void qspi_device_uninit(const struct device *dev); void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable); @@ -245,72 +239,99 @@ static inline int qspi_get_zephyr_ret_code(nrfx_err_t res) static inline void qspi_lock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - pm_device_busy_set(dev); - -#ifdef CONFIG_MULTITHREADING k_sem_take(&dev_data->sem, K_FOREVER); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev_data); -#endif /* CONFIG_MULTITHREADING */ - - /* - * Change the base clock divider only for the time the driver is locked - * to perform a QSPI operation, otherwise the power consumption would be - * increased also when the QSPI peripheral is idle. - * When XIP is enabled, there is nothing to do here as the changed - * divider is kept all the time. - */ -#if defined(CONFIG_SOC_SERIES_NRF53X) - if (!dev_data->xip_enabled) { - nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); - } #endif } static inline void qspi_unlock(const struct device *dev) { +#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* Restore the default base clock divider to reduce power consumption. - * Unless XIP is enabled, then the changed divider needs to be kept. - */ - if (!dev_data->xip_enabled) { - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); - } + k_sem_give(&dev_data->sem); #endif +} -#ifdef CONFIG_MULTITHREADING - k_sem_give(&dev_data->sem); -#else - ARG_UNUSED(dev_data); +static inline void qspi_clock_div_change(void) +{ +#ifdef CONFIG_SOC_SERIES_NRF53X + /* Make sure the base clock divider is changed accordingly + * before a QSPI transfer is performed. + */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); #endif +} - pm_device_busy_clear(dev); +static inline void qspi_clock_div_restore(void) +{ +#ifdef CONFIG_SOC_SERIES_NRF53X + /* Restore the default base clock divider to reduce power + * consumption when the QSPI peripheral is idle. + */ + nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); +#endif } -static inline void qspi_trans_lock(const struct device *dev) +static void qspi_acquire(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; - k_sem_take(&dev_data->trans, K_FOREVER); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev); -#endif /* CONFIG_MULTITHREADING */ +#if defined(CONFIG_PM_DEVICE_RUNTIME) + int rc = pm_device_runtime_get(dev); + + if (rc < 0) { + LOG_ERR("pm_device_runtime_get failed: %d", rc); + } +#elif defined(CONFIG_MULTITHREADING) + /* In multithreading, the driver can call qspi_acquire more than once + * before calling qspi_release. Keeping count, so QSPI is deactivated + * only at the last call (count == 0). + */ + k_sem_give(&dev_data->count); +#endif + + qspi_lock(dev); + + if (!dev_data->xip_enabled) { + qspi_clock_div_change(); + + pm_device_busy_set(dev); + } } -static inline void qspi_trans_unlock(const struct device *dev) +static void qspi_release(const struct device *dev) { -#ifdef CONFIG_MULTITHREADING struct qspi_nor_data *dev_data = dev->data; + bool deactivate = true; - k_sem_give(&dev_data->trans); -#else /* CONFIG_MULTITHREADING */ - ARG_UNUSED(dev); -#endif /* CONFIG_MULTITHREADING */ +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + /* The last thread to finish using the driver deactivates the QSPI */ + (void) k_sem_take(&dev_data->count, K_NO_WAIT); + deactivate = (k_sem_count_get(&dev_data->count) == 0); +#endif + + if (!dev_data->xip_enabled) { + qspi_clock_div_restore(); + + if (deactivate && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + (void) nrfx_qspi_deactivate(); + } + + pm_device_busy_clear(dev); + } + + qspi_unlock(dev); + +#if defined(CONFIG_PM_DEVICE_RUNTIME) + int rc = pm_device_runtime_put(dev); + + if (rc < 0) { + LOG_ERR("pm_device_runtime_put failed: %d", rc); + } +#endif } static inline void qspi_wait_for_completion(const struct device *dev, @@ -359,89 +380,6 @@ static void qspi_handler(nrfx_qspi_evt_t event, void *p_context) } } -static int qspi_device_init(const struct device *dev) -{ - struct qspi_nor_data *dev_data = dev->data; - - if (dev_data->xip_enabled) { - return 0; - } - -#ifdef CONFIG_PM_DEVICE_RUNTIME - return pm_device_runtime_get(dev); -#else - nrfx_err_t res; - int ret = 0; - - qspi_lock(dev); - - /* In multithreading, driver can call qspi_device_init more than once - * before calling qspi_device_uninit. Keepping count, so QSPI is - * uninitialized only at the last call (count == 0). - */ -#ifdef CONFIG_MULTITHREADING - k_sem_give(&dev_data->count); -#endif - - if (!qspi_initialized) { - const struct qspi_nor_config *dev_config = dev->config; - - res = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - ret = qspi_get_zephyr_ret_code(res); - qspi_initialized = (ret == 0); - } - - qspi_unlock(dev); - - return ret; -#endif -} - -static void qspi_device_uninit(const struct device *dev) -{ - struct qspi_nor_data *dev_data = dev->data; - - if (dev_data->xip_enabled) { - return; - } - -#ifdef CONFIG_PM_DEVICE_RUNTIME - int ret = pm_device_runtime_put(dev); - - if (ret < 0) { - LOG_ERR("Failed to schedule device sleep: %d", ret); - } -#else - bool last = true; - - qspi_lock(dev); - -#ifdef CONFIG_MULTITHREADING - /* The last thread to finish using the driver uninit the QSPI */ - (void) k_sem_take(&dev_data->count, K_NO_WAIT); - last = (k_sem_count_get(&dev_data->count) == 0); -#endif - - if (last) { - while (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { - if (IS_ENABLED(CONFIG_MULTITHREADING)) { - k_msleep(50); - } else { - k_busy_wait(50000); - } - } - - nrfx_qspi_uninit(); - - qspi_initialized = false; - } - - qspi_unlock(dev); -#endif -} - /* QSPI send custom command. * * If this is used for both send and receive the buffer sizes must be @@ -497,11 +435,8 @@ static int qspi_send_cmd(const struct device *dev, const struct qspi_cmd *cmd, .wren = wren, }; - qspi_lock(dev); - int res = nrfx_qspi_cinstr_xfer(&cinstr_cfg, tx_buf, rx_buf); - qspi_unlock(dev); return qspi_get_zephyr_ret_code(res); } @@ -526,27 +461,27 @@ static int qspi_rdsr(const struct device *dev, uint8_t sr_num) .op_code = opcode, .rx_buf = &sr_buf, }; - int ret = qspi_send_cmd(dev, &cmd, false); + int rc = qspi_send_cmd(dev, &cmd, false); - return (ret < 0) ? ret : sr; + return (rc < 0) ? rc : sr; } /* Wait until RDSR confirms write is not in progress. */ static int qspi_wait_while_writing(const struct device *dev) { - int ret; + int rc; do { - ret = qspi_rdsr(dev, 1); - } while ((ret >= 0) - && ((ret & SPI_NOR_WIP_BIT) != 0U)); + rc = qspi_rdsr(dev, 1); + } while ((rc >= 0) + && ((rc & SPI_NOR_WIP_BIT) != 0U)); - return (ret < 0) ? ret : 0; + return (rc < 0) ? rc : 0; } static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) { - int ret = 0; + int rc = 0; uint8_t opcode = SPI_NOR_CMD_WRSR; uint8_t length = 1; uint8_t sr_array[2] = {0}; @@ -559,12 +494,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) sr_array[0] = sr_val; #if SR1_WRITE_CLEARS_SR2 /* Writing sr1 clears sr2. need to read/modify/write both. */ - ret = qspi_rdsr(dev, 2); - if (ret < 0) { - LOG_ERR("RDSR for WRSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, 2); + if (rc < 0) { + LOG_ERR("RDSR for WRSR failed: %d", rc); + return rc; } - sr_array[1] = ret; + sr_array[1] = rc; length = 2; #endif } else { /* sr_num == 2 */ @@ -574,12 +509,12 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) * Uses standard WRSR opcode */ sr_array[1] = sr_val; - ret = qspi_rdsr(dev, 1); - if (ret < 0) { - LOG_ERR("RDSR for WRSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, 1); + if (rc < 0) { + LOG_ERR("RDSR for WRSR failed: %d", rc); + return rc; } - sr_array[0] = ret; + sr_array[0] = rc; length = 2; #elif IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_S2B1v6) /* Writing sr2 uses a dedicated WRSR2 command */ @@ -600,46 +535,30 @@ static int qspi_wrsr(const struct device *dev, uint8_t sr_val, uint8_t sr_num) .tx_buf = &sr_buf, }; - ret = qspi_send_cmd(dev, &cmd, true); + rc = qspi_send_cmd(dev, &cmd, true); /* Writing SR can take some time, and further * commands sent while it's happening can be * corrupted. Wait. */ - if (ret == 0) { - ret = qspi_wait_while_writing(dev); + if (rc == 0) { + rc = qspi_wait_while_writing(dev); } - return ret; + return rc; } #endif /* !IS_EQUAL(INST_0_QER, JESD216_DW15_QER_VAL_NONE) */ /* QSPI erase */ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) { - /* address must be sector-aligned */ - if ((addr % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } - - /* size must be a non-zero multiple of sectors */ - if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { - return -EINVAL; - } - - int rv = 0; const struct qspi_nor_config *params = dev->config; + int rc, rc2; - rv = qspi_device_init(dev); - if (rv != 0) { - goto out; - } - qspi_trans_lock(dev); - rv = qspi_nor_write_protection_set(dev, false); - if (rv != 0) { - goto out_trans_unlock; + rc = qspi_nor_write_protection_set(dev, false); + if (rc != 0) { + return rc; } - qspi_lock(dev); while (size > 0) { nrfx_err_t res = !NRFX_SUCCESS; uint32_t adj = 0; @@ -670,76 +589,20 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size) size -= adj; } else { LOG_ERR("erase error at 0x%lx size %zu", (long)addr, size); - rv = qspi_get_zephyr_ret_code(res); + rc = qspi_get_zephyr_ret_code(res); break; } } - qspi_unlock(dev); - - int rv2 = qspi_nor_write_protection_set(dev, true); - - if (!rv) { - rv = rv2; - } -out_trans_unlock: - qspi_trans_unlock(dev); + rc2 = qspi_nor_write_protection_set(dev, true); -out: - qspi_device_uninit(dev); - return rv; + return rc != 0 ? rc : rc2; } -/* Configures QSPI memory for the transfer */ -static int qspi_nrfx_configure(const struct device *dev) +static int configure_chip(const struct device *dev) { - struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* When the QSPI peripheral is activated, during the nrfx_qspi driver - * initialization, it reads the status of the connected flash chip. - * Make sure this transaction is performed with a valid base clock - * divider. - */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); -#endif - - nrfx_err_t res = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - -#if defined(CONFIG_SOC_SERIES_NRF53X) - /* Restore the default /4 divider after the QSPI initialization. */ - nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); -#endif - - int ret = qspi_get_zephyr_ret_code(res); - if (ret < 0) { - return ret; - } - -#if DT_INST_NODE_HAS_PROP(0, rx_delay) - if (!nrf53_errata_121()) { - nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); - } -#endif - - /* It may happen that after the flash chip was previously put into - * the DPD mode, the system was reset but the flash chip was not. - * Consequently, the flash chip can be in the DPD mode at this point. - * Some flash chips will just exit the DPD mode on the first CS pulse, - * but some need to receive the dedicated command to do it, so send it. - * This can be the case even if the current image does not have - * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image - * (for example the main image if the currently executing image is the - * bootloader) might have set DPD mode before reboot. As a result, - * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. - */ - ret = exit_dpd(dev); - if (ret < 0) { - return ret; - } + int rc = 0; /* Set QE to match transfer mode. If not using quad * it's OK to leave QE set, but doing so prevents use @@ -769,28 +632,28 @@ static int qspi_nrfx_configure(const struct device *dev) return -EINVAL; #endif - ret = qspi_rdsr(dev, sr_num); - if (ret < 0) { - LOG_ERR("RDSR failed: %d", ret); - return ret; + rc = qspi_rdsr(dev, sr_num); + if (rc < 0) { + LOG_ERR("RDSR failed: %d", rc); + return rc; } - uint8_t sr = (uint8_t)ret; + uint8_t sr = (uint8_t)rc; bool qe_state = ((sr & qe_mask) != 0U); LOG_DBG("RDSR %02x QE %d need %d: %s", sr, qe_state, qe_value, (qe_state != qe_value) ? "updating" : "no-change"); - ret = 0; + rc = 0; if (qe_state != qe_value) { sr ^= qe_mask; - ret = qspi_wrsr(dev, sr, sr_num); + rc = qspi_wrsr(dev, sr, sr_num); } - if (ret < 0) { + if (rc < 0) { LOG_ERR("QE %s failed: %d", qe_value ? "set" : "clear", - ret); - return ret; + rc); + return rc; } #endif @@ -802,20 +665,19 @@ static int qspi_nrfx_configure(const struct device *dev) /* Call will send write enable before instruction if that * requirement is encoded in INST_0_4BA. */ - ret = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); + rc = qspi_send_cmd(dev, &cmd, (INST_0_4BA & 0x02)); - if (ret < 0) { - LOG_ERR("E4BA cmd issue failed: %d.", ret); + if (rc < 0) { + LOG_ERR("E4BA cmd issue failed: %d.", rc); } else { LOG_DBG("E4BA cmd issued."); } } - return ret; + return rc; } -static int qspi_read_jedec_id(const struct device *dev, - uint8_t *id) +static int qspi_rdid(const struct device *dev, uint8_t *id) { const struct qspi_buf rx_buf = { .buf = id, @@ -826,18 +688,24 @@ static int qspi_read_jedec_id(const struct device *dev, .rx_buf = &rx_buf, }; - int ret = qspi_device_init(dev); - - if (ret == 0) { - ret = qspi_send_cmd(dev, &cmd, false); - } - qspi_device_uninit(dev); - - return ret; + return qspi_send_cmd(dev, &cmd, false); } #if defined(CONFIG_FLASH_JESD216_API) +static int qspi_read_jedec_id(const struct device *dev, uint8_t *id) +{ + int rc; + + qspi_acquire(dev); + + rc = qspi_rdid(dev, id); + + qspi_release(dev); + + return rc; +} + static int qspi_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { @@ -855,17 +723,10 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io2_level = true, .io3_level = true, }; + nrfx_err_t res; - int ret = qspi_device_init(dev); - nrfx_err_t res = NRFX_SUCCESS; - - if (ret != 0) { - LOG_DBG("qspi_device_init: %d", ret); - qspi_device_uninit(dev); - return ret; - } + qspi_acquire(dev); - qspi_lock(dev); res = nrfx_qspi_lfm_start(&cinstr_cfg); if (res != NRFX_SUCCESS) { LOG_DBG("lfm_start: %x", res); @@ -885,40 +746,13 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, } out: - qspi_unlock(dev); - qspi_device_uninit(dev); + qspi_release(dev); + return qspi_get_zephyr_ret_code(res); } #endif /* CONFIG_FLASH_JESD216_API */ -/** - * @brief Retrieve the Flash JEDEC ID and compare it with the one expected - * - * @param dev The device structure - * @return 0 on success, negative errno code otherwise - */ -static inline int qspi_nor_read_id(const struct device *dev) -{ - uint8_t id[SPI_NOR_MAX_ID_LEN]; - int ret = qspi_read_jedec_id(dev, id); - - if (ret != 0) { - return -EIO; - } - - const struct qspi_nor_config *qnc = dev->config; - - if (memcmp(qnc->id, id, SPI_NOR_MAX_ID_LEN) != 0) { - LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", - id[0], id[1], id[2], - qnc->id[0], qnc->id[1], qnc->id[2]); - return -ENODEV; - } - - return 0; -} - static inline nrfx_err_t read_non_aligned(const struct device *dev, off_t addr, void *dest, size_t size) @@ -993,6 +827,9 @@ static inline nrfx_err_t read_non_aligned(const struct device *dev, static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, size_t size) { + const struct qspi_nor_config *params = dev->config; + nrfx_err_t res; + if (!dest) { return -EINVAL; } @@ -1002,8 +839,6 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return 0; } - const struct qspi_nor_config *params = dev->config; - /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1013,23 +848,13 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest, return -EINVAL; } - int rc = qspi_device_init(dev); - - if (rc != 0) { - goto out; - } - - qspi_lock(dev); + qspi_acquire(dev); - nrfx_err_t res = read_non_aligned(dev, addr, dest, size); + res = read_non_aligned(dev, addr, dest, size); - qspi_unlock(dev); + qspi_release(dev); - rc = qspi_get_zephyr_ret_code(res); - -out: - qspi_device_uninit(dev); - return rc; + return qspi_get_zephyr_ret_code(res); } /* addr aligned, sptr not null, slen less than 4 */ @@ -1094,6 +919,9 @@ static int qspi_nor_write(const struct device *dev, off_t addr, const void *src, size_t size) { + const struct qspi_nor_config *params = dev->config; + int rc, rc2; + if (!src) { return -EINVAL; } @@ -1108,8 +936,6 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - const struct qspi_nor_config *params = dev->config; - /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1119,18 +945,12 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - nrfx_err_t res = NRFX_SUCCESS; - - int rc = qspi_device_init(dev); + qspi_acquire(dev); - if (rc != 0) { - goto out; - } + rc = qspi_nor_write_protection_set(dev, false); + if (rc == 0) { + nrfx_err_t res; - qspi_trans_lock(dev); - res = qspi_nor_write_protection_set(dev, false); - qspi_lock(dev); - if (!res) { if (size < 4U) { res = write_sub_word(dev, addr, src, size); } else if (!nrfx_is_in_ram(src) || @@ -1140,25 +960,31 @@ static int qspi_nor_write(const struct device *dev, off_t addr, res = nrfx_qspi_write(src, size, addr); qspi_wait_for_completion(dev, res); } + + rc = qspi_get_zephyr_ret_code(res); } - qspi_unlock(dev); - int res2 = qspi_nor_write_protection_set(dev, true); + rc2 = qspi_nor_write_protection_set(dev, true); - qspi_trans_unlock(dev); - if (!res) { - res = res2; - } + qspi_release(dev); - rc = qspi_get_zephyr_ret_code(res); -out: - qspi_device_uninit(dev); - return rc; + return rc != 0 ? rc : rc2; } static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) { const struct qspi_nor_config *params = dev->config; + int rc; + + /* address must be sector-aligned */ + if ((addr % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } + + /* size must be a non-zero multiple of sectors */ + if ((size == 0) || (size % QSPI_SECTOR_SIZE) != 0) { + return -EINVAL; + } /* affected region should be within device */ if (addr < 0 || @@ -1169,83 +995,117 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - int ret = qspi_erase(dev, addr, size); + qspi_acquire(dev); - return ret; + rc = qspi_erase(dev, addr, size); + + qspi_release(dev); + + return rc; } static int qspi_nor_write_protection_set(const struct device *dev, bool write_protect) { - int ret = 0; + int rc = 0; struct qspi_cmd cmd = { .op_code = ((write_protect) ? SPI_NOR_CMD_WRDI : SPI_NOR_CMD_WREN), }; if (qspi_send_cmd(dev, &cmd, false) != 0) { - ret = -EIO; + rc = -EIO; } - return ret; + return rc; } -/** - * @brief Configure the flash - * - * @param dev The flash device structure - * @param info The flash info structure - * @return 0 on success, negative errno code otherwise - */ -static int qspi_nor_configure(const struct device *dev) +static int qspi_init(const struct device *dev) { - int ret = qspi_nrfx_configure(dev); + const struct qspi_nor_config *dev_config = dev->config; + uint8_t id[SPI_NOR_MAX_ID_LEN]; + nrfx_err_t res; + int rc; - if (ret != 0) { - return ret; + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + rc = qspi_get_zephyr_ret_code(res); + if (rc < 0) { + return rc; } -#ifdef CONFIG_PM_DEVICE_RUNTIME - ret = pm_device_runtime_enable(dev); - if (ret < 0) { - LOG_ERR("Failed to enable runtime power management: %d", ret); - } else { - LOG_DBG("Runtime power management enabled"); +#if DT_INST_NODE_HAS_PROP(0, rx_delay) + if (!nrf53_errata_121()) { + nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); } -#else - qspi_device_uninit(dev); #endif - /* now the spi bus is configured, we can verify the flash id */ - if (qspi_nor_read_id(dev) != 0) { + /* It may happen that after the flash chip was previously put into + * the DPD mode, the system was reset but the flash chip was not. + * Consequently, the flash chip can be in the DPD mode at this point. + * Some flash chips will just exit the DPD mode on the first CS pulse, + * but some need to receive the dedicated command to do it, so send it. + * This can be the case even if the current image does not have + * CONFIG_PM_DEVICE set to enter DPD mode, as a previously executing image + * (for example the main image if the currently executing image is the + * bootloader) might have set DPD mode before reboot. As a result, + * attempt to exit DPD mode regardless of whether CONFIG_PM_DEVICE is set. + */ + rc = exit_dpd(dev); + if (rc < 0) { + return rc; + } + + /* Retrieve the Flash JEDEC ID and compare it with the one expected. */ + rc = qspi_rdid(dev, id); + if (rc < 0) { + return rc; + } + + if (memcmp(dev_config->id, id, SPI_NOR_MAX_ID_LEN) != 0) { + LOG_ERR("JEDEC id [%02x %02x %02x] expect [%02x %02x %02x]", + id[0], id[1], id[2], dev_config->id[0], + dev_config->id[1], dev_config->id[2]); return -ENODEV; } - return 0; + /* The chip is correct, it can be configured now. */ + return configure_chip(dev); } -/** - * @brief Initialize and configure the flash - * - * @param name The flash name - * @return 0 on success, negative errno code otherwise - */ static int qspi_nor_init(const struct device *dev) { - int rc; const struct qspi_nor_config *dev_config = dev->config; - int ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + int rc; - if (ret < 0) { - return ret; + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; } IRQ_CONNECT(DT_IRQN(QSPI_NODE), DT_IRQ(QSPI_NODE, priority), nrfx_isr, nrfx_qspi_irq_handler, 0); - rc = qspi_nor_configure(dev); + qspi_clock_div_change(); + + rc = qspi_init(dev); + + qspi_clock_div_restore(); + + if (!IS_ENABLED(CONFIG_NORDIC_QSPI_NOR_XIP) && nrfx_qspi_init_check()) { + (void)nrfx_qspi_deactivate(); + } + +#ifdef CONFIG_PM_DEVICE_RUNTIME + int rc2 = pm_device_runtime_enable(dev); + + if (rc2 < 0) { + LOG_ERR("Failed to enable runtime power management: %d", rc2); + } else { + LOG_DBG("Runtime power management enabled"); + } +#endif #ifdef CONFIG_NORDIC_QSPI_NOR_XIP - if (!rc) { + if (rc == 0) { /* Enable XIP mode for QSPI NOR flash, this will prevent the * flash from being powered down */ @@ -1317,11 +1177,11 @@ static int enter_dpd(const struct device *const dev) .op_code = SPI_NOR_CMD_DPD, }; uint32_t t_enter_dpd = DT_INST_PROP_OR(0, t_enter_dpd, 0); - int ret; + int rc; - ret = qspi_send_cmd(dev, &cmd, false); - if (ret < 0) { - return ret; + rc = qspi_send_cmd(dev, &cmd, false); + if (rc < 0) { + return rc; } if (t_enter_dpd) { @@ -1339,15 +1199,34 @@ static int enter_dpd(const struct device *const dev) static int exit_dpd(const struct device *const dev) { if (IS_ENABLED(DT_INST_PROP(0, has_dpd))) { + nrf_qspi_pins_t pins; + nrf_qspi_pins_t disconnected_pins = { + .sck_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .csn_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io0_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, + }; struct qspi_cmd cmd = { .op_code = SPI_NOR_CMD_RDPD, }; uint32_t t_exit_dpd = DT_INST_PROP_OR(0, t_exit_dpd, 0); - int ret; + nrfx_err_t res; + int rc; + + nrf_qspi_pins_get(NRF_QSPI, &pins); + nrf_qspi_pins_set(NRF_QSPI, &disconnected_pins); + res = nrfx_qspi_activate(true); + nrf_qspi_pins_set(NRF_QSPI, &pins); + + if (res != NRFX_SUCCESS) { + return -EIO; + } - ret = qspi_send_cmd(dev, &cmd, false); - if (ret < 0) { - return ret; + rc = qspi_send_cmd(dev, &cmd, false); + if (rc < 0) { + return rc; } if (t_exit_dpd) { @@ -1362,108 +1241,97 @@ static int exit_dpd(const struct device *const dev) } #ifdef CONFIG_PM_DEVICE -static int qspi_nor_pm_action(const struct device *dev, - enum pm_device_action action) +static int qspi_suspend(const struct device *dev) { - struct qspi_nor_data *dev_data = dev->data; const struct qspi_nor_config *dev_config = dev->config; - int ret; - nrfx_err_t err; + nrfx_err_t res; + int rc; - if (pm_device_is_busy(dev)) { + res = nrfx_qspi_mem_busy_check(); + if (res != NRFX_SUCCESS) { return -EBUSY; } - switch (action) { - case PM_DEVICE_ACTION_SUSPEND: -#ifndef CONFIG_PM_DEVICE_RUNTIME - /* If PM_DEVICE_RUNTIME, we don't uninit after RESUME */ - ret = qspi_device_init(dev); - if (ret < 0) { - return ret; - } -#endif + rc = enter_dpd(dev); + if (rc < 0) { + return rc; + } - if (dev_data->xip_enabled) { - return -EBUSY; - } + nrfx_qspi_uninit(); - if (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) { - return -EBUSY; - } + return pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); +} - ret = enter_dpd(dev); - if (ret < 0) { - return ret; - } +static int qspi_resume(const struct device *dev) +{ + const struct qspi_nor_config *dev_config = dev->config; + nrfx_err_t res; + int rc; - nrfx_qspi_uninit(); - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; - } - break; + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; + } - case PM_DEVICE_ACTION_RESUME: - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; - } - err = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - if (err != NRFX_SUCCESS) { - return -EIO; - } + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + if (res != NRFX_SUCCESS) { + return -EIO; + } - ret = exit_dpd(dev); - if (ret < 0) { - return ret; - } + return exit_dpd(dev); +} -#ifndef CONFIG_PM_DEVICE_RUNTIME - /* If PM_DEVICE_RUNTIME, we're immediately going to use the device */ - qspi_device_uninit(dev); -#endif +static int qspi_nor_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int rc; + + if (pm_device_is_busy(dev)) { + return -EBUSY; + } + + qspi_lock(dev); + qspi_clock_div_change(); + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + rc = qspi_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + rc = qspi_resume(dev); break; default: - return -ENOTSUP; + rc = -ENOTSUP; } - return 0; + qspi_clock_div_restore(); + qspi_unlock(dev); + + return rc; } #endif /* CONFIG_PM_DEVICE */ void z_impl_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) { struct qspi_nor_data *dev_data = dev->data; - int ret; if (dev_data->xip_enabled == enable) { return; } - ret = qspi_device_init(dev); - - if (ret != 0) { - LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", ret); - return; - } + qspi_acquire(dev); #if NRF_QSPI_HAS_XIPEN nrf_qspi_xip_set(NRF_QSPI, enable); #endif - qspi_lock(dev); if (enable) { (void)nrfx_qspi_activate(false); } dev_data->xip_enabled = enable; - qspi_unlock(dev); - qspi_device_uninit(dev); + qspi_release(dev); } #ifdef CONFIG_USERSPACE @@ -1481,11 +1349,12 @@ void z_vrfy_nrf_qspi_nor_xip_enable(const struct device *dev, bool enable) #endif /* CONFIG_USERSPACE */ static struct qspi_nor_data qspi_nor_dev_data = { +#if !defined(CONFIG_PM_DEVICE_RUNTIME) && defined(CONFIG_MULTITHREADING) + .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), +#endif #ifdef CONFIG_MULTITHREADING - .trans = Z_SEM_INITIALIZER(qspi_nor_dev_data.trans, 1, 1), .sem = Z_SEM_INITIALIZER(qspi_nor_dev_data.sem, 1, 1), .sync = Z_SEM_INITIALIZER(qspi_nor_dev_data.sync, 0, 1), - .count = Z_SEM_INITIALIZER(qspi_nor_dev_data.count, 0, K_SEM_MAX_LIMIT), #endif /* CONFIG_MULTITHREADING */ }; @@ -1517,6 +1386,7 @@ static const struct qspi_nor_config qspi_nor_dev_config = { .sck_delay = DT_INST_PROP(0, sck_delay), .spi_mode = INST_0_SPI_MODE, }, + .nrfx_cfg.timeout = CONFIG_NORDIC_QSPI_NOR_TIMEOUT_MS, .size = INST_0_BYTES, .id = DT_INST_PROP(0, jedec_id), diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index cc840309264e..b5a3fefa1e53 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,6 +37,11 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER +#include +#include +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ + #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -166,6 +171,12 @@ static int flash_nrf_read(const struct device *dev, off_t addr, } #endif +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS + if (addr < PM_APP_ADDRESS) { + return soc_secure_mem_read(data, (void *)addr, len); + } +#endif + nrf_nvmc_buffer_read(data, (uint32_t)addr, len); return 0; diff --git a/drivers/gpio/Kconfig.nrfx b/drivers/gpio/Kconfig.nrfx index 356c43cb5fa1..760a45204fdf 100644 --- a/drivers/gpio/Kconfig.nrfx +++ b/drivers/gpio/Kconfig.nrfx @@ -5,7 +5,12 @@ menuconfig GPIO_NRFX bool "nRF GPIO driver" default y depends on DT_HAS_NORDIC_NRF_GPIO_ENABLED - select NRFX_GPIOTE + select NRFX_GPIOTE0 if HAS_HW_NRF_GPIOTE0 + select NRFX_GPIOTE1 if HAS_HW_NRF_GPIOTE1 + select NRFX_GPIOTE20 if HAS_HW_NRF_GPIOTE20 + select NRFX_GPIOTE30 if HAS_HW_NRF_GPIOTE30 + select NRFX_GPIOTE130 if HAS_HW_NRF_GPIOTE130 + select NRFX_GPIOTE131 if HAS_HW_NRF_GPIOTE131 help Enable GPIO driver for nRF line of MCUs. diff --git a/drivers/gpio/gpio_b91.c b/drivers/gpio/gpio_b91.c index bc73f9db9f59..4c4c14dc9098 100644 --- a/drivers/gpio/gpio_b91.c +++ b/drivers/gpio/gpio_b91.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Driver dts compatibility: telink,b91_gpio */ diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 0aa282dda37d..d89c964cc90a 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define DT_DRV_COMPAT nordic_nrf_gpio #include @@ -25,6 +26,7 @@ struct gpio_nrfx_cfg { NRF_GPIO_Type *port; uint32_t edge_sense; uint8_t port_num; + nrfx_gpiote_t gpiote; }; static inline struct gpio_nrfx_data *get_port_data(const struct device *port) @@ -37,131 +39,139 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port return port->config; } -static int get_drive(gpio_flags_t flags, nrf_gpio_pin_drive_t *drive) +static bool has_gpiote(const struct gpio_nrfx_cfg *cfg) +{ + return cfg->gpiote.p_reg != NULL; +} + +static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) +{ + if (flags & GPIO_PULL_UP) { + return NRF_GPIO_PIN_PULLUP; + } else if (flags & GPIO_PULL_DOWN) { + return NRF_GPIO_PIN_PULLDOWN; + } + + return NRF_GPIO_PIN_NOPULL; +} + +static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, + gpio_flags_t flags) { + nrfx_err_t err = NRFX_SUCCESS; + uint8_t ch; + bool free_ch = false; + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); + nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); + nrf_gpio_pin_pull_t pull = get_pull(flags); + nrf_gpio_pin_drive_t drive; + switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) { case NRF_GPIO_DRIVE_S0S1: - *drive = NRF_GPIO_PIN_S0S1; + drive = NRF_GPIO_PIN_S0S1; break; case NRF_GPIO_DRIVE_S0H1: - *drive = NRF_GPIO_PIN_S0H1; + drive = NRF_GPIO_PIN_S0H1; break; case NRF_GPIO_DRIVE_H0S1: - *drive = NRF_GPIO_PIN_H0S1; + drive = NRF_GPIO_PIN_H0S1; break; case NRF_GPIO_DRIVE_H0H1: - *drive = NRF_GPIO_PIN_H0H1; + drive = NRF_GPIO_PIN_H0H1; break; case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_S0D1; + drive = NRF_GPIO_PIN_S0D1; break; case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_H0D1; + drive = NRF_GPIO_PIN_H0D1; break; case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0S1; + drive = NRF_GPIO_PIN_D0S1; break; case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0H1; + drive = NRF_GPIO_PIN_D0H1; break; default: return -EINVAL; } - return 0; -} - -static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) -{ - if (flags & GPIO_PULL_UP) { - return NRF_GPIO_PIN_PULLUP; - } else if (flags & GPIO_PULL_DOWN) { - return NRF_GPIO_PIN_PULLDOWN; + if (flags & GPIO_OUTPUT_INIT_HIGH) { + nrf_gpio_port_out_set(cfg->port, BIT(pin)); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + nrf_gpio_port_out_clear(cfg->port, BIT(pin)); } - return NRF_GPIO_PIN_NOPULL; -} + if (!has_gpiote(cfg)) { + nrf_gpio_pin_dir_t dir = (flags & GPIO_OUTPUT) + ? NRF_GPIO_PIN_DIR_OUTPUT + : NRF_GPIO_PIN_DIR_INPUT; + nrf_gpio_pin_input_t input = (flags & GPIO_INPUT) + ? NRF_GPIO_PIN_INPUT_CONNECT + : NRF_GPIO_PIN_INPUT_DISCONNECT; -static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, - gpio_flags_t flags) -{ - nrfx_err_t err = NRFX_SUCCESS; - uint8_t ch; - bool free_ch = false; - const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); + nrf_gpio_reconfigure(abs_pin, &dir, &input, &pull, &drive, NULL); + return 0; + } /* Get the GPIOTE channel associated with this pin, if any. It needs * to be freed when the pin is reconfigured or disconnected. */ if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - err = nrfx_gpiote_channel_get(abs_pin, &ch); + err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); free_ch = (err == NRFX_SUCCESS); } if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { /* Ignore the error code. The pin may not have been used. */ - (void)nrfx_gpiote_pin_uninit(abs_pin); - - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + (void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin); + } else { + /* Remove previously configured trigger when pin is reconfigured. */ + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { + nrfx_gpiote_trigger_config_t trigger_config = { + .trigger = NRFX_GPIOTE_TRIGGER_NONE, + }; + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_trigger_config = &trigger_config, + }; + + err = nrfx_gpiote_input_configure(&cfg->gpiote, + abs_pin, &input_pin_config); + if (err != NRFX_SUCCESS) { + return -EINVAL; + } } - return 0; - } - - if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - nrfx_gpiote_trigger_config_t trigger_config = { - .trigger = NRFX_GPIOTE_TRIGGER_NONE - }; + if (flags & GPIO_OUTPUT) { + nrfx_gpiote_output_config_t output_config = { + .drive = drive, + .input_connect = (flags & GPIO_INPUT) + ? NRF_GPIO_PIN_INPUT_CONNECT + : NRF_GPIO_PIN_INPUT_DISCONNECT, + .pull = pull, + }; + + err = nrfx_gpiote_output_configure(&cfg->gpiote, + abs_pin, &output_config, NULL); + } else { + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_pull_config = &pull, + }; + + err = nrfx_gpiote_input_configure(&cfg->gpiote, + abs_pin, &input_pin_config); + } - /* Remove previously configured trigger when pin is reconfigured. */ - err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); if (err != NRFX_SUCCESS) { return -EINVAL; } - - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); - } } - if (flags & GPIO_OUTPUT) { - nrf_gpio_pin_drive_t drive; - int rv = get_drive(flags, &drive); - - if (rv != 0) { - return rv; - } - - nrfx_gpiote_output_config_t output_config = { - .drive = drive, - .input_connect = (flags & GPIO_INPUT) ? - NRF_GPIO_PIN_INPUT_CONNECT : - NRF_GPIO_PIN_INPUT_DISCONNECT, - .pull = get_pull(flags) - }; - - - if (flags & GPIO_OUTPUT_INIT_HIGH) { - nrf_gpio_port_out_set(cfg->port, BIT(pin)); - } else if (flags & GPIO_OUTPUT_INIT_LOW) { - nrf_gpio_port_out_clear(cfg->port, BIT(pin)); - } - - err = nrfx_gpiote_output_configure(abs_pin, &output_config, NULL); - return (err != NRFX_SUCCESS) ? -EINVAL : 0; + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT) && free_ch) { + err = nrfx_gpiote_channel_free(&cfg->gpiote, ch); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); } - nrfx_gpiote_input_config_t input_config = { - .pull = get_pull(flags) - }; - - err = nrfx_gpiote_input_configure(abs_pin, &input_config, NULL, NULL); - - return (err != NRFX_SUCCESS) ? -EINVAL : 0; + return 0; } static int gpio_nrfx_port_get_raw(const struct device *port, @@ -242,12 +252,17 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, enum gpio_int_mode mode, enum gpio_int_trig trig) { - uint32_t abs_pin = NRF_GPIO_PIN_MAP(get_port_cfg(port)->port_num, pin); + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); + uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); nrfx_err_t err; uint8_t ch; + if (!has_gpiote(cfg)) { + return -ENOTSUP; + } + if (mode == GPIO_INT_MODE_DISABLED) { - nrfx_gpiote_trigger_disable(abs_pin); + nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin); return 0; } @@ -255,16 +270,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, nrfx_gpiote_trigger_config_t trigger_config = { .trigger = get_trigger(mode, trig), }; + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_trigger_config = &trigger_config, + }; /* If edge mode is to be used and pin is not configured to use sense for * edge use IN event. */ - if (!(BIT(pin) & get_port_cfg(port)->edge_sense) && + if (!(BIT(pin) & cfg->edge_sense) && (mode == GPIO_INT_MODE_EDGE) && (nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) { - err = nrfx_gpiote_channel_get(abs_pin, &ch); + err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); if (err == NRFX_ERROR_INVALID_PARAM) { - err = nrfx_gpiote_channel_alloc(&ch); + err = nrfx_gpiote_channel_alloc(&cfg->gpiote, &ch); if (err != NRFX_SUCCESS) { return -ENOMEM; } @@ -273,12 +291,12 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, trigger_config.p_in_channel = &ch; } - err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); + err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config); if (err != NRFX_SUCCESS) { return -EINVAL; } - nrfx_gpiote_trigger_enable(abs_pin, true); + nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true); return 0; } @@ -367,26 +385,31 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, } #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ -#define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote) +#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ + IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \ + NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0); static int gpio_nrfx_init(const struct device *port) { + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); nrfx_err_t err; - if (nrfx_gpiote_is_init()) { + if (!has_gpiote(cfg)) { + return 0; + } + + if (nrfx_gpiote_init_check(&cfg->gpiote)) { return 0; } - err = nrfx_gpiote_init(0/*not used*/); + err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/); if (err != NRFX_SUCCESS) { return -EIO; } #ifdef CONFIG_GPIO_NRFX_INTERRUPT - nrfx_gpiote_global_callback_set(nrfx_gpio_handler, NULL); - - IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), - nrfx_isr, nrfx_gpiote_irq_handler, 0); + nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL); + DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT); #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ return 0; @@ -408,12 +431,27 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { #endif }; +#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance) +#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance) + +#define GPIOTE_INSTANCE(id) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ + (NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \ + ({ .p_reg = NULL })) + /* Device instantiation is done with node labels because 'port_num' is * the peripheral number by SoC numbering. We therefore cannot use * DT_INST APIs here without wider changes. */ +#define GPIOTE_CHECK(id) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ + (BUILD_ASSERT(DT_NODE_HAS_STATUS(GPIOTE_PHANDLE(id), okay), \ + "Please enable GPIOTE instance for used GPIO port!")), \ + ()) + #define GPIO_NRF_DEVICE(id) \ + GPIOTE_CHECK(id); \ static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \ .common = { \ .port_pin_mask = \ @@ -421,7 +459,8 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { }, \ .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \ .port_num = DT_INST_PROP(id, port), \ - .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0) \ + .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \ + .gpiote = GPIOTE_INSTANCE(id), \ }; \ \ static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \ diff --git a/drivers/gpio/gpio_sifive.c b/drivers/gpio/gpio_sifive.c index 77703f257072..a412fdd15284 100644 --- a/drivers/gpio/gpio_sifive.c +++ b/drivers/gpio/gpio_sifive.c @@ -18,7 +18,7 @@ #include #include #include - +#include #include typedef void (*sifive_cfg_func_t)(void); diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 7c4cc7f08051..4bf9e462318a 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -181,7 +181,7 @@ config HWINFO_GECKO config HWINFO_ANDES bool "Andes system ID" default y - depends on SOC_SERIES_RISCV_ANDES_V5 + depends on SOC_FAMILY_ANDES_V5 help Enable Andes hwinfo driver diff --git a/drivers/hwinfo/hwinfo_nrf.c b/drivers/hwinfo/hwinfo_nrf.c index 2a79f1d0c0d1..4375cf05b2f2 100644 --- a/drivers/hwinfo/hwinfo_nrf.c +++ b/drivers/hwinfo/hwinfo_nrf.c @@ -58,22 +58,56 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) if (reason & NRFX_RESET_REASON_DIF_MASK) { flags |= RESET_DEBUG; } + if (reason & NRFX_RESET_REASON_SREQ_MASK) { + flags |= RESET_SOFTWARE; + } -#if !NRF_POWER_HAS_RESETREAS +#if NRFX_RESET_REASON_HAS_CTRLAP if (reason & NRFX_RESET_REASON_CTRLAP_MASK) { flags |= RESET_DEBUG; } - if (reason & NRFX_RESET_REASON_DOG0_MASK) { - flags |= RESET_WATCHDOG; +#endif +#if NRFX_RESET_REASON_HAS_LPCOMP + if (reason & NRFX_RESET_REASON_LPCOMP_MASK) { + flags |= RESET_LOW_POWER_WAKE; + } +#endif +#if NRFX_RESET_REASON_HAS_NFC + if (reason & NRFX_RESET_REASON_NFC_MASK) { + flags |= RESET_LOW_POWER_WAKE; + } +#endif +#if NRFX_RESET_REASON_HAS_VBUS + if (reason & NRFX_RESET_REASON_VBUS_MASK) { + flags |= RESET_POR; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPSOFT + if (reason & NRFX_RESET_REASON_CTRLAPSOFT_MASK) { + flags |= RESET_DEBUG; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPHARD + if (reason & NRFX_RESET_REASON_CTRLAPHARD_MASK) { + flags |= RESET_DEBUG; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPPIN + if (reason & NRFX_RESET_REASON_CTRLAPPIN_MASK) { + flags |= RESET_DEBUG; } +#endif +#if !NRF_POWER_HAS_RESETREAS if (reason & NRFX_RESET_REASON_DOG1_MASK) { flags |= RESET_WATCHDOG; } - if (reason & NRFX_RESETREAS_SREQ_MASK) { - flags |= RESET_SOFTWARE; +#endif +#if NRFX_RESET_REASON_HAS_GRTC + if (reason & NRFX_RESET_REASON_GRTC_MASK) { + flags |= RESET_CLOCK; } - -#if NRF_RESET_HAS_NETWORK +#endif +#if NRFX_RESET_REASON_HAS_NETWORK if (reason & NRFX_RESET_REASON_LSREQ_MASK) { flags |= RESET_SOFTWARE; } @@ -87,10 +121,14 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) flags |= RESET_DEBUG; } #endif - -#else - if (reason & NRFX_RESET_REASON_SREQ_MASK) { - flags |= RESET_SOFTWARE; +#if defined(NRFX_RESET_REASON_TAMPC_MASK) + if (reason & NRFX_RESET_REASON_TAMPC_MASK) { + flags |= RESET_SECURITY; + } +#endif +#if defined(NRFX_RESET_REASON_SECTAMPER_MASK) + if (reason & NRFX_RESET_REASON_SECTAMPER_MASK) { + flags |= RESET_SECURITY; } #endif diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index feccd4a60012..d692024b096d 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -98,11 +98,6 @@ config IEEE802154_CSL_DEBUG help Enable support for CSL debugging by avoiding sleep state in favor of receive state. -config IEEE802154_SELECTIVE_TXPOWER - bool "Support selective TX power setting" - help - Enable support for selectively setting TX power for every transmission request. - module = IEEE802154_DRIVER module-str = IEEE 802.15.4 driver module-help = Sets log level for IEEE 802.15.4 Device Drivers. diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 0557c5339442..0897b2b54df9 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -26,6 +26,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #endif +#include + #include "ieee802154_b91.h" diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 9a02aef7e4ce..1831a5b4a6a2 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -57,6 +57,9 @@ struct nrf5_802154_config { }; static struct nrf5_802154_data nrf5_data; +#if defined(CONFIG_IEEE802154_RAW_MODE) +static const struct device *nrf5_dev; +#endif #define DRX_SLOT_RX 0 /* Delayed reception window ID */ @@ -95,6 +98,15 @@ static struct nrf5_802154_data nrf5_data; #define IEEE802154_NRF5_VENDOR_OUI (uint32_t)0xF4CE36 #endif +static inline const struct device *nrf5_get_device(void) +{ +#if defined(CONFIG_IEEE802154_RAW_MODE) + return nrf5_dev; +#else + return net_if_get_device(nrf5_data.iface); +#endif +} + static void nrf5_get_eui64(uint8_t *mac) { uint64_t factoryAddress; @@ -224,6 +236,7 @@ static void nrf5_get_capabilities_at_boot(void) ((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) | ((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) | IEEE802154_HW_SLEEP_TO_TX | + IEEE802154_RX_ON_WHEN_IDLE | ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL) #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) | IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA @@ -363,7 +376,7 @@ static int nrf5_set_txpower(const struct device *dev, int16_t dbm) LOG_DBG("%d", dbm); - nrf_802154_tx_power_set(dbm); + nrf5_data.txpwr = dbm; return 0; } @@ -442,10 +455,8 @@ static bool nrf5_tx_immediate(struct net_pkt *pkt, uint8_t *payload, bool cca) }, .cca = cca, .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, }; @@ -461,10 +472,8 @@ static bool nrf5_tx_csma_ca(struct net_pkt *pkt, uint8_t *payload) .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt), }, .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, }; @@ -507,10 +516,8 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, .cca = cca, .channel = nrf_802154_channel_get(), .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) .extra_cca_attempts = max_extra_cca_attempts, @@ -648,6 +655,8 @@ static int nrf5_start(const struct device *dev) { ARG_UNUSED(dev); + nrf_802154_tx_power_set(nrf5_data.txpwr); + if (!nrf_802154_receive()) { LOG_ERR("Failed to enter receive state"); return -EIO; @@ -690,6 +699,8 @@ static int nrf5_continuous_carrier(const struct device *dev) { ARG_UNUSED(dev); + nrf_802154_tx_power_set(nrf5_data.txpwr); + if (!nrf_802154_continuous_carrier()) { LOG_ERR("Failed to enter continuous carrier state"); return -EIO; @@ -726,6 +737,9 @@ static int nrf5_init(const struct device *dev) { const struct nrf5_802154_config *nrf5_radio_cfg = NRF5_802154_CFG(dev); struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); +#if defined(CONFIG_IEEE802154_RAW_MODE) + nrf5_dev = dev; +#endif k_fifo_init(&nrf5_radio->rx_fifo); k_sem_init(&nrf5_radio->tx_wait, 0, 1); @@ -735,6 +749,7 @@ static int nrf5_init(const struct device *dev) nrf5_get_capabilities_at_boot(); + nrf5_radio->rx_on_when_idle = true; nrf5_radio_cfg->irq_config_func(dev); k_thread_create(&nrf5_radio->rx_thread, nrf5_radio->rx_stack, @@ -766,25 +781,17 @@ static void nrf5_iface_init(struct net_if *iface) #if defined(CONFIG_NRF_802154_ENCRYPTION) static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys) { - static nrf_802154_key_id_t stored_key_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE]; - static uint8_t stored_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE]; - uint8_t i; + nrf_802154_security_key_remove_all(); - for (i = 0; i < NRF_802154_SECURITY_KEY_STORAGE_SIZE && stored_key_ids[i].p_key_id; i++) { - nrf_802154_security_key_remove(&stored_key_ids[i]); - stored_key_ids[i].p_key_id = NULL; - } - - i = 0; - for (struct ieee802154_key *keys = mac_keys; keys->key_value - && i < NRF_802154_SECURITY_KEY_STORAGE_SIZE; keys++, i++) { + for (uint8_t i = 0; mac_keys->key_value + && i < NRF_802154_SECURITY_KEY_STORAGE_SIZE; mac_keys++, i++) { nrf_802154_key_t key = { - .value.p_cleartext_key = keys->key_value, - .id.mode = keys->key_id_mode, - .id.p_key_id = &(keys->key_index), + .value.p_cleartext_key = mac_keys->key_value, + .id.mode = mac_keys->key_id_mode, + .id.p_key_id = mac_keys->key_id, .type = NRF_802154_KEY_CLEARTEXT, .frame_counter = 0, - .use_global_frame_counter = !(keys->frame_counter_per_key), + .use_global_frame_counter = !(mac_keys->frame_counter_per_key), }; __ASSERT_EVAL((void)nrf_802154_security_key_store(&key), @@ -792,10 +799,6 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys) err == NRF_802154_SECURITY_ERROR_NONE || err == NRF_802154_SECURITY_ERROR_ALREADY_PRESENT, "Storing key failed, err: %d", err); - - stored_ids[i] = *key.id.p_key_id; - stored_key_ids[i].mode = key.id.mode; - stored_key_ids[i].p_key_id = &stored_ids[i]; }; } #endif /* CONFIG_NRF_802154_ENCRYPTION */ @@ -882,35 +885,44 @@ static int nrf5_configure(const struct device *dev, uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE]; uint8_t short_addr_le[SHORT_ADDRESS_SIZE]; uint8_t element_id; + bool valid_vendor_specific_ie = false; + + if (config->ack_ie.purge_ie) { + nrf_802154_ack_data_remove_all(false, NRF_802154_ACK_DATA_IE); + nrf_802154_ack_data_remove_all(true, NRF_802154_ACK_DATA_IE); + break; + } if (config->ack_ie.short_addr == IEEE802154_BROADCAST_ADDRESS || config->ack_ie.ext_addr == NULL) { return -ENOTSUP; } - element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie); + sys_put_le16(config->ack_ie.short_addr, short_addr_le); + sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE); - if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE && - (!IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) || - element_id != IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE)) { - return -ENOTSUP; - } + if (config->ack_ie.header_ie == NULL || config->ack_ie.header_ie->length == 0) { + nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE); + nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE); + } else { + element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie); #if defined(CONFIG_NET_L2_OPENTHREAD) - uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] = - IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI; + uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] = + IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI; - if (element_id == IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE && - memcmp(config->ack_ie.header_ie->content.vendor_specific.vendor_oui, - vendor_oui_le, sizeof(vendor_oui_le))) { - return -ENOTSUP; - } + if (element_id == IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE && + memcmp(config->ack_ie.header_ie->content.vendor_specific.vendor_oui, + vendor_oui_le, sizeof(vendor_oui_le)) == 0) { + valid_vendor_specific_ie = true; + } #endif - sys_put_le16(config->ack_ie.short_addr, short_addr_le); - sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE); + if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE && + !valid_vendor_specific_ie) { + return -ENOTSUP; + } - if (config->ack_ie.header_ie && config->ack_ie.header_ie->length > 0) { nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.header_ie, config->ack_ie.header_ie->length + IEEE802154_HEADER_IE_HEADER_LENGTH, @@ -919,9 +931,6 @@ static int nrf5_configure(const struct device *dev, config->ack_ie.header_ie->length + IEEE802154_HEADER_IE_HEADER_LENGTH, NRF_802154_ACK_DATA_IE); - } else { - nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE); - nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE); } } break; @@ -930,9 +939,9 @@ static int nrf5_configure(const struct device *dev, #if defined(CONFIG_NRF_802154_SER_HOST) net_time_t period_ns = nrf5_data.csl_period * NSEC_PER_TEN_SYMBOLS; - bool changed = (config->csl_rx_time - nrf5_data.csl_rx_time) % period_ns; + bool changed = (config->expected_rx_time - nrf5_data.csl_rx_time) % period_ns; - nrf5_data.csl_rx_time = config->csl_rx_time; + nrf5_data.csl_rx_time = config->expected_rx_time; if (changed) #endif /* CONFIG_NRF_802154_SER_HOST */ @@ -972,6 +981,11 @@ static int nrf5_configure(const struct device *dev, break; #endif /* CONFIG_IEEE802154_NRF5_MULTIPLE_CCA */ + case IEEE802154_CONFIG_RX_ON_WHEN_IDLE: + nrf_802154_rx_on_when_idle_set(config->rx_on_when_idle); + nrf5_data.rx_on_when_idle = config->rx_on_when_idle; + break; + default: return -EINVAL; } @@ -1046,22 +1060,16 @@ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi, void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) { - const struct device *dev = net_if_get_device(nrf5_data.iface); + const struct device *dev = nrf5_get_device(); #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) - if (id == DRX_SLOT_RX) { - __ASSERT_NO_MSG(nrf5_data.event_handler); -#if !defined(CONFIG_IEEE802154_CSL_DEBUG) - /* When CSL debug option is used we intentionally avoid notifying the higher layer - * about the finalization of a DRX slot, so that the radio stays in receive state - * for receiving "out of slot" frames. - * As a side effect, regular failure notifications would be reported with the - * incorrect ID. - */ - nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); -#endif - if (error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) { + if (id == DRX_SLOT_RX && error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) { + if (!nrf5_data.rx_on_when_idle) { + /* Transition to RxOff done automatically by the driver */ return; + } else if (nrf5_data.event_handler) { + /* Notify the higher layer to allow it to transition if needed */ + nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); } } #else @@ -1165,7 +1173,7 @@ void nrf_802154_energy_detected(const nrf_802154_energy_detected_t *result) energy_scan_done_cb_t callback = nrf5_data.energy_scan_done; nrf5_data.energy_scan_done = NULL; - callback(net_if_get_device(nrf5_data.iface), result->ed_dbm); + callback(nrf5_get_device(), result->ed_dbm); } } @@ -1175,7 +1183,7 @@ void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error) energy_scan_done_cb_t callback = nrf5_data.energy_scan_done; nrf5_data.energy_scan_done = NULL; - callback(net_if_get_device(nrf5_data.iface), SHRT_MAX); + callback(nrf5_get_device(), SHRT_MAX); } } diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index 9115fe0bdaee..b1c95548210e 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -97,6 +97,9 @@ struct nrf5_802154_data { uint8_t max_extra_cca_attempts; #endif + /* The TX power in dBm. */ + int8_t txpwr; + #if defined(CONFIG_NRF_802154_SER_HOST) && defined(CONFIG_IEEE802154_CSL_ENDPOINT) /* The last configured value of CSL period in units of 10 symbols. */ uint32_t csl_period; @@ -104,6 +107,9 @@ struct nrf5_802154_data { /* The last configured value of CSL phase time in nanoseconds. */ net_time_t csl_rx_time; #endif /* CONFIG_NRF_802154_SER_HOST && CONFIG_IEEE802154_CSL_ENDPOINT */ + + /* Indicates if RxOnWhenIdle mode is enabled. */ + bool rx_on_when_idle; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 51ce17693969..211a6f11041c 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -135,7 +135,7 @@ static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) * @brief Enable a riscv PLIC-specific interrupt line * * This routine enables a RISCV PLIC-specific interrupt line. - * riscv_plic_irq_enable is called by SOC_FAMILY_RISCV_PRIVILEGED + * riscv_plic_irq_enable is called by RISCV_PRIVILEGED * arch_irq_enable function to enable external interrupts for * IRQS level == 2, whenever CONFIG_RISCV_HAS_PLIC variable is set. * @@ -161,7 +161,7 @@ void riscv_plic_irq_enable(uint32_t irq) * @brief Disable a riscv PLIC-specific interrupt line * * This routine disables a RISCV PLIC-specific interrupt line. - * riscv_plic_irq_disable is called by SOC_FAMILY_RISCV_PRIVILEGED + * riscv_plic_irq_disable is called by RISCV_PRIVILEGED * arch_irq_disable function to disable external interrupts, for * IRQS level == 2, whenever CONFIG_RISCV_HAS_PLIC variable is set. * diff --git a/drivers/interrupt_controller/intc_swerv_pic.c b/drivers/interrupt_controller/intc_swerv_pic.c index 5c52ab49614d..96eb248d27c7 100644 --- a/drivers/interrupt_controller/intc_swerv_pic.c +++ b/drivers/interrupt_controller/intc_swerv_pic.c @@ -15,6 +15,7 @@ #include #include #include +#include #define SWERV_PIC_MAX_NUM CONFIG_NUM_IRQS #define SWERV_PIC_MAX_ID (SWERV_PIC_MAX_NUM + RISCV_MAX_GENERIC_IRQ) @@ -176,14 +177,14 @@ static int swerv_pic_init(const struct device *dev) __asm__ swerv_pic_writecsr(meicurpl, 0); /* Setup IRQ handler for SweRV PIC driver */ - IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, + IRQ_CONNECT(RISCV_IRQ_MEXT, 0, swerv_pic_irq_handler, NULL, 0); /* Enable IRQ for SweRV PIC driver */ - irq_enable(RISCV_MACHINE_EXT_IRQ); + irq_enable(RISCV_IRQ_MEXT); return 0; } diff --git a/drivers/interrupt_controller/intc_vexriscv_litex.c b/drivers/interrupt_controller/intc_vexriscv_litex.c index efec4d2478eb..2d5d2233ab2e 100644 --- a/drivers/interrupt_controller/intc_vexriscv_litex.c +++ b/drivers/interrupt_controller/intc_vexriscv_litex.c @@ -11,6 +11,7 @@ #include #include #include +#include #define IRQ_MASK DT_INST_REG_ADDR_BY_NAME(0, irq_mask) #define IRQ_PENDING DT_INST_REG_ADDR_BY_NAME(0, irq_pending) @@ -122,9 +123,9 @@ int arch_irq_is_enabled(unsigned int irq) static int vexriscv_litex_irq_init(const struct device *dev) { __asm__ volatile ("csrrs x0, mie, %0" - :: "r"(1 << RISCV_MACHINE_EXT_IRQ)); + :: "r"(1 << RISCV_IRQ_MEXT)); vexriscv_litex_irq_setie(1); - IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, 0, vexriscv_litex_irq_handler, + IRQ_CONNECT(RISCV_IRQ_MEXT, 0, vexriscv_litex_irq_handler, NULL, 0); return 0; diff --git a/drivers/mbox/mbox_andes_plic_sw.c b/drivers/mbox/mbox_andes_plic_sw.c index bc01da73a303..e2c287ae216c 100644 --- a/drivers/mbox/mbox_andes_plic_sw.c +++ b/drivers/mbox/mbox_andes_plic_sw.c @@ -199,11 +199,11 @@ static void andes_plic_sw_irq_handler(const struct device *dev) static int mbox_andes_init(const struct device *dev) { /* Setup IRQ handler for PLIC SW driver */ - IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 1, + IRQ_CONNECT(RISCV_IRQ_MSOFT, 1, andes_plic_sw_irq_handler, DEVICE_DT_INST_GET(0), 0); #ifndef CONFIG_SMP - irq_enable(RISCV_MACHINE_SOFT_IRQ); + irq_enable(RISCV_IRQ_MSOFT); #endif return 0; } diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index 863f839184e6..c23bdb185def 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -6,3 +6,5 @@ add_subdirectory_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb) add_subdirectory_ifdef(CONFIG_PIO_RPI_PICO pio_rpi_pico) add_subdirectory_ifdef(CONFIG_NXP_S32_EMIOS nxp_s32_emios) add_subdirectory_ifdef(CONFIG_TIMEAWARE_GPIO timeaware_gpio) +add_subdirectory_ifdef(CONFIG_DEVMUX devmux) +add_subdirectory_ifdef(CONFIG_NORDIC_VPR_LAUNCHER nordic_vpr_launcher) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 66d83fc693d1..3511b8b6fd43 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -10,5 +10,7 @@ source "drivers/misc/grove_lcd_rgb/Kconfig" source "drivers/misc/pio_rpi_pico/Kconfig" source "drivers/misc/nxp_s32_emios/Kconfig" source "drivers/misc/timeaware_gpio/Kconfig" +source "drivers/misc/devmux/Kconfig" +source "drivers/misc/nordic_vpr_launcher/Kconfig" endmenu diff --git a/drivers/misc/devmux/CMakeLists.txt b/drivers/misc/devmux/CMakeLists.txt new file mode 100644 index 000000000000..94f74ea57cea --- /dev/null +++ b/drivers/misc/devmux/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_syscall_header( + ${ZEPHYR_BASE}/include/zephyr/drivers/misc/devmux/devmux.h +) + +zephyr_library_sources(devmux.c) diff --git a/drivers/misc/devmux/Kconfig b/drivers/misc/devmux/Kconfig new file mode 100644 index 000000000000..4f848b4e06c9 --- /dev/null +++ b/drivers/misc/devmux/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +config DEVMUX + bool "Device Multiplexer (devmux) [EXPERIMENTAL]" + depends on DT_HAS_ZEPHYR_DEVMUX_ENABLED + depends on DEVICE_MUTABLE + select EXPERIMENTAL + help + Devmux is a pseudo-device that operates as a device switch. It allows + software to select the data, config, and api from a number of linked + devices. + +if DEVMUX + +config DEVMUX_INIT_PRIORITY + int "Devmux init priority" + default 51 + help + Init priority for the devmux driver. It must be + greater than the priority of the initially selected muxed device. + +endif diff --git a/drivers/misc/devmux/devmux.c b/drivers/misc/devmux/devmux.c new file mode 100644 index 000000000000..653236f903de --- /dev/null +++ b/drivers/misc/devmux/devmux.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_devmux + +#include +#include +#include +#include + +struct devmux_config { + const struct device **devs; + const size_t n_devs; +}; + +struct devmux_data { + struct k_spinlock lock; + size_t selected; +}; + +/* The number of devmux devices */ +#define N DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) + +static const struct device *devmux_devices[N]; +static const struct devmux_config *devmux_configs[N]; +static struct devmux_data *devmux_datas[N]; + +static bool devmux_device_is_valid(const struct device *dev) +{ + for (size_t i = 0; i < N; ++i) { + if (dev == devmux_devices[i]) { + return true; + } + } + + return false; +} + +static size_t devmux_inst_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return i; + } + } + + return SIZE_MAX; +} + +const struct devmux_config *devmux_config_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return devmux_configs[i]; + } + } + + return NULL; +} + +struct devmux_data *devmux_data_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return devmux_datas[i]; + } + } + + return NULL; +} + +ssize_t z_impl_devmux_select_get(const struct device *dev) +{ + ssize_t index; + struct devmux_data *const data = devmux_data_get(dev); + + if (!devmux_device_is_valid(dev)) { + return -EINVAL; + } + + K_SPINLOCK(&data->lock) + { + index = data->selected; + } + + return index; +} + +#ifdef CONFIG_USERSPACE +ssize_t z_vrfy_devmux_select_get(const struct device *dev) +{ + return z_impl_devmux_select_get(dev); +} +#include +#endif + +int z_impl_devmux_select_set(struct device *dev, size_t index) +{ + struct devmux_data *const data = devmux_data_get(dev); + const struct devmux_config *config = devmux_config_get(dev); + + if (!devmux_device_is_valid(dev) || index >= config->n_devs) { + return -EINVAL; + } + + if (!device_is_ready(config->devs[index])) { + return -ENODEV; + } + + K_SPINLOCK(&data->lock) + { + *dev = *config->devs[index]; + data->selected = index; + } + + return 0; +} + +#ifdef CONFIG_USERSPACE +int z_vrfy_devmux_select_set(struct device *dev, size_t index) +{ + return z_impl_devmux_select_set(dev, index); +} +#include +#endif + +static int devmux_init(struct device *const dev) +{ + size_t inst = devmux_inst_get(dev); + struct devmux_data *const data = dev->data; + const struct devmux_config *config = dev->config; + size_t sel = data->selected; + + devmux_configs[inst] = config; + devmux_datas[inst] = data; + + if (!device_is_ready(config->devs[sel])) { + return -ENODEV; + } + + *dev = *config->devs[sel]; + + 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, (,)) + +#define DEVMUX_SELECTED(_n) DT_INST_PROP(_n, selected) + +#define DEVMUX_DEFINE(_n) \ + BUILD_ASSERT(DT_INST_PROP_OR(_n, zephyr_mutable, 0), \ + "devmux nodes must contain the 'zephyr,mutable' property"); \ + BUILD_ASSERT(DT_INST_PROP_LEN(_n, devices) > 0, "devices array must have non-zero size"); \ + BUILD_ASSERT(DEVMUX_SELECTED(_n) >= 0, "selected must be > 0"); \ + BUILD_ASSERT(DEVMUX_SELECTED(_n) < DT_INST_PROP_LEN(_n, devices), \ + "selected must be within bounds of devices phandle array"); \ + static const struct device *demux_devs_##_n[] = {DEVMUX_PHANDLE_DEVICES(_n)}; \ + static const struct devmux_config devmux_config_##_n = { \ + .devs = demux_devs_##_n, \ + .n_devs = DT_INST_PROP_LEN(_n, devices), \ + }; \ + static struct devmux_data devmux_data_##_n = { \ + .selected = DEVMUX_SELECTED(_n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(_n, devmux_init, NULL, &devmux_data_##_n, &devmux_config_##_n, \ + PRE_KERNEL_1, CONFIG_DEVMUX_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(DEVMUX_DEFINE) + +#define DEVMUX_DEVICE_GET(_n) DEVICE_DT_INST_GET(_n), +static const struct device *devmux_devices[] = {DT_INST_FOREACH_STATUS_OKAY(DEVMUX_DEVICE_GET)}; diff --git a/drivers/misc/nordic_vpr_launcher/CMakeLists.txt b/drivers/misc/nordic_vpr_launcher/CMakeLists.txt new file mode 100644 index 000000000000..70c84e842175 --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(nordic_vpr_launcher.c) diff --git a/drivers/misc/nordic_vpr_launcher/Kconfig b/drivers/misc/nordic_vpr_launcher/Kconfig new file mode 100644 index 000000000000..57605e505f25 --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/Kconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config NORDIC_VPR_LAUNCHER + bool "Nordic VPR coprocessor launcher" + default y + depends on DT_HAS_NORDIC_NRF_VPR_COPROCESSOR_ENABLED + help + When enabled, the VPR coprocessors will be automatically launched + during system initialization. + +if NORDIC_VPR_LAUNCHER + +module = NORDIC_VPR_LAUNCHER +module-str = Nordic VPR Launcher +source "subsys/logging/Kconfig.template.log_config" + +config NORDIC_VPR_LAUNCHER_INIT_PRIORITY + int "Nordic VPR coprocessor launcher init priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + The init priority of the VPR coprocessor launcher. + +endif # NORDIC_VPR_LAUNCHER diff --git a/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c new file mode 100644 index 000000000000..161465ba02c9 --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_vpr_coprocessor + +#include + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(nordic_vpr_launcher, CONFIG_NORDIC_VPR_LAUNCHER_LOG_LEVEL); + +struct nordic_vpr_launcher_config { + NRF_VPR_Type *vpr; + uintptr_t exec_addr; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(source_memory) + uintptr_t src_addr; + size_t src_size; +#endif +}; + +static int nordic_vpr_launcher_init(const struct device *dev) +{ + const struct nordic_vpr_launcher_config *config = dev->config; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(source_memory) + if (config->src_size > 0U) { + LOG_DBG("Loading VPR (%p) from %p to %p (%zu bytes)", config->vpr, + (void *)config->src_addr, (void *)config->exec_addr, config->src_size); + memcpy((void *)config->exec_addr, (void *)config->src_addr, config->src_size); + } +#endif + + LOG_DBG("Launching VPR (%p) from %p", config->vpr, (void *)config->exec_addr); + nrf_vpr_initpc_set(config->vpr, config->exec_addr); + nrf_vpr_cpurun_set(config->vpr, true); + + return 0; +} + +/* obtain VPR source address either from memory or partition */ +#define VPR_SRC_ADDR(node_id) \ + (DT_REG_ADDR(node_id) + \ + COND_CODE_0(DT_FIXED_PARTITION_EXISTS(node_id), (0), (DT_REG_ADDR(DT_GPARENT(node_id))))) + +#define NORDIC_VPR_LAUNCHER_DEFINE(inst) \ + COND_CODE_1(DT_NODE_HAS_PROP(inst, source_memory), \ + (BUILD_ASSERT((DT_REG_SIZE(DT_INST_PHANDLE(inst, execution_memory)) == \ + DT_REG_SIZE(DT_INST_PHANDLE(inst, source_memory))), \ + "Source/execution memory sizes mismatch");), \ + ()) \ + \ + static const struct nordic_vpr_launcher_config config##inst = { \ + .vpr = (NRF_VPR_Type *)DT_INST_REG_ADDR(inst), \ + .exec_addr = DT_REG_ADDR(DT_INST_PHANDLE(inst, execution_memory)), \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, source_memory), \ + (.src_addr = VPR_SRC_ADDR(DT_INST_PHANDLE(inst, source_memory)), \ + .src_size = DT_REG_SIZE(DT_INST_PHANDLE(inst, source_memory)),), \ + ())}; \ + \ + DEVICE_DT_INST_DEFINE(inst, nordic_vpr_launcher_init, NULL, NULL, &config##inst, \ + POST_KERNEL, CONFIG_NORDIC_VPR_LAUNCHER_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(NORDIC_VPR_LAUNCHER_DEFINE) diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index c2ac538c93b9..12ee1d522941 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -13,19 +13,24 @@ BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) && (NRF_PULL_UP == NRF_GPIO_PIN_PULLUP)), "nRF pinctrl pull settings do not match HAL values"); -BUILD_ASSERT(((NRF_DRIVE_S0S1 == NRF_GPIO_PIN_S0S1) && - (NRF_DRIVE_H0S1 == NRF_GPIO_PIN_H0S1) && - (NRF_DRIVE_S0H1 == NRF_GPIO_PIN_S0H1) && - (NRF_DRIVE_H0H1 == NRF_GPIO_PIN_H0H1) && - (NRF_DRIVE_D0S1 == NRF_GPIO_PIN_D0S1) && - (NRF_DRIVE_D0H1 == NRF_GPIO_PIN_D0H1) && - (NRF_DRIVE_S0D1 == NRF_GPIO_PIN_S0D1) && - (NRF_DRIVE_H0D1 == NRF_GPIO_PIN_H0D1) && -#if defined(GPIO_PIN_CNF_DRIVE_E0E1) - (NRF_DRIVE_E0E1 == NRF_GPIO_PIN_E0E1) && -#endif /* defined(GPIO_PIN_CNF_DRIVE_E0E1) */ - (1U)), - "nRF pinctrl drive settings do not match HAL values"); +#if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0) +#define NRF_DRIVE_COUNT (NRF_DRIVE_E0E1 + 1) +#else +#define NRF_DRIVE_COUNT (NRF_DRIVE_H0D1 + 1) +#endif +static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { + [NRF_DRIVE_S0S1] = NRF_GPIO_PIN_S0S1, + [NRF_DRIVE_H0S1] = NRF_GPIO_PIN_H0S1, + [NRF_DRIVE_S0H1] = NRF_GPIO_PIN_S0H1, + [NRF_DRIVE_H0H1] = NRF_GPIO_PIN_H0H1, + [NRF_DRIVE_D0S1] = NRF_GPIO_PIN_D0S1, + [NRF_DRIVE_D0H1] = NRF_GPIO_PIN_D0H1, + [NRF_DRIVE_S0D1] = NRF_GPIO_PIN_S0D1, + [NRF_DRIVE_H0D1] = NRF_GPIO_PIN_H0D1, +#if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0) + [NRF_DRIVE_E0E1] = NRF_GPIO_PIN_E0E1, +#endif +}; /* value to indicate pin level doesn't need initialization */ #define NO_WRITE UINT32_MAX @@ -86,12 +91,19 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { for (uint8_t i = 0U; i < pin_cnt; i++) { - nrf_gpio_pin_drive_t drive = NRF_GET_DRIVE(pins[i]); + nrf_gpio_pin_drive_t drive; + uint8_t drive_idx = NRF_GET_DRIVE(pins[i]); uint32_t psel = NRF_GET_PIN(pins[i]); uint32_t write = NO_WRITE; nrf_gpio_pin_dir_t dir; nrf_gpio_pin_input_t input; + if (drive_idx < ARRAY_SIZE(drive_modes)) { + drive = drive_modes[drive_idx]; + } else { + return -EINVAL; + } + if (psel == NRF_PIN_DISCONNECTED) { psel = PSEL_DISCONNECTED; } @@ -165,22 +177,22 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, #if defined(NRF_PSEL_TWIM) case NRF_FUN_TWIM_SCL: NRF_PSEL_TWIM(reg, SCL) = psel; - if (drive == NRF_DRIVE_S0S1) { + if (drive == NRF_GPIO_PIN_S0S1) { /* Override the default drive setting with one * suitable for TWI/TWIM peripherals (S0D1). * This drive cannot be used always so that * users are able to select e.g. H0D1 or E0E1 * in devicetree. */ - drive = NRF_DRIVE_S0D1; + drive = NRF_GPIO_PIN_S0D1; } dir = NRF_GPIO_PIN_DIR_INPUT; input = NRF_GPIO_PIN_INPUT_CONNECT; break; case NRF_FUN_TWIM_SDA: NRF_PSEL_TWIM(reg, SDA) = psel; - if (drive == NRF_DRIVE_S0S1) { - drive = NRF_DRIVE_S0D1; + if (drive == NRF_GPIO_PIN_S0S1) { + drive = NRF_GPIO_PIN_S0D1; } dir = NRF_GPIO_PIN_DIR_INPUT; input = NRF_GPIO_PIN_INPUT_CONNECT; diff --git a/drivers/pwm/pwm_nrf_sw.c b/drivers/pwm/pwm_nrf_sw.c index f367bb59899f..2b9a22a38f08 100644 --- a/drivers/pwm/pwm_nrf_sw.c +++ b/drivers/pwm/pwm_nrf_sw.c @@ -62,6 +62,7 @@ struct pwm_config { NRF_RTC_Type *rtc; NRF_TIMER_Type *timer; }; + nrfx_gpiote_t gpiote[PWM_0_MAP_SIZE]; uint8_t psel_ch[PWM_0_MAP_SIZE]; uint8_t initially_inverted; uint8_t map_size; @@ -123,6 +124,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, const struct pwm_config *config = dev->config; NRF_TIMER_Type *timer = pwm_config_timer(config); NRF_RTC_Type *rtc = pwm_config_rtc(config); + NRF_GPIOTE_Type *gpiote; struct pwm_data *data = dev->data; uint32_t ppi_mask; uint8_t active_level; @@ -161,6 +163,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, } } + gpiote = config->gpiote[channel].p_reg; psel_ch = config->psel_ch[channel]; gpiote_ch = data->gpiote_ch[channel]; ppi_chs = data->ppi_ch[channel]; @@ -186,7 +189,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, : active_level); /* clear GPIOTE config */ - nrf_gpiote_te_default(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_te_default(gpiote, gpiote_ch); /* No PWM generation for this channel. */ data->pulse_cycles[channel] = 0U; @@ -235,7 +238,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, } /* Configure GPIOTE - toggle task with proper initial output value. */ - NRF_GPIOTE->CONFIG[gpiote_ch] = + gpiote->CONFIG[gpiote_ch] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | ((uint32_t)psel_ch << 8) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | @@ -256,9 +259,9 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, pulse_end_task = period_end_task = nrf_gpiote_out_task_get(gpiote_ch); #endif uint32_t pulse_end_task_address = - nrf_gpiote_task_address_get(NRF_GPIOTE, pulse_end_task); + nrf_gpiote_task_address_get(gpiote, pulse_end_task); uint32_t period_end_task_address = - nrf_gpiote_task_address_get(NRF_GPIOTE, period_end_task); + nrf_gpiote_task_address_get(gpiote, period_end_task); if (USE_RTC) { uint32_t clear_task_address = @@ -359,7 +362,8 @@ static int pwm_nrf_sw_init(const struct device *dev) } } - err = nrfx_gpiote_channel_alloc(&data->gpiote_ch[i]); + err = nrfx_gpiote_channel_alloc(&config->gpiote[i], + &data->gpiote_ch[i]); if (err != NRFX_SUCCESS) { /* Do not free allocated resource. It is a fatal condition, * system requires reconfiguration. @@ -402,8 +406,14 @@ static int pwm_nrf_sw_init(const struct device *dev) ((DT_GPIO_FLAGS_BY_IDX(_node_id, _prop, _idx) & GPIO_ACTIVE_LOW) \ ? BIT(_idx) : 0) | +#define GPIOTE_AND_COMMA(_node_id, _prop, _idx) \ + NRFX_GPIOTE_INSTANCE(NRF_DT_GPIOTE_INST_BY_IDX(_node_id, _prop, _idx)), + static const struct pwm_config pwm_nrf_sw_0_config = { COND_CODE_1(USE_RTC, (.rtc), (.timer)) = GENERATOR_ADDR, + .gpiote = { + DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, GPIOTE_AND_COMMA) + }, .psel_ch = { DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, PSEL_AND_COMMA) }, diff --git a/drivers/regulator/regulator_common.c b/drivers/regulator/regulator_common.c index 7f33040d2d91..14866a3738f2 100644 --- a/drivers/regulator/regulator_common.c +++ b/drivers/regulator/regulator_common.c @@ -107,10 +107,13 @@ int regulator_enable(const struct device *dev) (void)k_mutex_lock(&data->lock, K_FOREVER); #endif - if (data->refcnt == 0) { + data->refcnt++; + + if (data->refcnt == 1) { ret = api->enable(dev); - if (ret == 0) { - data->refcnt++; + if (ret < 0) { + data->refcnt--; + } else { regulator_delay(config->off_on_delay_us); } } diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c index f63b8f73a321..1d5c31ad0210 100644 --- a/drivers/sensor/adxl367/adxl367.c +++ b/drivers/sensor/adxl367/adxl367.c @@ -287,16 +287,22 @@ int adxl367_self_test(const struct device *dev) switch (cfg->odr) { case ADXL367_ODR_12P5HZ: st_delay_ms = 320; + break; case ADXL367_ODR_25HZ: st_delay_ms = 160; + break; case ADXL367_ODR_50HZ: st_delay_ms = 80; + break; case ADXL367_ODR_100HZ: st_delay_ms = 40; + break; case ADXL367_ODR_200HZ: st_delay_ms = 20; + break; case ADXL367_ODR_400HZ: st_delay_ms = 10; + break; default: return -EINVAL; } diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index bfc386038642..67e02e0c2614 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -26,7 +26,13 @@ zephyr_library_sources_ifdef(CONFIG_UART_MIV uart_miv.c) zephyr_library_sources_ifdef(CONFIG_UART_MSP432P4XX uart_msp432p4xx.c) zephyr_library_sources_ifdef(CONFIG_UART_NS16550 uart_ns16550.c) zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UART uart_nrfx_uart.c) -zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UARTE uart_nrfx_uarte.c) +if (CONFIG_UART_NRFX_UARTE) + if (CONFIG_UART_NRFX_UARTE_LEGACY_SHIM) + zephyr_library_sources(uart_nrfx_uarte.c) + else() + zephyr_library_sources(uart_nrfx_uarte2.c) + endif() +endif() zephyr_library_sources_ifdef(CONFIG_UART_NUMICRO uart_numicro.c) zephyr_library_sources_ifdef(CONFIG_UART_SAM uart_sam.c) zephyr_library_sources_ifdef(CONFIG_USART_SAM usart_sam.c) @@ -93,3 +99,4 @@ endif() 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) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 5eb183c9a3e2..2d097932cf48 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -133,6 +133,21 @@ config UART_ASYNC_RX_HELPER is delayed. Module implements zero-copy approach with multiple reception buffers. +config UART_ASYNC_TO_INT_DRIVEN_API + bool + select UART_ASYNC_RX_HELPER + help + Asynchronous to Interrupt driven adaptation layer. When enabled device + which implements only asynchronous API can be used with interrupt driven + API implemented by the generic adaptation layer. + +config UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT + int "Receiver timeout (in bauds)" + depends on UART_ASYNC_TO_INT_DRIVEN_API + default 100 + help + Receiver inactivity timeout. It is used to calculate timeout in microseconds. + comment "Serial Drivers" source "drivers/serial/Kconfig.b91" diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 53553e3d06ed..158731404e63 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -25,11 +25,20 @@ config UART_NRFX_UART config UART_NRFX_UARTE def_bool y depends on DT_HAS_NORDIC_NRF_UARTE_ENABLED + imply NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM + imply NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM + +config UART_NRFX_UARTE_LEGACY_SHIM + bool "Legacy UARTE shim" + depends on UART_NRFX_UARTE + depends on !SOC_SERIES_NRF54LX && !SOC_SERIES_NRF54HX + # New shim takes more ROM. Until it is fixed use legacy shim. + default y config UART_ASYNC_TX_CACHE_SIZE int "TX cache buffer size" depends on UART_ASYNC_API - depends on UART_NRFX_UARTE + depends on UART_NRFX_UARTE_LEGACY_SHIM default 8 help For UARTE, TX cache buffer is used when provided TX buffer is not located @@ -56,6 +65,76 @@ nrfx_uart_num = 3 rsource "Kconfig.nrfx_uart_instance" endif +if HAS_HW_NRF_UARTE00 +nrfx_uart_num = 00 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE20 +nrfx_uart_num = 20 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE21 +nrfx_uart_num = 21 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE22 +nrfx_uart_num = 22 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE30 +nrfx_uart_num = 30 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE120 +nrfx_uart_num = 120 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE130 +nrfx_uart_num = 130 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE131 +nrfx_uart_num = 131 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE132 +nrfx_uart_num = 132 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE133 +nrfx_uart_num = 133 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE134 +nrfx_uart_num = 134 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE135 +nrfx_uart_num = 135 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE136 +nrfx_uart_num = 136 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE137 +nrfx_uart_num = 137 +rsource "Kconfig.nrfx_uart_instance" +endif + config NRFX_TIMER0 default y depends on UART_0_NRF_HW_ASYNC_TIMER = 0 \ diff --git a/drivers/serial/Kconfig.nrfx_uart_instance b/drivers/serial/Kconfig.nrfx_uart_instance index 39e774e25444..9e992ca9737a 100644 --- a/drivers/serial/Kconfig.nrfx_uart_instance +++ b/drivers/serial/Kconfig.nrfx_uart_instance @@ -6,6 +6,7 @@ config UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN bool "Interrupt support on port $(nrfx_uart_num)" depends on UART_INTERRUPT_DRIVEN + select UART_ASYNC_TO_INT_DRIVEN_API if !UART_NRFX_UARTE_LEGACY_SHIM default y help This option enables UART interrupt support on port $(nrfx_uart_num). @@ -19,14 +20,19 @@ 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 !SOC_SERIES_NRF54LX default y depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC select NRFX_PPI if HAS_HW_NRF_PPI select NRFX_DPPI if HAS_HW_NRF_DPPIC help When enabled, polling out does not trigger interrupt which stops TX. Feature uses a PPI channel. +config NRFX_UARTE$(nrfx_uart_num) + def_bool y if HAS_HW_NRF_UARTE$(nrfx_uart_num) && !UART_NRFX_UARTE_LEGACY_SHIM + config UART_$(nrfx_uart_num)_NRF_PARITY_BIT bool "Parity bit" help @@ -34,7 +40,8 @@ config UART_$(nrfx_uart_num)_NRF_PARITY_BIT config UART_$(nrfx_uart_num)_NRF_TX_BUFFER_SIZE int "Size of RAM buffer" - depends on UART_INTERRUPT_DRIVEN + depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on UART_NRFX_UARTE_LEGACY_SHIM range 1 65535 default 32 help @@ -46,6 +53,7 @@ config UART_$(nrfx_uart_num)_NRF_HW_ASYNC bool "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 select NRFX_PPI if HAS_HW_NRF_PPI select NRFX_DPPI if HAS_HW_NRF_DPPIC help @@ -58,6 +66,7 @@ config UART_$(nrfx_uart_num)_NRF_ASYNC_LOW_POWER bool "Low power mode" depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) depends on UART_ASYNC_API + depends on UART_NRFX_UARTE_LEGACY_SHIM help When enabled, UARTE is enabled before each TX or RX usage and disabled when not used. Disabling UARTE while in idle allows to achieve lowest @@ -67,6 +76,42 @@ config UART_$(nrfx_uart_num)_NRF_HW_ASYNC_TIMER int "Timer instance" depends on UART_$(nrfx_uart_num)_NRF_HW_ASYNC +config UART_$(nrfx_uart_num)_TX_CACHE_SIZE + int "TX cache buffer size" + depends on !UART_NRFX_UARTE_LEGACY_SHIM + default 8 + help + For UARTE, TX cache buffer is used when provided TX buffer is not located + in memory which can be used by the EasyDMA. + +config UART_$(nrfx_uart_num)_RX_CACHE_SIZE + int "RX cache buffer size" + depends on !UART_NRFX_UARTE_LEGACY_SHIM + default 32 if $(dt_nodelabel_has_compat,ram3x,$(DT_COMPAT_MMIO_SRAM)) + default 5 + range 5 255 + help + For UARTE, RX cache buffer is used when provided RX buffer is not located + in memory which can be used by the EasyDMA. It is also used to store + flushed data. + +config UART_$(nrfx_uart_num)_A2I_RX_SIZE + depends on !UART_NRFX_UARTE_LEGACY_SHIM + int "Asynchronous to interrupt driven adaptation layer RX buffer size" + default 64 if UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + default 0 + help + Amount of space dedicated for RX. It is divided into chunks with some + amount of that space used for control data. + +config UART_$(nrfx_uart_num)_A2I_RX_BUF_COUNT + depends on !UART_NRFX_UARTE_LEGACY_SHIM + int "Asynchronous to interrupt driven adaptation layer RX buffer count" + default 8 if UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + default 0 + help + Number of chunks into RX space is divided. + config UART_$(nrfx_uart_num)_GPIO_MANAGEMENT bool "GPIO management on port $(nrfx_uart_num)" depends on PM_DEVICE diff --git a/drivers/serial/uart_async_to_irq.c b/drivers/serial/uart_async_to_irq.c new file mode 100644 index 000000000000..209e8d4f2053 --- /dev/null +++ b/drivers/serial/uart_async_to_irq.c @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +LOG_MODULE_REGISTER(UART_ASYNC_TO_IRQ_LOG_NAME, CONFIG_UART_LOG_LEVEL); + +/* Internal state flags. */ + +/* RX interrupt enabled. */ +#define A2I_RX_IRQ_ENABLED BIT(0) + +/* TX interrupt enabled. */ +#define A2I_TX_IRQ_ENABLED BIT(1) + +/* Error interrupt enabled. */ +#define A2I_ERR_IRQ_ENABLED BIT(2) + +/* Receiver to be kept enabled. */ +#define A2I_RX_ENABLE BIT(3) + +/* TX busy. */ +#define A2I_TX_BUSY BIT(4) + +static struct uart_async_to_irq_data *get_data(const struct device *dev) +{ + struct uart_async_to_irq_data **data = dev->data; + + return *data; +} + +static const struct uart_async_to_irq_config *get_config(const struct device *dev) +{ + const struct uart_async_to_irq_config * const *config = dev->config; + + return *config; +} + +/* Function calculates RX timeout based on baudrate. */ +static uint32_t get_rx_timeout(const struct device *dev) +{ + struct uart_config cfg; + int err; + uint32_t baudrate; + + err = uart_config_get(dev, &cfg); + if (err == 0) { + baudrate = cfg.baudrate; + } else { + baudrate = get_config(dev)->baudrate; + } + + uint32_t us = (CONFIG_UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT * 1000000) / baudrate; + + return us; +} + +static int rx_enable(const struct device *dev, + struct uart_async_to_irq_data *data, + uint8_t *buf, + size_t len) +{ + int err; + const struct uart_async_to_irq_config *config = get_config(dev); + + err = config->api->rx_enable(dev, buf, len, get_rx_timeout(dev)); + + return err; +} + +static int try_rx_enable(const struct device *dev, struct uart_async_to_irq_data *data) +{ + uint8_t *buf = uart_async_rx_buf_req(&data->rx.async_rx); + size_t len = uart_async_rx_get_buf_len(&data->rx.async_rx); + + if (buf == NULL) { + return -EBUSY; + } + + return rx_enable(dev, data, buf, len); +} + +static void on_rx_buf_req(const struct device *dev, + const struct uart_async_to_irq_config *config, + struct uart_async_to_irq_data *data) +{ + struct uart_async_rx *async_rx = &data->rx.async_rx; + uint8_t *buf = uart_async_rx_buf_req(async_rx); + size_t len = uart_async_rx_get_buf_len(async_rx); + + if (buf) { + int err = config->api->rx_buf_rsp(dev, buf, len); + + if (err < 0) { + uart_async_rx_on_buf_rel(async_rx, buf); + } + } else { + atomic_inc(&data->rx.pending_buf_req); + } +} + +static void on_rx_dis(const struct device *dev, struct uart_async_to_irq_data *data) +{ + if (data->flags & A2I_RX_ENABLE) { + data->rx.pending_buf_req = 0; + + int err = try_rx_enable(dev, data); + + LOG_INST_DBG(get_config(dev)->log, "Reenabling RX from RX_DISABLED (err:%d)", err); + __ASSERT_NO_MSG(err >= 0); + return; + } + + k_sem_give(&data->rx.sem); +} + +static void uart_async_to_irq_callback(const struct device *dev, + struct uart_event *evt, + void *user_data) +{ + struct uart_async_to_irq_data *data = (struct uart_async_to_irq_data *)user_data; + const struct uart_async_to_irq_config *config = get_config(dev); + bool call_handler = false; + + switch (evt->type) { + case UART_TX_DONE: + atomic_and(&data->flags, ~A2I_TX_BUSY); + call_handler = data->flags & A2I_TX_IRQ_ENABLED; + break; + case UART_RX_RDY: + uart_async_rx_on_rdy(&data->rx.async_rx, evt->data.rx.buf, evt->data.rx.len); + call_handler = data->flags & A2I_RX_IRQ_ENABLED; + break; + case UART_RX_BUF_REQUEST: + on_rx_buf_req(dev, config, data); + break; + case UART_RX_BUF_RELEASED: + uart_async_rx_on_buf_rel(&data->rx.async_rx, evt->data.rx_buf.buf); + break; + case UART_RX_STOPPED: + call_handler = data->flags & A2I_ERR_IRQ_ENABLED; + break; + case UART_RX_DISABLED: + on_rx_dis(dev, data); + break; + default: + break; + } + + if (data->callback && call_handler) { + atomic_inc(&data->irq_req); + config->trampoline(dev); + } +} + +int z_uart_async_to_irq_fifo_fill(const struct device *dev, const uint8_t *buf, int len) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + len = MIN(len, data->tx.len); + if (atomic_or(&data->flags, A2I_TX_BUSY) & A2I_TX_BUSY) { + return 0; + } + + memcpy(data->tx.buf, buf, len); + + err = config->api->tx(dev, data->tx.buf, len, SYS_FOREVER_US); + if (err < 0) { + atomic_and(&data->flags, ~A2I_TX_BUSY); + return 0; + } + + return len; +} + +/** Interrupt driven FIFO read function */ +int z_uart_async_to_irq_fifo_read(const struct device *dev, + uint8_t *buf, + const int len) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + struct uart_async_rx *async_rx = &data->rx.async_rx; + size_t claim_len; + uint8_t *claim_buf; + + claim_len = uart_async_rx_data_claim(async_rx, &claim_buf, len); + if (claim_len == 0) { + return 0; + } + + memcpy(buf, claim_buf, claim_len); + uart_async_rx_data_consume(async_rx, claim_len); + + if (data->rx.pending_buf_req) { + buf = uart_async_rx_buf_req(async_rx); + if (buf) { + int err; + size_t rx_len = uart_async_rx_get_buf_len(async_rx); + + atomic_dec(&data->rx.pending_buf_req); + err = config->api->rx_buf_rsp(dev, buf, rx_len); + if (err < 0) { + if (err == -EACCES) { + data->rx.pending_buf_req = 0; + err = rx_enable(dev, data, buf, rx_len); + } + if (err < 0) { + return err; + } + } + } + } + + return (int)claim_len; +} + +static void dir_disable(const struct device *dev, uint32_t flag) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + atomic_and(&data->flags, ~flag); +} + +static void dir_enable(const struct device *dev, uint32_t flag) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + atomic_or(&data->flags, flag); + + atomic_inc(&data->irq_req); + get_config(dev)->trampoline(dev); +} + +/** Interrupt driven transfer enabling function */ +void z_uart_async_to_irq_irq_tx_enable(const struct device *dev) +{ + dir_enable(dev, A2I_TX_IRQ_ENABLED); +} + +/** Interrupt driven transfer disabling function */ +void z_uart_async_to_irq_irq_tx_disable(const struct device *dev) +{ + dir_disable(dev, A2I_TX_IRQ_ENABLED); +} + +/** Interrupt driven transfer ready function */ +int z_uart_async_to_irq_irq_tx_ready(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + return (data->flags & A2I_TX_IRQ_ENABLED) && !(data->flags & A2I_TX_BUSY); +} + +/** Interrupt driven receiver enabling function */ +void z_uart_async_to_irq_irq_rx_enable(const struct device *dev) +{ + dir_enable(dev, A2I_RX_IRQ_ENABLED); +} + +/** Interrupt driven receiver disabling function */ +void z_uart_async_to_irq_irq_rx_disable(const struct device *dev) +{ + dir_disable(dev, A2I_RX_IRQ_ENABLED); +} + +/** Interrupt driven transfer complete function */ +int z_uart_async_to_irq_irq_tx_complete(const struct device *dev) +{ + return z_uart_async_to_irq_irq_tx_ready(dev); +} + +/** Interrupt driven receiver ready function */ +int z_uart_async_to_irq_irq_rx_ready(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + return (data->flags & A2I_RX_IRQ_ENABLED) && (data->rx.async_rx.pending_bytes > 0); +} + +/** Interrupt driven error enabling function */ +void z_uart_async_to_irq_irq_err_enable(const struct device *dev) +{ + dir_enable(dev, A2I_ERR_IRQ_ENABLED); +} + +/** Interrupt driven error disabling function */ +void z_uart_async_to_irq_irq_err_disable(const struct device *dev) +{ + dir_disable(dev, A2I_ERR_IRQ_ENABLED); +} + +/** Interrupt driven pending status function */ +int z_uart_async_to_irq_irq_is_pending(const struct device *dev) +{ + return z_uart_async_to_irq_irq_tx_ready(dev) || z_uart_async_to_irq_irq_rx_ready(dev); +} + +/** Interrupt driven interrupt update function */ +int z_uart_async_to_irq_irq_update(const struct device *dev) +{ + return 1; +} + +/** Set the irq callback function */ +void z_uart_async_to_irq_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + data->callback = cb; + data->user_data = user_data; +} + +int uart_async_to_irq_rx_enable(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + err = config->api->callback_set(dev, uart_async_to_irq_callback, data); + if (err < 0) { + return err; + } + + uart_async_rx_reset(&data->rx.async_rx); + + err = try_rx_enable(dev, data); + if (err == 0) { + atomic_or(&data->flags, A2I_RX_ENABLE); + } + + return err; +} + +int uart_async_to_irq_rx_disable(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + if (atomic_and(&data->flags, ~A2I_RX_ENABLE) & A2I_RX_ENABLE) { + err = config->api->rx_disable(dev); + if (err < 0) { + return err; + } + k_sem_take(&data->rx.sem, K_FOREVER); + } + + return 0; +} + +void uart_async_to_irq_trampoline_cb(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + do { + data->callback(dev, data->user_data); + } while (atomic_dec(&data->irq_req) > 1); +} + +int uart_async_to_irq_init(struct uart_async_to_irq_data *data, + const struct uart_async_to_irq_config *config) +{ + data->tx.buf = config->tx_buf; + data->tx.len = config->tx_len; + + k_sem_init(&data->rx.sem, 0, 1); + + return uart_async_rx_init(&data->rx.async_rx, &config->async_rx); +} diff --git a/drivers/serial/uart_b91.c b/drivers/serial/uart_b91.c index cb2d7ebd1904..e2502f4fd9b0 100644 --- a/drivers/serial/uart_b91.c +++ b/drivers/serial/uart_b91.c @@ -11,6 +11,7 @@ #include #include #include +#include /* Driver dts compatibility: telink,b91_uart */ diff --git a/drivers/serial/uart_nrfx_uarte2.c b/drivers/serial/uart_nrfx_uarte2.c new file mode 100644 index 000000000000..bfc770f1399f --- /dev/null +++ b/drivers/serial/uart_nrfx_uarte2.c @@ -0,0 +1,1029 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Nordic Semiconductor nRF UARTE + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define LOG_MODULE_NAME uarte +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_UART_LOG_LEVEL); + +#define INSTANCE_INT_DRIVEN(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_INTERRUPT_DRIVEN) + +#define INSTANCE_ASYNC(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ASYNC) + +#define INSTANCE_POLLING(periph, prefix, id, _) \ + UTIL_AND(CONFIG_HAS_HW_NRF_UARTE##prefix##id, \ + UTIL_AND(COND_CODE_1(CONFIG_UART_##prefix##id##_INTERRUPT_DRIVEN, (0), (1)), \ + COND_CODE_1(CONFIG_UART_##prefix##id##_ASYNC, (0), (1)))) + +#define INSTANCE_ENHANCED_POLL_OUT(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ENHANCED_POLL_OUT) + +/* Macro determining if any instance is using interrupt driven API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_INT_DRIVEN, (+), (0), _)) +#define UARTE_ANY_INTERRUPT_DRIVEN 1 +#else +#define UARTE_ANY_INTERRUPT_DRIVEN 0 +#endif + +/* Macro determining if any instance is enabled and using ASYNC API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_ASYNC, (+), (0), _)) +#define UARTE_ANY_ASYNC 1 +#else +#define UARTE_ANY_ASYNC 0 +#endif + +/* Macro determining if any instance is using only polling API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_POLLING, (+), (0), _)) +#define UARTE_ANY_POLLING 1 +#else +#define UARTE_ANY_POLLING 0 +#endif + +/* Macro determining if any instance is using interrupt driven API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_ENHANCED_POLL_OUT, (+), (0), _)) +#define UARTE_ENHANCED_POLL_OUT 1 +#else +#define UARTE_ENHANCED_POLL_OUT 0 +#endif + +#if UARTE_ANY_INTERRUPT_DRIVEN || UARTE_ANY_ASYNC +#define UARTE_INT_ASYNC 1 +#else +#define UARTE_INT_ASYNC 0 +#endif + +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) +#define UARTE_ODD_PARITY_ALLOWED 1 +#else +#define UARTE_ODD_PARITY_ALLOWED 0 +#endif + +/* + * RX timeout is divided into time slabs, this define tells how many divisions + * should be made. More divisions - higher timeout accuracy and processor usage. + */ +#define RX_TIMEOUT_DIV 5 + +/* 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. + */ +#define NRF_BAUDRATE(baudrate) ((baudrate) == 300 ? 0x00014000 :\ + (baudrate) == 600 ? 0x00027000 : \ + (baudrate) == 1200 ? NRF_UARTE_BAUDRATE_1200 : \ + (baudrate) == 2400 ? NRF_UARTE_BAUDRATE_2400 : \ + (baudrate) == 4800 ? NRF_UARTE_BAUDRATE_4800 : \ + (baudrate) == 9600 ? NRF_UARTE_BAUDRATE_9600 : \ + (baudrate) == 14400 ? NRF_UARTE_BAUDRATE_14400 : \ + (baudrate) == 19200 ? NRF_UARTE_BAUDRATE_19200 : \ + (baudrate) == 28800 ? NRF_UARTE_BAUDRATE_28800 : \ + (baudrate) == 31250 ? NRF_UARTE_BAUDRATE_31250 : \ + (baudrate) == 38400 ? NRF_UARTE_BAUDRATE_38400 : \ + (baudrate) == 56000 ? NRF_UARTE_BAUDRATE_56000 : \ + (baudrate) == 57600 ? NRF_UARTE_BAUDRATE_57600 : \ + (baudrate) == 76800 ? NRF_UARTE_BAUDRATE_76800 : \ + (baudrate) == 115200 ? NRF_UARTE_BAUDRATE_115200 : \ + (baudrate) == 230400 ? NRF_UARTE_BAUDRATE_230400 : \ + (baudrate) == 250000 ? NRF_UARTE_BAUDRATE_250000 : \ + (baudrate) == 460800 ? NRF_UARTE_BAUDRATE_460800 : \ + (baudrate) == 921600 ? NRF_UARTE_BAUDRATE_921600 : \ + (baudrate) == 1000000 ? NRF_UARTE_BAUDRATE_1000000 : 0) + +#define UARTE_DATA_FLAG_TRAMPOLINE BIT(0) +#define UARTE_DATA_FLAG_RX_ENABLED BIT(1) + +struct uarte_async_data { + uart_callback_t user_callback; + void *user_data; + + struct k_timer tx_timer; + struct k_timer rx_timer; + + k_timeout_t rx_timeout; + + /* Keeps the most recent error mask. */ + uint32_t err; + + uint8_t idle_cnt; +}; + +/* Device data structure */ +struct uarte_nrfx_data { + struct uart_async_to_irq_data *a2i_data; +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + struct uart_config uart_config; +#endif + struct uarte_async_data *async; + atomic_t flags; + uint8_t rx_byte; +}; +BUILD_ASSERT(offsetof(struct uarte_nrfx_data, a2i_data) == 0); + +/* If set then pins are managed when going to low power mode. */ +#define UARTE_CFG_FLAG_GPIO_MGMT BIT(0) + +/* If set then receiver is not used. */ +#define UARTE_CFG_FLAG_NO_RX BIT(1) + +/* If set then instance is using interrupt driven API. */ +#define UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API BIT(2) + +/** + * @brief Structure for UARTE configuration. + */ +struct uarte_nrfx_config { + const struct uart_async_to_irq_config *a2i_config; + nrfx_uarte_t nrfx_dev; + nrfx_uarte_config_t nrfx_config; + const struct pinctrl_dev_config *pcfg; + uint32_t flags; + + LOG_INSTANCE_PTR_DECLARE(log); +}; +BUILD_ASSERT(offsetof(struct uarte_nrfx_config, a2i_config) == 0); + +#define UARTE_ERROR_FROM_MASK(mask) \ + ((mask) & NRF_UARTE_ERROR_OVERRUN_MASK ? UART_ERROR_OVERRUN \ + : (mask) & NRF_UARTE_ERROR_PARITY_MASK ? UART_ERROR_PARITY \ + : (mask) & NRF_UARTE_ERROR_FRAMING_MASK ? UART_ERROR_FRAMING \ + : (mask) & NRF_UARTE_ERROR_BREAK_MASK ? UART_BREAK \ + : 0) + +/* Determine if the device has interrupt driven API enabled. */ +#define IS_INT_DRIVEN_API(dev) \ + (UARTE_ANY_INTERRUPT_DRIVEN && \ + (((const struct uarte_nrfx_config *)dev->config)->flags & \ + UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API)) + +/* Determine if the device supports only polling API. */ +#define IS_POLLING_API(dev) \ + (!UARTE_INT_ASYNC || (((struct uarte_nrfx_data *)dev->data)->async == NULL)) + +/* Determine if the device supports asynchronous API. */ +#define IS_ASYNC_API(dev) (!IS_INT_DRIVEN_API(dev) && !IS_POLLING_API(dev)) + +static inline const nrfx_uarte_t *get_nrfx_dev(const struct device *dev) +{ + const struct uarte_nrfx_config *config = dev->config; + + return &config->nrfx_dev; +} + +static int callback_set(const struct device *dev, uart_callback_t callback, void *user_data) +{ + struct uarte_nrfx_data *data = dev->data; + + data->async->user_callback = callback; + data->async->user_data = user_data; + + return 0; +} + +#if UARTE_ANY_ASYNC +static int api_callback_set(const struct device *dev, uart_callback_t callback, void *user_data) +{ + if (!IS_ASYNC_API(dev)) { + return -ENOTSUP; + } + + return callback_set(dev, callback, user_data); +} +#endif + +static void on_tx_done(const struct device *dev, const nrfx_uarte_event_t *event) +{ + struct uarte_nrfx_data *data = dev->data; + struct uart_event evt = { + .type = (event->data.tx.flags & NRFX_UARTE_TX_DONE_ABORTED) ? + UART_TX_ABORTED : UART_TX_DONE, + .data.tx.buf = event->data.tx.p_buffer, + .data.tx.len = event->data.tx.length + }; + bool hwfc; + +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + hwfc = data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS; +#else + const struct uarte_nrfx_config *config = dev->config; + + hwfc = config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED; +#endif + + if (hwfc) { + k_timer_stop(&data->async->tx_timer); + } + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void on_rx_done(const struct device *dev, const nrfx_uarte_event_t *event) +{ + struct uarte_nrfx_data *data = dev->data; + struct uart_event evt; + + if (event->data.rx.length) { + if (data->async->err) { + evt.type = UART_RX_STOPPED; + evt.data.rx_stop.reason = UARTE_ERROR_FROM_MASK(data->async->err); + evt.data.rx_stop.data.buf = event->data.rx.p_buffer; + evt.data.rx_stop.data.len = event->data.rx.length; + /* Keep error code for uart_err_check(). */ + if (!IS_INT_DRIVEN_API(dev)) { + data->async->err = 0; + } + } else { + evt.type = UART_RX_RDY, + evt.data.rx.buf = event->data.rx.p_buffer, + evt.data.rx.len = event->data.rx.length, + evt.data.rx.offset = 0; + } + data->async->user_callback(dev, &evt, data->async->user_data); + } + + evt.type = UART_RX_BUF_RELEASED; + evt.data.rx_buf.buf = event->data.rx.p_buffer; + + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void start_rx_timer(struct uarte_nrfx_data *data) +{ + struct uarte_async_data *adata = data->async; + + k_timer_start(&adata->rx_timer, adata->rx_timeout, K_NO_WAIT); +} + +static void on_rx_byte(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + nrfx_uarte_rxdrdy_disable(nrfx_dev); + adata->idle_cnt = RX_TIMEOUT_DIV; + start_rx_timer(data); +} + +static void on_rx_buf_req(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + struct uart_event evt = { + .type = UART_RX_BUF_REQUEST + }; + + /* If counter reached zero that indicates that timeout was reached and + * reception of one buffer was terminated to restart another transfer. + */ + if (!K_TIMEOUT_EQ(adata->rx_timeout, K_NO_WAIT)) { + /* Read and clear any pending new data information. */ + nrfx_uarte_rx_new_data_check(nrfx_dev); + nrfx_uarte_rxdrdy_enable(nrfx_dev); + } + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void on_rx_disabled(const struct device *dev, struct uarte_nrfx_data *data) +{ + struct uart_event evt = { + .type = UART_RX_DISABLED + }; + + atomic_and(&data->flags, ~UARTE_DATA_FLAG_RX_ENABLED); + k_timer_stop(&data->async->rx_timer); + + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void trigger_handler(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + + if (UARTE_ANY_INTERRUPT_DRIVEN && + atomic_and(&data->flags, ~UARTE_DATA_FLAG_TRAMPOLINE) & + UARTE_DATA_FLAG_TRAMPOLINE) { + uart_async_to_irq_trampoline_cb(dev); + } +} + +static void evt_handler(nrfx_uarte_event_t const *event, void *context) +{ + const struct device *dev = context; + struct uarte_nrfx_data *data = dev->data; + + switch (event->type) { + case NRFX_UARTE_EVT_TX_DONE: + on_tx_done(dev, event); + break; + case NRFX_UARTE_EVT_RX_DONE: + on_rx_done(dev, event); + break; + case NRFX_UARTE_EVT_RX_BYTE: + on_rx_byte(dev); + break; + case NRFX_UARTE_EVT_ERROR: + data->async->err = event->data.error.error_mask; + break; + case NRFX_UARTE_EVT_RX_BUF_REQUEST: + on_rx_buf_req(dev); + break; + case NRFX_UARTE_EVT_RX_DISABLED: + on_rx_disabled(dev, data); + break; + case NRFX_UARTE_EVT_RX_BUF_TOO_LATE: + /* No support */ + break; + case NRFX_UARTE_EVT_TRIGGER: + trigger_handler(dev); + break; + default: + __ASSERT_NO_MSG(0); + } +} + +static int api_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) +{ + struct uarte_nrfx_data *data = dev->data; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + bool hwfc; + +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + hwfc = data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS; +#else + const struct uarte_nrfx_config *config = dev->config; + + hwfc = config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED; +#endif + + err = nrfx_uarte_tx(nrfx_dev, buf, len, 0); + if (err != NRFX_SUCCESS) { + return (err == NRFX_ERROR_BUSY) ? -EBUSY : -EIO; + } + + if (hwfc && timeout != SYS_FOREVER_US) { + k_timer_start(&data->async->tx_timer, K_USEC(timeout), K_NO_WAIT); + } + + return 0; +} + +static int api_tx_abort(const struct device *dev) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + + err = nrfx_uarte_tx_abort(nrfx_dev, false); + return (err == NRFX_SUCCESS) ? 0 : -EFAULT; +} + +static void tx_timeout_handler(struct k_timer *timer) +{ + const struct device *dev = k_timer_user_data_get(timer); + + (void)api_tx_abort(dev); +} + +static void rx_timeout_handler(struct k_timer *timer) +{ + const struct device *dev = (const struct device *)k_timer_user_data_get(timer); + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + if (nrfx_uarte_rx_new_data_check(nrfx_dev)) { + adata->idle_cnt = RX_TIMEOUT_DIV - 1; + } else { + adata->idle_cnt--; + if (adata->idle_cnt == 0) { + (void)nrfx_uarte_rx_abort(nrfx_dev, false, false); + return; + } + } + + start_rx_timer(data); +} + +/* Determine if RX FIFO content shall be kept when device is being disabled. + * When flow-control is used then we expect to keep RX FIFO content since HWFC + * enforces lossless communication. However, when HWFC is not used (by any instance + * then RX FIFO handling feature is disabled in the nrfx_uarte to save space. + * It is based on assumption that without HWFC it is expected that some data may + * be lost and there are means to prevent that (keeping receiver always opened by + * provided reception buffers on time). + */ +static inline uint32_t get_keep_fifo_content_flag(const struct device *dev) +{ +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + struct uarte_nrfx_data *data = dev->data; + + if (data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS) { + return NRFX_UARTE_RX_ENABLE_KEEP_FIFO_CONTENT; + } +#else + const struct uarte_nrfx_config *config = dev->config; + + if (config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED) { + return NRFX_UARTE_RX_ENABLE_KEEP_FIFO_CONTENT; + } +#endif + + return 0; +} + +static int api_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) +{ + nrfx_err_t err; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + uint32_t flags = NRFX_UARTE_RX_ENABLE_CONT | + get_keep_fifo_content_flag(dev) | + (IS_ASYNC_API(dev) ? NRFX_UARTE_RX_ENABLE_STOP_ON_END : 0); + + if (cfg->flags & UARTE_CFG_FLAG_NO_RX) { + return -ENOTSUP; + } + + if (timeout != SYS_FOREVER_US) { + adata->idle_cnt = RX_TIMEOUT_DIV + 1; + adata->rx_timeout = K_USEC(timeout / RX_TIMEOUT_DIV); + } else { + adata->rx_timeout = K_NO_WAIT; + } + + err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len); + if (err != NRFX_SUCCESS) { + return -EIO; + } + + err = nrfx_uarte_rx_enable(nrfx_dev, flags); + if (err != NRFX_SUCCESS) { + return (err == NRFX_ERROR_BUSY) ? -EBUSY : -EIO; + } + + atomic_or(&data->flags, UARTE_DATA_FLAG_RX_ENABLED); + + return 0; +} + +static int api_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + struct uarte_nrfx_data *data = dev->data; + nrfx_err_t err; + + if (!(data->flags & UARTE_DATA_FLAG_RX_ENABLED)) { + return -EACCES; + } + + err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len); + switch (err) { + case NRFX_SUCCESS: + return 0; + case NRFX_ERROR_BUSY: + return -EBUSY; + default: + return -EIO; + } +} + +static int api_rx_disable(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + + k_timer_stop(&data->async->rx_timer); + + return (nrfx_uarte_rx_abort(get_nrfx_dev(dev), true, false) == NRFX_SUCCESS) ? 0 : -EFAULT; +} + +static int api_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uarte_nrfx_config *cfg = dev->config; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + nrfx_err_t err; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_fifo_read(dev, c, 1) == 0 ? -1 : 0; + } + + if (IS_ASYNC_API(dev)) { + return -EBUSY; + } + + err = nrfx_uarte_rx_ready(instance, NULL); + if (err == NRFX_SUCCESS) { + uint8_t *rx_byte = cfg->nrfx_config.rx_cache.p_buffer; + + *c = *rx_byte; + err = nrfx_uarte_rx_buffer_set(instance, rx_byte, 1); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + return 0; + } + + return -1; +} + +static void api_poll_out(const struct device *dev, unsigned char out_char) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + + do { + /* When runtime PM is used we cannot use early return because then + * we have no information when UART is actually done with the + * transmission. It reduces UART performance however, polling in + * general is not power efficient and should be avoided in low + * power applications. + */ + err = nrfx_uarte_tx(nrfx_dev, &out_char, 1, NRFX_UARTE_TX_EARLY_RETURN); + __ASSERT(err != NRFX_ERROR_INVALID_ADDR, "Invalid address of the buffer"); + + if (err == NRFX_ERROR_BUSY && + IS_ENABLED(CONFIG_MULTITHREADING) && k_is_preempt_thread()) { + k_msleep(1); + } + Z_SPIN_DELAY(3); + } while (err == NRFX_ERROR_BUSY); +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +/** + * @brief Set the baud rate + * + * This routine set the given baud rate for the UARTE. + * + * @param dev UARTE device struct + * @param baudrate Baud rate + * + * @return 0 on success or error code + */ +static int baudrate_set(NRF_UARTE_Type *uarte, uint32_t baudrate) +{ + nrf_uarte_baudrate_t nrf_baudrate = NRF_BAUDRATE(baudrate); + + if (baudrate == 0) { + return -EINVAL; + } + + nrfy_uarte_baudrate_set(uarte, nrf_baudrate); + + return 0; +} + +static int uarte_nrfx_configure(const struct device *dev, + const struct uart_config *cfg) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + struct uarte_nrfx_data *data = dev->data; + nrf_uarte_config_t uarte_cfg; + +#if defined(UARTE_CONFIG_STOP_Msk) + switch (cfg->stop_bits) { + case UART_CFG_STOP_BITS_1: + uarte_cfg.stop = NRF_UARTE_STOP_ONE; + break; + case UART_CFG_STOP_BITS_2: + uarte_cfg.stop = NRF_UARTE_STOP_TWO; + break; + default: + return -ENOTSUP; + } +#else + if (cfg->stop_bits != UART_CFG_STOP_BITS_1) { + return -ENOTSUP; + } +#endif + + if (cfg->data_bits != UART_CFG_DATA_BITS_8) { + return -ENOTSUP; + } + + switch (cfg->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + uarte_cfg.hwfc = NRF_UARTE_HWFC_DISABLED; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + uarte_cfg.hwfc = NRF_UARTE_HWFC_ENABLED; + break; + default: + return -ENOTSUP; + } + +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) + uarte_cfg.paritytype = NRF_UARTE_PARITYTYPE_EVEN; +#endif + switch (cfg->parity) { + case UART_CFG_PARITY_NONE: + uarte_cfg.parity = NRF_UARTE_PARITY_EXCLUDED; + break; + case UART_CFG_PARITY_EVEN: + uarte_cfg.parity = NRF_UARTE_PARITY_INCLUDED; + break; +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) + case UART_CFG_PARITY_ODD: + uarte_cfg.parity = NRF_UARTE_PARITY_INCLUDED; + uarte_cfg.paritytype = NRF_UARTE_PARITYTYPE_ODD; + break; +#endif + default: + return -ENOTSUP; + } + + if (baudrate_set(nrfx_dev->p_reg, cfg->baudrate) != 0) { + return -ENOTSUP; + } + + nrfy_uarte_configure(nrfx_dev->p_reg, &uarte_cfg); + + data->uart_config = *cfg; + + return 0; +} + +static int uarte_nrfx_config_get(const struct device *dev, + struct uart_config *cfg) +{ + struct uarte_nrfx_data *data = dev->data; + + *cfg = data->uart_config; + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#if UARTE_ANY_POLLING || UARTE_ANY_INTERRUPT_DRIVEN +static int api_err_check(const struct device *dev) +{ + if (IS_POLLING_API(dev)) { + const struct uarte_nrfx_config *cfg = dev->config; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + uint32_t mask = nrfx_uarte_errorsrc_get(instance); + + return mask; + } + + struct uarte_nrfx_data *data = dev->data; + uint32_t rv = data->async->err; + + data->async->err = 0; + + return rv; +} +#endif + +static const struct uart_async_to_irq_async_api a2i_api = { + .callback_set = 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, +}; + +static const struct uart_driver_api uart_nrfx_uarte_driver_api = { + .poll_in = api_poll_in, + .poll_out = api_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uarte_nrfx_configure, + .config_get = uarte_nrfx_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#if UARTE_ANY_POLLING || UARTE_ANY_INTERRUPT_DRIVEN + .err_check = api_err_check, +#endif +#if UARTE_ANY_ASYNC + .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 /* UARTE_ANY_ASYNC */ +#if UARTE_ANY_INTERRUPT_DRIVEN + UART_ASYNC_TO_IRQ_API_INIT(), +#endif /* UARTE_ANY_INTERRUPT_DRIVEN */ +}; + +static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte) +{ + nrfx_err_t ret; + uint8_t ch; + + ret = nrfx_gppi_channel_alloc(&ch); + if (ret != NRFX_SUCCESS) { + LOG_ERR("Failed to allocate PPI Channel"); + return -EIO; + } + + nrfx_gppi_channel_endpoints_setup(ch, + nrfy_uarte_event_address_get(uarte, NRF_UARTE_EVENT_ENDTX), + nrfy_uarte_task_address_get(uarte, NRF_UARTE_TASK_STOPTX)); + nrfx_gppi_channels_enable(BIT(ch)); + + return 0; +} + +static int start_rx(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_async_to_irq_rx_enable(dev); + } + + __ASSERT_NO_MSG(IS_POLLING_API(dev)); + + nrfx_err_t err; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + uint8_t *rx_byte = cfg->nrfx_config.rx_cache.p_buffer; + + err = nrfx_uarte_rx_buffer_set(instance, rx_byte, 1); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + err = nrfx_uarte_rx_enable(instance, 0); + __ASSERT_NO_MSG(err == NRFX_SUCCESS || err == NRFX_ERROR_BUSY); + + (void)err; + + return 0; +} + +static void async_to_irq_trampoline(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + uint32_t prev = atomic_or(&data->flags, UARTE_DATA_FLAG_TRAMPOLINE); + + if (!(prev & UARTE_DATA_FLAG_TRAMPOLINE)) { + nrfx_uarte_int_trigger(&cfg->nrfx_dev); + } +} + +static int uarte_nrfx_init(const struct device *dev) +{ + int err; + nrfx_err_t nerr; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + + err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + if (UARTE_ENHANCED_POLL_OUT && cfg->nrfx_config.tx_stop_on_end) { + err = endtx_stoptx_ppi_init(nrfx_dev->p_reg); + if (err < 0) { + return err; + } + } + + if (UARTE_ANY_INTERRUPT_DRIVEN) { + if (cfg->a2i_config) { + err = uart_async_to_irq_init(data->a2i_data, cfg->a2i_config); + if (err < 0) { + return err; + } + } + } + + if (IS_ENABLED(UARTE_INT_ASYNC) && data->async) { + k_timer_init(&data->async->rx_timer, rx_timeout_handler, NULL); + k_timer_user_data_set(&data->async->rx_timer, (void *)dev); + k_timer_init(&data->async->tx_timer, tx_timeout_handler, NULL); + k_timer_user_data_set(&data->async->tx_timer, (void *)dev); + } + + nerr = nrfx_uarte_init(nrfx_dev, &cfg->nrfx_config, + IS_ENABLED(UARTE_INT_ASYNC) ? + (IS_POLLING_API(dev) ? NULL : evt_handler) : NULL); + if (nerr == NRFX_SUCCESS && !IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + err = start_rx(dev); + } + + switch (nerr) { + case NRFX_ERROR_INVALID_STATE: + return -EBUSY; + case NRFX_ERROR_BUSY: + return -EACCES; + case NRFX_ERROR_INVALID_PARAM: + return -EINVAL; + default: + return 0; + } +} + +#ifdef CONFIG_PM_DEVICE +static int stop_rx(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_async_to_irq_rx_disable(dev); + } + + __ASSERT_NO_MSG(IS_POLLING_API(dev)); + nrfx_err_t err; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + + err = nrfx_uarte_rx_abort(instance, true, true); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + return 0; +} + +static int uarte_nrfx_pm_action(const struct device *dev, + enum pm_device_action action) +{ + const struct uarte_nrfx_config *cfg = dev->config; + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT) { + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + } + if (!IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + return start_rx(dev); + } + + break; + case PM_DEVICE_ACTION_SUSPEND: + if (!IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + stop_rx(dev); + } + + if (cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT) { + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP); + if (ret < 0) { + return ret; + } + } + + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +#if defined(UARTE_CONFIG_STOP_Msk) +#define UARTE_HAS_STOP_CONFIG 1 +#endif + +#define UARTE(idx) DT_NODELABEL(uart##idx) +#define UARTE_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(UARTE(idx), prop) +#define UARTE_PROP(idx, prop) DT_PROP(UARTE(idx), prop) + +/* Macro returning initial log level. Logs are off for UART used for console. */ +#define GET_INIT_LOG_LEVEL(idx) \ + COND_CODE_1(DT_HAS_CHOSEN(zephyr_console), \ + (DT_SAME_NODE(UARTE(idx), \ + DT_CHOSEN(zephyr_console)) ? \ + LOG_LEVEL_NONE : CONFIG_UART_LOG_LEVEL), \ + (CONFIG_UART_LOG_LEVEL)) + +/* Macro puts buffers in dedicated section if device tree property is set. */ +#define UARTE_MEMORY_SECTION(idx) \ + COND_CODE_1(UARTE_HAS_PROP(idx, memory_regions), \ + (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ + DT_PHANDLE(UARTE(idx), memory_regions)))))), \ + ()) + +#define UART_NRF_UARTE_DEVICE(idx) \ + LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, GET_INIT_LOG_LEVEL(idx)); \ + static uint8_t uarte##idx##_tx_cache[CONFIG_UART_##idx##_TX_CACHE_SIZE] \ + UARTE_MEMORY_SECTION(idx) __aligned(4); \ + static uint8_t uarte##idx##_rx_cache[CONFIG_UART_##idx##_RX_CACHE_SIZE] \ + UARTE_MEMORY_SECTION(idx) __aligned(4); \ + static nrfx_uarte_rx_cache_t uarte##idx##_rx_cache_scratch; \ + IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (static uint8_t a2i_rx_buf##idx[CONFIG_UART_##idx##_A2I_RX_SIZE];)) \ + PINCTRL_DT_DEFINE(UARTE(idx)); \ + static const struct uart_async_to_irq_config uarte_a2i_config_##idx = \ + UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(&a2i_api, \ + async_to_irq_trampoline, \ + UARTE_PROP(idx, current_speed), \ + uarte##idx##_tx_cache, \ + /* nrfx_uarte driver is using the last byte in the */ \ + /* cache buffer for keeping a byte that is currently*/\ + /* polled out so it cannot be used as a cache buffer*/\ + /* by the adaptation layer. */ \ + sizeof(uarte##idx##_tx_cache) - 1, \ + COND_CODE_1(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (a2i_rx_buf##idx), (NULL)), \ + COND_CODE_1(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (sizeof(a2i_rx_buf##idx)), (0)), \ + CONFIG_UART_##idx##_A2I_RX_BUF_COUNT, \ + LOG_INSTANCE_PTR(LOG_MODULE_NAME, idx)); \ + static const struct uarte_nrfx_config uarte_config_##idx = { \ + .a2i_config = IS_ENABLED(CONFIG_UART_##idx## _INTERRUPT_DRIVEN) ? \ + &uarte_a2i_config_##idx : NULL, \ + .nrfx_dev = NRFX_UARTE_INSTANCE(idx), \ + .nrfx_config = { \ + .p_context = (void *)DEVICE_DT_GET(UARTE(idx)), \ + .tx_cache = { \ + .p_buffer = uarte##idx##_tx_cache, \ + .length = CONFIG_UART_##idx##_TX_CACHE_SIZE \ + }, \ + .rx_cache = { \ + .p_buffer = uarte##idx##_rx_cache, \ + .length = CONFIG_UART_##idx##_RX_CACHE_SIZE \ + }, \ + .p_rx_cache_scratch = &uarte##idx##_rx_cache_scratch, \ + .baudrate = NRF_BAUDRATE(UARTE_PROP(idx, current_speed)), \ + .interrupt_priority = DT_IRQ(UARTE(idx), priority), \ + .config = { \ + .hwfc = (UARTE_PROP(idx, hw_flow_control) == \ + UART_CFG_FLOW_CTRL_RTS_CTS) ? \ + NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED, \ + .parity = IS_ENABLED(CONFIG_UART_##idx##_NRF_PARITY_BIT) ? \ + NRF_UARTE_PARITY_INCLUDED : NRF_UARTE_PARITY_EXCLUDED, \ + IF_ENABLED(UARTE_HAS_STOP_CONFIG, (.stop = NRF_UARTE_STOP_ONE,))\ + IF_ENABLED(UARTE_ODD_PARITY_ALLOWED, \ + (.paritytype = NRF_UARTE_PARITYTYPE_EVEN,)) \ + }, \ + .tx_stop_on_end = IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT), \ + .skip_psel_cfg = true, \ + .skip_gpio_cfg = true, \ + }, \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(UARTE(idx)), \ + .flags = (UARTE_PROP(idx, disable_rx) ? UARTE_CFG_FLAG_NO_RX : 0) | \ + (IS_ENABLED(CONFIG_UART_##idx##_GPIO_MANAGEMENT) ? \ + UARTE_CFG_FLAG_GPIO_MGMT : 0) | \ + (IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) ? \ + UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API : 0), \ + LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx) \ + }; \ + static struct uart_async_to_irq_data uarte_a2i_data_##idx; \ + static struct uarte_async_data uarte_async_##idx; \ + static struct uarte_nrfx_data uarte_data_##idx = { \ + .a2i_data = IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) ? \ + &uarte_a2i_data_##idx : NULL, \ + IF_ENABLED(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ + (.uart_config = { \ + .baudrate = UARTE_PROP(idx, current_speed), \ + .parity = IS_ENABLED(CONFIG_UART_##idx##_NRF_PARITY_BIT) ? \ + UART_CFG_PARITY_EVEN : UART_CFG_PARITY_NONE, \ + .stop_bits = UART_CFG_STOP_BITS_1, \ + .data_bits = UART_CFG_DATA_BITS_8, \ + .flow_ctrl = UARTE_PROP(idx, hw_flow_control) ? \ + UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE, \ + },)) \ + .async = (IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) || \ + IS_ENABLED(CONFIG_UART_##idx##_ASYNC)) ? &uarte_async_##idx : NULL \ + }; \ + static int uarte_init_##idx(const struct device *dev) \ + { \ + COND_CODE_1(INSTANCE_POLLING(_, /*empty*/, idx, _), (), \ + ( \ + IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \ + nrfx_isr, nrfx_uarte_##idx##_irq_handler, 0); \ + irq_enable(DT_IRQN(UARTE(idx))); \ + ) \ + ) \ + return uarte_nrfx_init(dev); \ + } \ + PM_DEVICE_DT_DEFINE(UARTE(idx), uarte_nrfx_pm_action); \ + DEVICE_DT_DEFINE(UARTE(idx), \ + uarte_init_##idx, \ + PM_DEVICE_DT_GET(UARTE(idx)), \ + &uarte_data_##idx, \ + &uarte_config_##idx, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_nrfx_uarte_driver_api) + +/* Macro creates device instance if it is enabled in devicetree. */ +#define UARTE_DEVICE(periph, prefix, id, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##id, (UART_NRF_UARTE_DEVICE(prefix##id);)) + +/* Macro iterates over nrfx_uarte instances enabled in the nrfx_config.h. */ +NRFX_FOREACH_ENABLED(UARTE, UARTE_DEVICE, (), (), _) diff --git a/drivers/spi/spi_nrfx_common.c b/drivers/spi/spi_nrfx_common.c index 1ef233cfab38..04a11c2367a9 100644 --- a/drivers/spi/spi_nrfx_common.c +++ b/drivers/spi/spi_nrfx_common.c @@ -6,40 +6,39 @@ #include "spi_nrfx_common.h" #include -#include -int spi_nrfx_wake_init(uint32_t wake_pin) +int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) { - nrfx_gpiote_input_config_t input_config = { - .pull = NRF_GPIO_PIN_PULLDOWN, - }; + nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN; uint8_t ch; nrfx_gpiote_trigger_config_t trigger_config = { .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, .p_in_channel = &ch, }; + nrfx_gpiote_input_pin_config_t input_config = { + .p_pull_config = &pull_config, + .p_trigger_config = &trigger_config, + .p_handler_config = NULL, + }; nrfx_err_t res; - res = nrfx_gpiote_channel_alloc(&ch); + res = nrfx_gpiote_channel_alloc(gpiote, &ch); if (res != NRFX_SUCCESS) { return -ENODEV; } - res = nrfx_gpiote_input_configure(wake_pin, - &input_config, - &trigger_config, - NULL); + res = nrfx_gpiote_input_configure(gpiote, wake_pin, &input_config); if (res != NRFX_SUCCESS) { - nrfx_gpiote_channel_free(ch); + nrfx_gpiote_channel_free(gpiote, ch); return -EIO; } return 0; } -int spi_nrfx_wake_request(uint32_t wake_pin) +int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) { - nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(wake_pin); + nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(gpiote, wake_pin); uint32_t start_cycles; uint32_t max_wait_cycles = DIV_ROUND_UP(CONFIG_SPI_NRFX_WAKE_TIMEOUT_US * @@ -51,7 +50,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) * The expected time to wait is quite short so it is not worth paying * the overhead of context switching to handle the interrupt. */ - nrfx_gpiote_trigger_enable(wake_pin, false); + nrfx_gpiote_trigger_enable(gpiote, wake_pin, false); /* Enable pull-up on the WAKE line. After the slave device sees the * WAKE line going high, it will force the line to go low. This will * be caught by the enabled trigger and the loop below waits for that. @@ -59,7 +58,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLUP); start_cycles = k_cycle_get_32(); - while (!nrf_gpiote_event_check(NRF_GPIOTE, trigger_event)) { + while (!nrf_gpiote_event_check(gpiote->p_reg, trigger_event)) { uint32_t elapsed_cycles = k_cycle_get_32() - start_cycles; if (elapsed_cycles >= max_wait_cycles) { @@ -68,7 +67,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) } } - nrfx_gpiote_trigger_disable(wake_pin); + nrfx_gpiote_trigger_disable(gpiote, wake_pin); nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLDOWN); return err; diff --git a/drivers/spi/spi_nrfx_common.h b/drivers/spi/spi_nrfx_common.h index 515ed5c6f1f2..0cf17e2a0356 100644 --- a/drivers/spi/spi_nrfx_common.h +++ b/drivers/spi/spi_nrfx_common.h @@ -8,10 +8,17 @@ #define ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ #include +#include #define WAKE_PIN_NOT_USED UINT32_MAX -int spi_nrfx_wake_init(uint32_t wake_pin); -int spi_nrfx_wake_request(uint32_t wake_pin); +#define WAKE_GPIOTE_INSTANCE(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, wake_gpios), \ + (NRFX_GPIOTE_INSTANCE( \ + NRF_DT_GPIOTE_INST(node_id, wake_gpios))), \ + ({0})) + +int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); +int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); #endif /* ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ */ diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index fd1dc5d933c4..04d7853d11d4 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -31,6 +31,7 @@ struct spi_nrfx_config { void (*irq_connect)(void); const struct pinctrl_dev_config *pcfg; uint32_t wake_pin; + nrfx_gpiote_t wake_gpiote; }; static void event_handler(const nrfx_spi_evt_t *p_event, void *p_context); @@ -237,7 +238,8 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(dev_config->wake_pin); + error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); /* If timeout occurs, try to perform the transfer @@ -381,7 +383,7 @@ static int spi_nrfx_init(const struct device *dev) } if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(dev_config->wake_pin); + err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -444,6 +446,7 @@ static int spi_nrfx_init(const struct device *dev) .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPI(idx)), \ .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPI(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ + .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPI(idx)), \ }; \ BUILD_ASSERT(!DT_NODE_HAS_PROP(SPI(idx), wake_gpios) || \ !(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 8b187f54c52b..fb89f096ccaa 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -9,7 +9,6 @@ #include #include #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 -#include #include #endif #include @@ -61,6 +60,7 @@ struct spi_nrfx_config { bool anomaly_58_workaround; #endif uint32_t wake_pin; + nrfx_gpiote_t wake_gpiote; }; static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context); @@ -204,6 +204,8 @@ static int configure(const struct device *dev, } #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 +static const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(0); + /* * Brief Workaround for transmitting 1 byte with SPIM. * @@ -223,15 +225,15 @@ static void anomaly_58_workaround_setup(const struct device *dev) NRF_SPIM_Type *spim = dev_config->spim.p_reg; uint32_t ppi_ch = dev_data->ppi_ch; uint32_t gpiote_ch = dev_data->gpiote_ch; - uint32_t eep = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_ch]; + uint32_t eep = (uint32_t)&gpiote.p_reg->EVENTS_IN[gpiote_ch]; uint32_t tep = (uint32_t)&spim->TASKS_STOP; dev_data->anomaly_58_workaround_active = true; /* Create an event when SCK toggles */ - nrf_gpiote_event_configure(NRF_GPIOTE, gpiote_ch, spim->PSEL.SCK, + nrf_gpiote_event_configure(gpiote.p_reg, gpiote_ch, spim->PSEL.SCK, GPIOTE_CONFIG_POLARITY_Toggle); - nrf_gpiote_event_enable(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_event_enable(gpiote.p_reg, gpiote_ch); /* Stop the spim instance when SCK toggles */ nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, eep, tep); @@ -250,7 +252,7 @@ static void anomaly_58_workaround_clear(struct spi_nrfx_data *dev_data) if (dev_data->anomaly_58_workaround_active) { nrf_ppi_channel_disable(NRF_PPI, ppi_ch); - nrf_gpiote_task_disable(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_task_disable(gpiote.p_reg, gpiote_ch); dev_data->anomaly_58_workaround_active = false; } @@ -271,7 +273,7 @@ static int anomaly_58_workaround_init(const struct device *dev) return -ENODEV; } - err_code = nrfx_gpiote_channel_alloc(&dev_data->gpiote_ch); + err_code = nrfx_gpiote_channel_alloc(&gpiote, &dev_data->gpiote_ch); if (err_code != NRFX_SUCCESS) { LOG_ERR("Failed to allocate GPIOTE channel"); return -ENODEV; @@ -399,7 +401,8 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(dev_config->wake_pin); + error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); /* If timeout occurs, try to perform the transfer @@ -547,7 +550,7 @@ static int spi_nrfx_init(const struct device *dev) } if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(dev_config->wake_pin); + err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -634,6 +637,7 @@ static int spi_nrfx_init(const struct device *dev) ()) \ .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ + .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ }; \ BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIM(idx), wake_gpios) || \ !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 47a10b358c1b..36534e4716f0 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources_ifdef(CONFIG_MCUX_GPT_TIMER mcux_gpt_timer.c) zephyr_library_sources_ifdef(CONFIG_MIPS_CP0_TIMER mips_cp0_timer.c) zephyr_library_sources_ifdef(CONFIG_NATIVE_POSIX_TIMER native_posix_timer.c) zephyr_library_sources_ifdef(CONFIG_NPCX_ITIM_TIMER npcx_itim_timer.c) +zephyr_library_sources_ifdef(CONFIG_NRF_GRTC_TIMER nrf_grtc_timer.c) 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) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 8a88e731986c..f20442dd2c58 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -84,6 +84,8 @@ source "drivers/timer/Kconfig.mips_cp0" source "drivers/timer/Kconfig.native_posix" source "drivers/timer/Kconfig.npcx_itim" source "drivers/timer/Kconfig.nrf_rtc" +source "drivers/timer/Kconfig.nrf_grtc" +source "drivers/timer/Kconfig.nrf_xrtc" source "drivers/timer/Kconfig.rcar_cmt" source "drivers/timer/Kconfig.riscv_machine" source "drivers/timer/Kconfig.rv32m1_lptmr" diff --git a/drivers/timer/Kconfig.nrf_grtc b/drivers/timer/Kconfig.nrf_grtc new file mode 100644 index 000000000000..442c524fd197 --- /dev/null +++ b/drivers/timer/Kconfig.nrf_grtc @@ -0,0 +1,48 @@ +# Timer driver configuration options +# Copyright (c) 2024 Nordic Semiconductor ASA + +menuconfig NRF_GRTC_TIMER + bool "nRF GRTC Timer" + default y if DT_HAS_NORDIC_NRF_GRTC_ENABLED + select TICKLESS_CAPABLE + select TIMER_HAS_64BIT_CYCLE_COUNTER + select NRFX_GRTC + help + This module implements a kernel device driver for the nRF Global Real + Time Counter NRF_GRTC and provides the standard "system clock driver" + interfaces. + +if NRF_GRTC_TIMER + +config NRF_GRTC_SLEEP_ALLOWED + def_bool y + depends on POWEROFF + help + This feature allows GRTC SYSCOUNTER to go to sleep state. + +config NRF_GRTC_TIMER_APP_DEFINED_INIT + bool "Application defines GRTC initialization" + help + Application defines the initialization procedure and time of the GRTC + drivers, rather than leaving it up to SYS_INIT. + +config NRF_GRTC_START_SYSCOUNTER + bool "Start SYSCOUNTER on driver init" + select NRF_GRTC_TIMER_CLOCK_MANAGEMENT + help + Start the SYSCOUNTER when initializing the GRTC. This should only be + handled by one processor in the system. + +config NRF_GRTC_TIMER_CLOCK_MANAGEMENT + bool + help + Compile additional driver code for enabling management functionality of + the GRTC. Usually this is only needed by the processor that is starting + the SYSCOUNTER, but can be shared by multiple processors in the system. + +config NRF_GRTC_SLEEP_MINIMUM_LATENCY + int + default 1000 + depends on NRF_GRTC_SLEEP_ALLOWED + +endif # NRF_GRTC_TIMER diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index baa917282bc6..729dc8d362a7 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -42,36 +42,4 @@ config NRF_RTC_TIMER_TRIGGER_OVERFLOW When enabled, a function can be used to trigger RTC overflow and effectively shift time into the future. -choice - prompt "Clock startup policy" - default SYSTEM_CLOCK_WAIT_FOR_STABILITY - -config SYSTEM_CLOCK_NO_WAIT - bool "No wait" - help - System clock source is initiated but does not wait for clock readiness. - When this option is picked, system clock may not be ready when code relying - on kernel API is executed. Requested timeouts will be prolonged by the - remaining startup time. - -config SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY - bool "Wait for availability" - help - System clock source initialization waits until clock is available. In some - systems, clock initially runs from less accurate source which has faster - startup time and then seamlessly switches to the target clock source when - it is ready. When this option is picked, system clock is available after - system clock driver initialization but it may be less accurate. Option is - equivalent to waiting for stability if clock source does not have - intermediate state. - -config SYSTEM_CLOCK_WAIT_FOR_STABILITY - bool "Wait for stability" - help - System clock source initialization waits until clock is stable. When this - option is picked, system clock is available and stable after system clock - driver initialization. - -endchoice - endif # NRF_RTC_TIMER diff --git a/drivers/timer/Kconfig.nrf_xrtc b/drivers/timer/Kconfig.nrf_xrtc new file mode 100644 index 000000000000..f9fa25a1c306 --- /dev/null +++ b/drivers/timer/Kconfig.nrf_xrtc @@ -0,0 +1,38 @@ +# Common RTC configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if NRF_RTC_TIMER || NRF_GRTC_TIMER +choice + prompt "Clock startup policy" + default SYSTEM_CLOCK_WAIT_FOR_STABILITY + +config SYSTEM_CLOCK_NO_WAIT + bool "No wait" + help + System clock source is initiated but does not wait for clock readiness. + When this option is picked, system clock may not be ready when code relying + on kernel API is executed. Requested timeouts will be prolonged by the + remaining startup time. + +config SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY + bool "Wait for availability" + help + System clock source initialization waits until clock is available. In some + systems, clock initially runs from less accurate source which has faster + startup time and then seamlessly switches to the target clock source when + it is ready. When this option is picked, system clock is available after + system clock driver initialization but it may be less accurate. Option is + equivalent to waiting for stability if clock source does not have + intermediate state. + +config SYSTEM_CLOCK_WAIT_FOR_STABILITY + bool "Wait for stability" + help + System clock source initialization waits until clock is stable. When this + option is picked, system clock is available and stable after system clock + driver initialization. + +endchoice +endif # NRF_RTC_TIMER || NRF_GRTC_TIMER diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c new file mode 100644 index 000000000000..8ac357864cc5 --- /dev/null +++ b/drivers/timer/nrf_grtc_timer.c @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#if defined(CONFIG_CLOCK_CONTROL_NRF) +#include +#endif +#include +#include +#include +#include + +#define GRTC_NODE DT_NODELABEL(grtc) + +/* Ensure that GRTC properties in devicetree are defined correctly. */ +#if !DT_NODE_HAS_PROP(GRTC_NODE, owned_channels) +#error GRTC owned-channels DT property is not defined +#endif +#define OWNED_CHANNELS_MASK NRFX_CONFIG_GRTC_MASK_DT(owned_channels) +#define CHILD_OWNED_CHANNELS_MASK NRFX_CONFIG_GRTC_MASK_DT(child_owned_channels) +#if ((OWNED_CHANNELS_MASK | CHILD_OWNED_CHANNELS_MASK) != OWNED_CHANNELS_MASK) +#error GRTC child-owned-channels DT property must be a subset of owned-channels +#endif + +#define CHAN_COUNT NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define EXT_CHAN_COUNT (CHAN_COUNT - 1) +/* The reset value of waketime is 1, which doesn't seem to work. + * It's being looked into, but for the time being use 4. + * Timeout must always be higher than waketime, so setting that to 5. + */ +#define WAKETIME (4) +#define TIMEOUT (WAKETIME + 1) + +#ifndef GRTC_SYSCOUNTERL_VALUE_Msk +#define GRTC_SYSCOUNTERL_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERL_VALUE_Msk +#endif + +#ifndef GRTC_SYSCOUNTERH_VALUE_Msk +#define GRTC_SYSCOUNTERH_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERH_VALUE_Msk +#endif + +#define MAX_CC_LATCH_WAIT_TIME_US 77 + +#define CYC_PER_TICK \ + ((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +#define COUNTER_SPAN (GRTC_SYSCOUNTERL_VALUE_Msk | ((uint64_t)GRTC_SYSCOUNTERH_VALUE_Msk << 32)) +#define MAX_TICKS \ + (((COUNTER_SPAN / CYC_PER_TICK) > INT_MAX) ? INT_MAX : (COUNTER_SPAN / CYC_PER_TICK)) + +#define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) + +/* The maximum SYSCOUNTERVALID settling time equals 1x32k cycles + 20x1MHz cycles. */ +#define GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US 51 + +#if defined(CONFIG_TEST) +const int32_t z_sys_timer_irq_for_test = DT_IRQN(GRTC_NODE); +#endif + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context); + +static struct k_spinlock lock; +static uint64_t last_count; +static atomic_t int_mask; +static uint8_t ext_channels_allocated; +static nrfx_grtc_channel_t system_clock_channel_data = { + .handler = sys_clock_timeout_handler, + .p_context = NULL, + .channel = (uint8_t)-1, +}; + +#define IS_CHANNEL_ALLOWED_ASSERT(chan) \ + __ASSERT_NO_MSG((NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK & (1UL << (chan))) && \ + ((chan) != system_clock_channel_data.channel)) + +static inline void grtc_active_set(void) +{ +#if defined(NRF_GRTC_HAS_SYSCOUNTER_ARRAY) && (NRF_GRTC_HAS_SYSCOUNTER_ARRAY == 1) + nrfy_grtc_sys_counter_active_set(NRF_GRTC, true); + while (!nrfy_grtc_sys_conter_ready_check(NRF_GRTC)) { + } +#else + nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, true); + k_busy_wait(GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US); +#endif +} + +static inline void grtc_wakeup(void) +{ + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + grtc_active_set(); + } +} + +static inline void grtc_sleep(void) +{ + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { +#if defined(NRF_GRTC_HAS_SYSCOUNTER_ARRAY) && (NRF_GRTC_HAS_SYSCOUNTER_ARRAY == 1) + nrfy_grtc_sys_counter_active_set(NRF_GRTC, false); +#else + nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, false); +#endif + } +} + +static inline uint64_t counter_sub(uint64_t a, uint64_t b) +{ + return (a - b); +} + +static inline uint64_t counter(void) +{ + uint64_t now; + + grtc_wakeup(); + nrfx_grtc_syscounter_get(&now); + grtc_sleep(); + return now; +} + +static inline uint64_t get_comparator(uint32_t chan) +{ + uint64_t cc; + nrfx_err_t result; + + result = nrfx_grtc_syscounter_cc_value_read(chan, &cc); + if (result != NRFX_SUCCESS) { + if (result != NRFX_ERROR_INVALID_PARAM) { + return -EAGAIN; + } + return -EPERM; + } + return cc; +} + +static void system_timeout_set(uint64_t value) +{ + if (value <= NRF_GRTC_SYSCOUNTER_CCADD_MASK) { + grtc_wakeup(); + nrfx_grtc_syscounter_cc_relative_set(&system_clock_channel_data, value, true, + NRFX_GRTC_CC_RELATIVE_SYSCOUNTER); + grtc_sleep(); + } else { + nrfx_grtc_syscounter_cc_absolute_set(&system_clock_channel_data, value + counter(), + true); + } +} + +static bool compare_int_lock(int32_t chan) +{ + atomic_val_t prev = atomic_and(&int_mask, ~BIT(chan)); + + nrfx_grtc_syscounter_cc_int_disable(chan); + + return prev & BIT(chan); +} + +static void compare_int_unlock(int32_t chan, bool key) +{ + if (key) { + atomic_or(&int_mask, BIT(chan)); + nrfx_grtc_syscounter_cc_int_enable(chan); + } +} + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context) +{ + ARG_UNUSED(id); + ARG_UNUSED(p_context); + uint64_t dticks; + uint64_t now = counter(); + + if (unlikely(now < cc_val)) { + return; + } + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + /* protection is not needed because we are in the GRTC interrupt + * so it won't get preempted by the interrupt. + */ + system_timeout_set(CYC_PER_TICK); + } + + dticks = counter_sub(now, last_count) / CYC_PER_TICK; + + last_count += dticks * CYC_PER_TICK; + sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? (int32_t)dticks : (dticks > 0)); +} + +int32_t z_nrf_grtc_timer_chan_alloc(void) +{ + uint8_t chan; + nrfx_err_t err_code; + + /* Prevent allocating all available channels - one must be left for system purposes. */ + if (ext_channels_allocated >= EXT_CHAN_COUNT) { + return -ENOMEM; + } + err_code = nrfx_grtc_channel_alloc(&chan); + if (err_code != NRFX_SUCCESS) { + return -ENOMEM; + } + ext_channels_allocated++; + return (int32_t)chan; +} + +void z_nrf_grtc_timer_chan_free(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + nrfx_err_t err_code = nrfx_grtc_channel_free(chan); + + if (err_code == NRFX_SUCCESS) { + ext_channels_allocated--; + } +} + +bool z_nrf_grtc_timer_compare_evt_check(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + uint32_t event_address = nrfx_grtc_event_compare_address_get(chan); + + return *(volatile uint32_t *)event_address != 0; +} + +uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return nrfx_grtc_event_compare_address_get(chan); +} + +uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return nrfx_grtc_capture_task_address_get(chan); +} + +uint64_t z_nrf_grtc_timer_read(void) +{ + return counter(); +} + +bool z_nrf_grtc_timer_compare_int_lock(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return compare_int_lock(chan); +} + +void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + compare_int_unlock(chan, key); +} + +uint64_t z_nrf_grtc_timer_compare_read(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return get_comparator(chan); +} + +static int compare_set_nolocks(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + nrfx_err_t result; + + __ASSERT_NO_MSG(target_time < COUNTER_SPAN); + nrfx_grtc_channel_t user_channel_data = { + .handler = handler, + .p_context = user_data, + .channel = chan, + }; + result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, target_time, true); + if (result != NRFX_SUCCESS) { + return -EPERM; + } + return 0; +} + +static int compare_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + bool key = compare_int_lock(chan); + int ret = compare_set_nolocks(chan, target_time, handler, user_data); + + compare_int_unlock(chan, key); + + return ret; +} + +int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return compare_set(chan, target_time, (nrfx_grtc_cc_handler_t)handler, user_data); +} + +void z_nrf_grtc_timer_abort(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + bool key = compare_int_lock(chan); + (void)nrfx_grtc_syscounter_cc_disable(chan); + compare_int_unlock(chan, key); +} + +uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t) +{ + uint64_t curr_time; + int64_t curr_tick; + int64_t result; + int64_t abs_ticks; + + curr_time = counter(); + curr_tick = sys_clock_tick_get(); + + abs_ticks = Z_TICK_ABS(t.ticks); + if (abs_ticks < 0) { + /* relative timeout */ + return (t.ticks > (int64_t)COUNTER_SPAN) ? -EINVAL : (curr_time + t.ticks); + } + + /* absolute timeout */ + result = abs_ticks - curr_tick; + + if (result > (int64_t)COUNTER_SPAN) { + return -EINVAL; + } + + return curr_time + result; +} + +int z_nrf_grtc_timer_capture_prepare(int32_t chan) +{ + nrfx_grtc_channel_t user_channel_data = { + .handler = NULL, + .p_context = NULL, + .channel = chan, + }; + nrfx_err_t result; + + IS_CHANNEL_ALLOWED_ASSERT(chan); + + /* Set the CC value to mark channel as not triggered and also to enable it + * (makes CCEN=1). COUNTER_SPAN is used so as not to fire an event unnecessarily + * - it can be assumed that such a large value will never be reached. + */ + result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, COUNTER_SPAN, false); + + if (result != NRFX_SUCCESS) { + return -EPERM; + } + + return 0; +} + +int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time) +{ + /* TODO: The implementation should probably go to nrfx_grtc and this + * should be just a wrapper for some nrfx_grtc_syscounter_capture_read. + */ + + uint64_t capt_time; + + IS_CHANNEL_ALLOWED_ASSERT(chan); + + /* TODO: Use `nrfy_grtc_sys_counter_enable_check` when available (NRFX-2480) */ + if (NRF_GRTC->CC[chan].CCEN == GRTC_CC_CCEN_ACTIVE_Enable) { + /* If the channel is enabled (.CCEN), it means that there was no capture + * triggering event. + */ + return -EBUSY; + } + + capt_time = nrfy_grtc_sys_counter_cc_get(NRF_GRTC, chan); + + __ASSERT_NO_MSG(capt_time < COUNTER_SPAN); + + *captured_time = capt_time; + + return 0; +} + +#if defined(CONFIG_NRF_GRTC_SLEEP_ALLOWED) +int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us) +{ + nrfx_err_t err_code; + static uint8_t systemoff_channel; + uint64_t now = counter(); + /* Minimum time that ensures valid execution of system-off procedure. */ + uint32_t minimum_latency_us = nrfy_grtc_waketime_get(NRF_GRTC) + + nrfy_grtc_timeout_get(NRF_GRTC) + + CONFIG_NRF_GRTC_SLEEP_MINIMUM_LATENCY; + uint32_t chan; + int ret; + + if (minimum_latency_us > wake_time_us) { + return -EINVAL; + } + k_spinlock_key_t key = k_spin_lock(&lock); + + err_code = nrfx_grtc_channel_alloc(&systemoff_channel); + if (err_code != NRFX_SUCCESS) { + k_spin_unlock(&lock, key); + return -ENOMEM; + } + (void)nrfx_grtc_syscounter_cc_int_disable(systemoff_channel); + ret = compare_set(systemoff_channel, now + wake_time_us, NULL, NULL); + if (ret < 0) { + k_spin_unlock(&lock, key); + return ret; + } + + for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) { + /* Clear all GRTC channels except the systemoff_channel. */ + chan = u32_count_trailing_zeros(grtc_chan_mask); + if (chan != systemoff_channel) { + nrfx_grtc_syscounter_cc_disable(chan); + } + } + + /* Make sure that wake_time_us was not triggered yet. */ + if (nrfy_grtc_sys_counter_compare_event_check(NRF_GRTC, systemoff_channel)) { + k_spin_unlock(&lock, key); + return -EINVAL; + } + + /* This mechanism ensures that stored CC value is latched. */ + uint32_t wait_time = + nrfy_grtc_timeout_get(NRF_GRTC) * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 32768 + + MAX_CC_LATCH_WAIT_TIME_US; + k_busy_wait(wait_time); +#if NRF_GRTC_HAS_CLKSEL + nrfy_grtc_clksel_set(NRF_GRTC, NRF_GRTC_CLKSEL_LFXO); +#endif + k_spin_unlock(&lock, key); + return 0; +} +#endif /* CONFIG_NRF_GRTC_SLEEP_ALLOWED */ + +uint32_t sys_clock_cycle_get_32(void) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + uint32_t ret = (uint32_t)counter(); + + k_spin_unlock(&lock, key); + return ret; +} + +uint64_t sys_clock_cycle_get_64(void) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + uint64_t ret = counter(); + + k_spin_unlock(&lock, key); + return ret; +} + +uint32_t sys_clock_elapsed(void) +{ + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return 0; + } + + return (uint32_t)(counter_sub(counter(), last_count) / CYC_PER_TICK); +} + +static int sys_clock_driver_init(void) +{ + nrfx_err_t err_code; + +#if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && \ + (defined(NRF_GRTC_HAS_CLKSEL) && (NRF_GRTC_HAS_CLKSEL == 1)) + /* Use System LFCLK as the low-frequency clock source. */ + nrfy_grtc_clksel_set(NRF_GRTC, NRF_GRTC_CLKSEL_LFCLK); +#endif + +#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) + /* SYSCOUNTER needs to be turned off before initialization. */ + nrfy_grtc_sys_counter_set(NRF_GRTC, false); + nrfy_grtc_timeout_set(NRF_GRTC, TIMEOUT); + nrfy_grtc_waketime_set(NRF_GRTC, WAKETIME); +#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + IRQ_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_grtc_irq_handler, 0, 0); + + err_code = nrfx_grtc_init(0); + if (err_code != NRFX_SUCCESS) { + return -EPERM; + } + +#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) + err_code = nrfx_grtc_syscounter_start(true, &system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return err_code == NRFX_ERROR_NO_MEM ? -ENOMEM : -EPERM; + } + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + nrfy_grtc_sys_counter_auto_mode_set(NRF_GRTC, false); + } +#else + err_code = nrfx_grtc_channel_alloc(&system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return -ENOMEM; + } +#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + if (!IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + grtc_active_set(); + } + + int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + system_timeout_set(CYC_PER_TICK); + } + +#if defined(CONFIG_CLOCK_CONTROL_NRF) + static const enum nrf_lfclk_start_mode mode = + IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) + ? CLOCK_CONTROL_NRF_LF_START_NOWAIT + : (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) + ? CLOCK_CONTROL_NRF_LF_START_AVAILABLE + : CLOCK_CONTROL_NRF_LF_START_STABLE); + + z_nrf_clock_control_lf_on(mode); +#endif + + return 0; +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + uint64_t cyc, off, now; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return; + } + + ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : MIN(MAX_TICKS, MAX(ticks - 1, 0)); + + now = counter(); + + /* Round up to the next tick boundary */ + off = (now - last_count) + (CYC_PER_TICK - 1); + off = (off / CYC_PER_TICK) * CYC_PER_TICK; + + /* Get the offset with respect to now */ + off -= (now - last_count); + + /* Add the offset to get to the next tick boundary */ + cyc = (uint64_t)ticks * CYC_PER_TICK + off; + + /* Due to elapsed time the calculation above might produce a + * duration that laps the counter. Don't let it. + */ + if (cyc > MAX_CYCLES) { + cyc = MAX_CYCLES; + } + + system_timeout_set(cyc == 0 ? 1 : cyc); +} + +#if defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT) +int nrf_grtc_timer_clock_driver_init(void) +{ + return sys_clock_driver_init(); +} +#else +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); +#endif diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c index 9045e1ded702..3db193ee2f07 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c @@ -376,8 +376,6 @@ static bool nrf_usbd_common_feeder(nrf_usbd_common_ep_transfer_t *p_next, nrf_usbd_common_transfer_t *p_transfer, size_t ep_size) { - __ASSERT_NO_MSG(nrfx_is_in_ram(p_transfer->p_data.tx)); - size_t tx_size = p_transfer->size; if (tx_size > ep_size) { diff --git a/drivers/watchdog/Kconfig.nrfx b/drivers/watchdog/Kconfig.nrfx index 52cf45dc0687..2967fe864890 100644 --- a/drivers/watchdog/Kconfig.nrfx +++ b/drivers/watchdog/Kconfig.nrfx @@ -9,5 +9,9 @@ config WDT_NRFX depends on DT_HAS_NORDIC_NRF_WDT_ENABLED select NRFX_WDT0 if HAS_HW_NRF_WDT0 select NRFX_WDT1 if HAS_HW_NRF_WDT1 + select NRFX_WDT30 if HAS_HW_NRF_WDT30 + select NRFX_WDT31 if HAS_HW_NRF_WDT31 + select NRFX_WDT130 if HAS_HW_NRF_WDT130 + help Enable support for nrfx WDT driver for nRF MCU series. diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 98fcb713b818..8967d1e162be 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -145,8 +145,12 @@ static const struct wdt_driver_api wdt_nrfx_driver_api = { .feed = wdt_nrf_feed, }; -static void wdt_event_handler(const struct device *dev, uint32_t requests) +static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type, + uint32_t requests, void *p_context) { + (void)event_type; + (void)p_context; + struct wdt_nrfx_data *data = dev->data; while (requests) { @@ -162,9 +166,12 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) #define WDT(idx) DT_NODELABEL(wdt##idx) #define WDT_NRFX_WDT_DEVICE(idx) \ - static void wdt_##idx##_event_handler(uint32_t requests) \ + static void wdt_##idx##_event_handler(nrf_wdt_event_t event_type, \ + uint32_t requests, \ + void *p_context) \ { \ - wdt_event_handler(DEVICE_DT_GET(WDT(idx)), requests); \ + wdt_event_handler(DEVICE_DT_GET(WDT(idx)), event_type, \ + requests, p_context); \ } \ static int wdt_##idx##_init(const struct device *dev) \ { \ @@ -174,7 +181,8 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0); \ err_code = nrfx_wdt_init(&config->wdt, \ NULL, \ - wdt_##idx##_event_handler); \ + wdt_##idx##_event_handler, \ + NULL); \ if (err_code != NRFX_SUCCESS) { \ return -EBUSY; \ } \ @@ -202,3 +210,15 @@ WDT_NRFX_WDT_DEVICE(0); #ifdef CONFIG_HAS_HW_NRF_WDT1 WDT_NRFX_WDT_DEVICE(1); #endif + +#ifdef CONFIG_HAS_HW_NRF_WDT30 +WDT_NRFX_WDT_DEVICE(30); +#endif + +#ifdef CONFIG_HAS_HW_NRF_WDT31 +WDT_NRFX_WDT_DEVICE(31); +#endif + +#ifdef CONFIG_HAS_HW_NRF_WDT130 +WDT_NRFX_WDT_DEVICE(130); +#endif diff --git a/dts/arm/nordic/nrf51822.dtsi b/dts/arm/nordic/nrf51822.dtsi index 222ccd4854c3..b64de1d4985c 100644 --- a/dts/arm/nordic/nrf51822.dtsi +++ b/dts/arm/nordic/nrf51822.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -24,6 +24,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -131,11 +132,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -316,6 +318,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index dd7845588e7d..c5a184d5e288 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -28,6 +28,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -132,11 +133,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -311,6 +313,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -318,3 +321,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 82f5afb99f6d..1ca4a9ea378a 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -136,11 +137,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -337,6 +339,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -344,3 +347,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 9e03d5edb320..63b856765877 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -36,6 +36,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -167,11 +168,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -372,6 +374,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -379,3 +382,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index 71ff85afbeb9..f93e449b0b2c 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { @@ -37,6 +37,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -180,11 +181,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; timer0: timer@40008000 { @@ -389,6 +391,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -396,3 +399,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index 69de3aa591ad..ed5a21b9935a 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -179,11 +180,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -465,6 +467,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -472,3 +475,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index 8003649385cf..5ac9cb2d2f87 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -36,6 +36,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -186,11 +187,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -521,6 +523,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@50000300 { @@ -532,6 +535,7 @@ ngpios = <10>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; }; }; @@ -539,3 +543,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 24710e8e0ff2..8efe49a3c91a 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { - zephyr,entropy = &rng; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -181,11 +182,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -525,6 +527,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@50000300 { @@ -536,6 +539,7 @@ ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; cryptocell: crypto@5002a000 { @@ -543,7 +547,7 @@ reg = <0x5002a000 0x1000>, <0x5002b000 0x1000>; reg-names = "wrapper", "core"; interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; }; @@ -551,3 +555,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 77762990e133..d48f0ce62dc4 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -33,7 +33,7 @@ }; chosen { - zephyr,entropy = &rng_hci; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -41,6 +41,7 @@ ficr: ficr@ff0000 { compatible = "nordic,nrf-ficr"; reg = <0xff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -84,6 +85,16 @@ reg = <0x5000d000 0x1000>; interrupts = <13 5>; status = "disabled"; + instance = <0>; + }; + + /* Additional Non-Secure GPIOTE instance */ + gpiote1: gpiote@4002f000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x4002f000 0x1000>; + interrupts = <47 5>; + status = "disabled"; + instance = <1>; }; cryptocell: crypto@50844000 { @@ -91,7 +102,7 @@ reg = <0x50844000 0x1000>, <0x50845000 0x1000>; reg-names = "wrapper", "core"; interrupts = <68 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; @@ -105,9 +116,7 @@ arm,num-irq-priority-bits = <3>; }; -/* - * Include the non-secure peripherals file here since - * it expects to be at the root level. This provides - * a node for GPIOTE1. - */ -#include "nrf5340_cpuapp_peripherals_ns.dtsi" +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi index e7aa0309f70d..afb839fcef48 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi @@ -526,6 +526,7 @@ gpio0: gpio@842500 { #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@842800 { @@ -536,6 +537,7 @@ gpio1: gpio@842800 { ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; ieee802154: ieee802154 { diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi deleted file mode 100644 index 5cfe561e6139..000000000000 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * GPIOTE1 is always accessible as a non-secure peripheral. - */ - -/ { - soc { - gpiote1: gpiote@4002f000 { - compatible = "nordic,nrf-gpiote"; - reg = <0x4002f000 0x1000>; - interrupts = <47 5>; - status = "disabled"; - }; - }; -}; diff --git a/dts/arm/nordic/nrf5340_cpuappns.dtsi b/dts/arm/nordic/nrf5340_cpuappns.dtsi index b5278745e5d5..6df1be54b348 100644 --- a/dts/arm/nordic/nrf5340_cpuappns.dtsi +++ b/dts/arm/nordic/nrf5340_cpuappns.dtsi @@ -7,7 +7,7 @@ /* .dtsi header for nRF5340 CPUAPP (Application MCU), Non-Secure domain */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -48,6 +48,19 @@ */ #include "nrf5340_cpuapp_peripherals.dtsi" }; + + /* + * GPIOTE1 is always accessible as a non-secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote1: gpiote@4002f000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x4002f000 0x1000>; + interrupts = <47 5>; + status = "disabled"; + instance = <1>; + }; }; /* Default IPC description */ @@ -65,11 +78,7 @@ arm,num-irq-priority-bits = <3>; }; -/* - * Include the non-secure peripherals file here since - * it expects to be at the root level, adding a 'gpiote' label - * for the GPIOTE1 peripheral defined in that file which is - * always accessible as a non-secure peripheral. - */ -#include "nrf5340_cpuapp_peripherals_ns.dtsi" -gpiote: &gpiote1 {}; +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpunet.dtsi b/dts/arm/nordic/nrf5340_cpunet.dtsi index 63c7e920f818..8a95b3e99850 100644 --- a/dts/arm/nordic/nrf5340_cpunet.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -35,6 +35,7 @@ ficr: ficr@1ff0000 { compatible = "nordic,nrf-ficr"; reg = <0x01ff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -108,11 +109,12 @@ status = "okay"; }; - gpiote: gpiote@4100a000 { + gpiote: gpiote0: gpiote@4100a000 { compatible = "nordic,nrf-gpiote"; reg = <0x4100a000 0x1000>; interrupts = <10 5>; status = "disabled"; + instance = <0>; }; wdt: wdt0: watchdog@4100b000 { @@ -192,6 +194,7 @@ reg = <0x41013000 0x1000>; clock-frequency = ; interrupts = <19 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -317,6 +320,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@418c0800 { @@ -327,6 +331,7 @@ ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; }; @@ -346,3 +351,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi b/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi new file mode 100644 index 000000000000..f51528d57332 --- /dev/null +++ b/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuapp {}; +systick: &cpuapp_systick {}; +nvic: &cpuapp_nvic {}; + +/delete-node/ &cpuppr; +/delete-node/ &cpurad; +/delete-node/ &cpurad_peripherals; +/delete-node/ &cpurad_ppb; +/delete-node/ &cpurad_ram0; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuapp_nvic>; + ranges; + }; +}; + +&cpuapp_ppb { + compatible = "simple-bus"; + ranges; +}; + +&gpiote130 { + interrupts = <105 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi b/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi new file mode 100644 index 000000000000..cb2767381daf --- /dev/null +++ b/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpurad {}; +systick: &cpurad_systick {}; +nvic: &cpurad_nvic {}; + +/delete-node/ &cpuapp; +/delete-node/ &cpuapp_peripherals; +/delete-node/ &cpuapp_ppb; +/delete-node/ &cpuapp_ram0; +/delete-node/ &cpuppr; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpurad_nvic>; + ranges; + }; +}; + +&cpurad_ppb { + compatible = "simple-bus"; + ranges; +}; + +&gpiote130 { + interrupts = <105 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/dts/arm/nordic/nrf54l15_cpuapp.dtsi b/dts/arm/nordic/nrf54l15_cpuapp.dtsi new file mode 100644 index 000000000000..df4ccc522947 --- /dev/null +++ b/dts/arm/nordic/nrf54l15_cpuapp.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu: cpu@0 { + clock-frequency = ; + device_type = "cpu"; + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + itm: itm@e0000000 { + compatible = "arm,armv8m-itm"; + reg = <0xe0000000 0x1000>; + swo-ref-frequency = ; + }; + }; + }; + + clocks { + lfxo: lfxo { + compatible = "nordic,nrf-lfxo"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + hfxo: hfxo { + compatible = "nordic,nrf-hfxo"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + soc { + uicr: uicr@ffd000 { + compatible = "nordic,nrf-uicr"; + reg = <0xffd000 0x1000>; + }; + + ficr: ficr@ffc000 { + compatible = "nordic,nrf-ficr"; + reg = <0xffc000 0x1000>; + #nordic,ficr-cells = <1>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + peripheral@50000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x50000000 0x10000000>; + + /* Common nRF54L15 peripheral description */ + #include "nrf54l15_cpuapp_peripherals.dtsi" + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&rram_controller { + rram0: rram@0 { + /* + * "1524 KB non-volatile memory (RRAM) and 256 KB RAM" + * -- Product Specification + * NB: 1524 = 1.5 * 1024 - 12 + */ + reg = <0x0 DT_SIZE_K(1524)>; + }; +}; + +/* Disable by default to use GRTC */ +&systick { + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi new file mode 100644 index 000000000000..485d85829a46 --- /dev/null +++ b/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dppic00: dppic@42000 { + compatible = "nordic,nrf-dppic"; + reg = <0x42000 0x808>; + status = "disabled"; +}; + +spi00: spi@4a000 { + /* + * 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 = <0x4a000 0x1000>; + interrupts = <74 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart00: uart@4a000 { + compatible = "nordic,nrf-uarte"; + reg = <0x4a000 0x1000>; + interrupts = <74 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +gpio2: gpio@50400 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0x50400 0x300>; + #gpio-cells = <2>; + ngpios = <11>; + status = "disabled"; + port = <2>; +}; + +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>; + prescaler = <0>; +}; + +dppic10: dppic@82000 { + compatible = "nordic,nrf-dppic"; + reg = <0x82000 0x808>; + 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>; + 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; + + ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; +}; + +dppic20: dppic@c2000 { + compatible = "nordic,nrf-dppic"; + reg = <0xc2000 0x808>; + status = "disabled"; +}; + +i2c20: i2c@c6000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc6000 0x1000>; + clock-frequency = ; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +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>; + status = "disabled"; +}; + +uart20: uart@c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +i2c21: i2c@c7000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc7000 0x1000>; + clock-frequency = ; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +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>; + status = "disabled"; +}; + +uart21: uart@c7000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +i2c22: i2c@c8000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc8000 0x1000>; + clock-frequency = ; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +spi22: spi@c8000 { + /* + * 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 = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart22: uart@c8000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +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>; +}; + +nfct: nfct@d6000 { + compatible = "nordic,nrf-nfct"; + reg = <0xd6000 0x1000>; + interrupts = <214 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +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>; + interrupts = <219 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + instance = <20>; +}; + +i2s20: i2s@dd000 { + compatible = "nordic,nrf-i2s"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xdd000 0x1000>; + interrupts = <221 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +qdec20: qdec@e0000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe0000 0x1000>; + interrupts = <224 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +qdec21: qdec@e1000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe1000 0x1000>; + interrupts = <225 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +grtc: grtc@e2000 { + compatible = "nordic,nrf-grtc"; + reg = <0xe2000 0x1000>; + cc-num = <12>; + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +dppic30: dppic@102000 { + compatible = "nordic,nrf-dppic"; + reg = <0x102000 0x808>; + status = "disabled"; +}; + +i2c30: i2c@104000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x104000 0x1000>; + clock-frequency = ; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +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>; + status = "disabled"; +}; + +uart30: uart@104000 { + compatible = "nordic,nrf-uarte"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +wdt30: watchdog@108000 { + compatible = "nordic,nrf-wdt"; + reg = <0x108000 0x620>; + interrupts = <264 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +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>; + interrupts = <269 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + instance = <30>; +}; + +clock: clock@10e000 { + compatible = "nordic,nrf-clock"; + reg = <0x10e000 0x1000>; + interrupts = <270 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54l_common.dtsi b/dts/arm/nordic/nrf54l_common.dtsi new file mode 100644 index 000000000000..415f24711742 --- /dev/null +++ b/dts/arm/nordic/nrf54l_common.dtsi @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + rram_controller: rram-controller@5004b000 { + compatible = "nordic,rram-controller"; + reg = <0x5004b000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <75 NRF_DEFAULT_IRQ_PRIORITY>; + rram0: rram@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <1>; + }; + }; + }; + + chosen { + zephyr,flash-controller = &rram_controller; + }; + + sw_pwm: sw-pwm { + generator = <&timer21>; + }; +}; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index 460240111669..e65ce04a0042 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -28,6 +28,7 @@ }; chosen { + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -51,7 +52,7 @@ reg = <0x50840000 0x1000>, <0x50841000 0x1000>; reg-names = "wrapper", "core"; interrupts = <64 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; ctrlap: ctrlap@50006000 { @@ -60,11 +61,26 @@ status = "okay"; }; - gpiote: gpiote@5000d000 { + /* + * GPIOTE0 is always accessible as a secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote0: gpiote@5000d000 { compatible = "nordic,nrf-gpiote"; reg = <0x5000d000 0x1000>; interrupts = <13 5>; status = "disabled"; + instance = <0>; + }; + + /* Additional Non-Secure GPIOTE instance */ + gpiote1: gpiote@40031000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x40031000 0x1000>; + interrupts = <49 5>; + status = "disabled"; + instance = <1>; }; spu: spu@50003000 { @@ -77,6 +93,7 @@ ficr: ficr@ff0000 { compatible = "nordic,nrf-ficr"; reg = <0xff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -91,3 +108,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf9151_laca.dtsi b/dts/arm/nordic/nrf9151_laca.dtsi new file mode 100644 index 000000000000..9ed202740170 --- /dev/null +++ b/dts/arm/nordic/nrf9151_laca.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +/ { + soc { + compatible = "nordic,nrf9151-laca", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; + }; +}; diff --git a/dts/arm/nordic/nrf9151ns_laca.dtsi b/dts/arm/nordic/nrf9151ns_laca.dtsi new file mode 100644 index 000000000000..ac31c6e19c60 --- /dev/null +++ b/dts/arm/nordic/nrf9151ns_laca.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +/ { + soc { + compatible = "nordic,nrf9151-laca", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; + }; +}; diff --git a/dts/arm/nordic/nrf91_peripherals.dtsi b/dts/arm/nordic/nrf91_peripherals.dtsi index 2e437eb082dd..12e61743bfe1 100644 --- a/dts/arm/nordic/nrf91_peripherals.dtsi +++ b/dts/arm/nordic/nrf91_peripherals.dtsi @@ -313,6 +313,7 @@ gpio0: gpio@842500 { #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; rtc0: rtc@14000 { diff --git a/dts/arm/nordic/nrf91ns.dtsi b/dts/arm/nordic/nrf91ns.dtsi index 910f45ec7061..c692873981be 100644 --- a/dts/arm/nordic/nrf91ns.dtsi +++ b/dts/arm/nordic/nrf91ns.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -46,12 +46,17 @@ #include "nrf91_peripherals.dtsi" }; - /* Additional Non-Secure peripherals */ - gpiote: gpiote@40031000 { + /* + * GPIOTE1 is always accessible as a non-secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote1: gpiote@40031000 { compatible = "nordic,nrf-gpiote"; reg = <0x40031000 0x1000>; interrupts = <49 5>; status = "disabled"; + instance = <1>; }; }; @@ -64,3 +69,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/bindings/arm/nordic,nrf-uicr-v2.yaml b/dts/bindings/arm/nordic,nrf-uicr-v2.yaml new file mode 100644 index 000000000000..f509fdf40612 --- /dev/null +++ b/dts/bindings/arm/nordic,nrf-uicr-v2.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic UICR v2 (User Information Configuration Registers) + +compatible: "nordic,nrf-uicr-v2" + +include: base.yaml + +properties: + reg: + required: true + + domain: + type: int + required: true + description: | + Domain ID of the domain associated with this UICR instance. Must be unique + across all UICR instances in the system. + + ptr-ext-uicr: + type: phandle + required: true + description: | + Handle of a memory region reserved to contain an Extended UICR instance. + The address of that node will be stored in the UICR.PTREXTUICR register. diff --git a/dts/bindings/base/mutable.yaml b/dts/bindings/base/mutable.yaml new file mode 100644 index 000000000000..0e2d1cad3b04 --- /dev/null +++ b/dts/bindings/base/mutable.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +# Properties for Mutable devices + +properties: + zephyr,mutable: + type: boolean + description: | + True iff the device structure may be mutated. + + Inherit this binding for devices that are runtime-modifiable, in-place. + This places the device structure into SRAM rather than Flash. diff --git a/dts/bindings/clock/nordic,nrf-hfxo.yaml b/dts/bindings/clock/nordic,nrf-hfxo.yaml new file mode 100644 index 000000000000..cd82e1c34d3a --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hfxo.yaml @@ -0,0 +1,82 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF high-frequency crystal oscillator + +compatible: "nordic,nrf-hfxo" + +include: fixed-clock.yaml + +properties: + clock-frequency: + const: 32000000 + + load-capacitors: + type: string + enum: + - "internal" + - "external" + description: | + Type of load capacitors connected to the crystal. If not specified, + adjustments may still happen when the device trimming happens during + system initialization. + + load-capacitance-femtofarad: + type: int + enum: + - 4000 + - 4250 + - 4500 + - 4750 + - 5000 + - 5250 + - 5500 + - 5750 + - 6000 + - 6250 + - 6500 + - 6750 + - 7000 + - 7250 + - 7500 + - 7750 + - 8000 + - 8250 + - 8500 + - 8750 + - 9000 + - 9250 + - 9500 + - 9750 + - 10000 + - 10250 + - 10500 + - 10750 + - 11000 + - 11250 + - 11500 + - 11750 + - 12000 + - 12250 + - 12500 + - 12750 + - 13000 + - 13250 + - 13500 + - 13750 + - 14000 + - 14250 + - 14500 + - 14750 + - 15000 + - 15250 + - 15500 + - 15750 + - 16000 + - 16250 + - 16500 + - 16750 + - 17000 + description: | + Load capacitance in femtofarads. This property is only used when + load-capacitors is set to "internal". diff --git a/dts/bindings/clock/nordic,nrf-hsfll.yaml b/dts/bindings/clock/nordic,nrf-hsfll.yaml new file mode 100644 index 000000000000..3614d80870fa --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hsfll.yaml @@ -0,0 +1,65 @@ +# 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 + + nordic,ficrs: + required: true + + nordic,ficr-names: + required: true diff --git a/dts/bindings/clock/nordic,nrf-lfxo.yaml b/dts/bindings/clock/nordic,nrf-lfxo.yaml new file mode 100644 index 000000000000..328c374769ca --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-lfxo.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF low-frequency crystal oscillator + +compatible: "nordic,nrf-lfxo" + +include: fixed-clock.yaml + +properties: + clock-frequency: + const: 32768 + + load-capacitors: + type: string + enum: + - "internal" + - "external" + description: | + Type of load capacitors connected to the crystal. If not specified, + adjustments may still happen when the device trimming happens during + system initialization. + + load-capacitance-femtofarad: + type: int + enum: + - 4000 + - 4500 + - 5000 + - 5500 + - 6000 + - 6500 + - 7000 + - 7500 + - 8000 + - 8500 + - 9000 + - 9500 + - 10000 + - 10500 + - 11000 + - 11500 + - 12000 + - 12500 + - 13000 + - 13500 + - 14000 + - 14500 + - 15000 + - 15500 + - 16000 + - 16500 + - 17000 + - 17500 + - 18000 + description: | + Load capacitance in femtofarads. This property is only used when + load-capacitors is set to "internal". diff --git a/dts/bindings/cpu/nordic,vpr.yaml b/dts/bindings/cpu/nordic,vpr.yaml new file mode 100644 index 000000000000..11146f89c512 --- /dev/null +++ b/dts/bindings/cpu/nordic,vpr.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic Semiconductor RISC-V VPR CPU + +compatible: "nordic,vpr" + +include: riscv,cpus.yaml + +properties: + nordic,bus-width: + type: int + enum: + - 32 + - 64 + required: true + description: + Bus width of the CPU. diff --git a/dts/bindings/cpu/nuclei,bumblebee.yaml b/dts/bindings/cpu/nuclei,bumblebee.yaml index 8c9dfc7d35d8..96eebcd0fb8d 100644 --- a/dts/bindings/cpu/nuclei,bumblebee.yaml +++ b/dts/bindings/cpu/nuclei,bumblebee.yaml @@ -6,9 +6,3 @@ description: Nuclei Bumblebee RISC-V Core compatible: "nuclei,bumblebee" include: riscv,cpus.yaml - -properties: - mcause-exception-mask: - type: int - required: true - description: Specify the bits to use for exception code in mcause register. diff --git a/dts/bindings/gpio/nordic,nrf-gpio.yaml b/dts/bindings/gpio/nordic,nrf-gpio.yaml index 550acd1a865c..097a99d8fa94 100644 --- a/dts/bindings/gpio/nordic,nrf-gpio.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpio.yaml @@ -11,6 +11,11 @@ properties: reg: required: true + gpiote-instance: + type: phandle + description: | + GPIOTE instance that can be used with this GPIO port. + "#gpio-cells": const: 2 diff --git a/dts/bindings/gpio/nordic,nrf-gpiote.yaml b/dts/bindings/gpio/nordic,nrf-gpiote.yaml index 49ddba3595ba..4bb09574e9b9 100644 --- a/dts/bindings/gpio/nordic,nrf-gpiote.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpiote.yaml @@ -5,7 +5,9 @@ description: NRF5 GPIOTE node compatible: "nordic,nrf-gpiote" -include: base.yaml +include: + - base.yaml + - nordic,split-channels.yaml properties: reg: @@ -13,3 +15,15 @@ properties: interrupts: required: true + + instance: + type: int + required: true + description: | + The GPIOTE instance number. GPIOTE instance GPIOTE0 has: + + instance = <0>; + + And GPIOTE1 has: + + instance = <1>; diff --git a/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml b/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml new file mode 100644 index 000000000000..f570e668ea50 --- /dev/null +++ b/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic VPR CLIC + +compatible: "nordic,nrf-clic" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/arm/nordic,nrf-ficr.yaml b/dts/bindings/misc/nordic,nrf-ficr.yaml similarity index 61% rename from dts/bindings/arm/nordic,nrf-ficr.yaml rename to dts/bindings/misc/nordic,nrf-ficr.yaml index bea0762573eb..ca199c24f078 100644 --- a/dts/bindings/arm/nordic,nrf-ficr.yaml +++ b/dts/bindings/misc/nordic,nrf-ficr.yaml @@ -7,3 +7,11 @@ include: base.yaml properties: reg: required: true + + "#nordic,ficr-cells": + type: int + required: true + const: 1 + +nordic,ficr-cells: + - offset diff --git a/dts/bindings/misc/nordic,split-channels.yaml b/dts/bindings/misc/nordic,split-channels.yaml new file mode 100644 index 000000000000..a875dc12d7f3 --- /dev/null +++ b/dts/bindings/misc/nordic,split-channels.yaml @@ -0,0 +1,44 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: | + Nordic Split Channels + + Some of Nordic's peripherals support split ownership feature that allows to + be used by independent owners. As an example the configuration of the + Global Real Time Counter (GRTC) is shown below: + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + child-owned-channels = <7 8 9 10 11>; + + Which means that channels 0-11 will be assigned to the particular CPU. + Other CPUs cannot use those and another set must be defined for them. + In addition, `child-owned-channels` property allows to use channels + 7-11 only by child subprocessor. If the CPU you're configuring has no + subprocessor(s) assigned, the `child-owned-channels` property + should not be defined. + +properties: + owned-channels: + type: array + description: | + List of channels in a split-ownership peripheral that are to be owned + for use by the compiled CPU. + + nonsecure-channels: + type: array + description: | + List of channels in a split-ownership, split-security peripheral that + are to be configured as nonsecure. In Trustzone systems, this property + is only evaluated for secure peripherals, as nonsecure channels are + implicitly specified through the owned-channels property. This property + is ignored in non-Trustzone systems. + + child-owned-channels: + type: array + description: | + List of channels in a split-ownership peripheral that are officially + owned by the compiled CPU but intended to be used by its child + subprocessor(s). diff --git a/dts/bindings/misc/nordic-nrf-ficr-client.yaml b/dts/bindings/misc/nordic-nrf-ficr-client.yaml new file mode 100644 index 000000000000..06a1e727f3fc --- /dev/null +++ b/dts/bindings/misc/nordic-nrf-ficr-client.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +properties: + nordic,ficrs: + type: phandle-array + description: | + FICR entries, e.g. <&ficr OFFSET>. Available offsets (or FICR entries) are + available at . + + nordic,ficr-names: + type: string-array + description: | + Names of each nordic,ficrs entry. diff --git a/dts/bindings/misc/zephyr,devmux.yaml b/dts/bindings/misc/zephyr,devmux.yaml new file mode 100644 index 000000000000..744daaca120a --- /dev/null +++ b/dts/bindings/misc/zephyr,devmux.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +description: Generic Device Multiplexer + +compatible: "zephyr,devmux" + +include: [base.yaml, mutable.yaml] + +properties: + + devices: + type: phandles + required: true + description: | + Devices to be multiplexed. + + selected: + type: int + default: 0 + description: | + Initial multiplexer selection. + + This must be in the range [0, N-1], where N is the length of the + 'devices' phandle list. + + If unspecified, the default selection is zero in order to ensure that + the multiplexer is ready for use (i.e. one of the [0, N-1] multiplexed + devices is selected). Zero is, necessarily, the only possible valid + default value since the phandle list must have length >= 1. + + Note: Specifying a value of 'selected' outside the range [0, N-1] + results in a compile-time error. diff --git a/dts/bindings/mtd/nordic,mram.yaml b/dts/bindings/mtd/nordic,mram.yaml new file mode 100644 index 000000000000..dac7d14305d6 --- /dev/null +++ b/dts/bindings/mtd/nordic,mram.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic MRAM + +compatible: nordic,mram + +include: soc-nv-flash.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/mtd/nordic,owned-partitions.yaml b/dts/bindings/mtd/nordic,owned-partitions.yaml new file mode 100644 index 000000000000..bf42c13346ae --- /dev/null +++ b/dts/bindings/mtd/nordic,owned-partitions.yaml @@ -0,0 +1,89 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Owned Partitions + + Memory partition table with permission attributes common to its partitions. + This is a special case of the Nordic Owned Memory binding. + + Every compatible node is expected to be a child of a memory node, where the + listed partitions belong. + + A single memory node can contain multiple partition tables, each with a + different set of permissions. For each such table, the smallest memory region + spanning the contained partitions will be recorded in the UICR. These regions + are allowed to contain gaps between the partitions, but this is discouraged. + + Example: + + mram1x: mram@e000000 { + compatible = "nordic,mram"; + reg = <0xe000000 0x200000>; + ... + + rx-partitions { + compatible = "nordic,owned-partitions"; + perm-read; + perm-execute; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@c0000 { + label = "image-0"; + reg = <0xc0000 0x40000>; + }; + }; + + rw-partitions { + compatible = "nordic,owned-partitions"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x100000 0x50000>; + }; + storage_partition: partition@150000 { + label = "storage"; + reg = <0x150000 0x6000>; + }; + }; + }; + + From this example, two memory regions will be inferred: + + - 0x0E0C0000--0x0E100000, with read & execute permissions, containing the + partition labeled "image-0". + - 0x0E100000--0x0E156000, with read & write permissions, containing the + partitions labeled "image-1" and "storage". + +compatible: "nordic,owned-partitions" + +include: + - name: nordic,owned-memory.yaml + property-blocklist: + - reg + +properties: + "#address-cells": + required: true + + "#size-cells": + required: true + +child-binding: + description: | + Partitions in the table are defined as subnodes. Each partition must have a + size and an offset relative to the base address of the parent memory node. + + include: + - name: base.yaml + property-blocklist: + - compatible + + properties: + reg: + required: true diff --git a/dts/bindings/options/openthread,config.yaml b/dts/bindings/options/openthread,config.yaml index 054107fab44f..6366c289c805 100644 --- a/dts/bindings/options/openthread,config.yaml +++ b/dts/bindings/options/openthread,config.yaml @@ -10,6 +10,7 @@ description: | compatible = "openthread,config"; diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>, <&gpio1 0 GPIO_ACTIVE_LOW>; + bootloader-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; }; @@ -21,3 +22,9 @@ properties: description: | This enables access to diagnostic GPIO pins. Each field consists of GPIO pin's configuration: controller's phandle, pin number and configuration flags. + + bootloader-gpios: + type: phandle-array + description: | + This enables resetting to bootloader by triggering given GPIO pin. Property represents + chosen GPIO pin's configuration: controller's phandle, pin number and configuration flags. diff --git a/dts/bindings/reserved-memory/nordic,owned-memory.yaml b/dts/bindings/reserved-memory/nordic,owned-memory.yaml new file mode 100644 index 000000000000..9b13c965ac82 --- /dev/null +++ b/dts/bindings/reserved-memory/nordic,owned-memory.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Owned Memory + + Memory region with permission attributes. Each enabled region of this kind + will be recorded in the UICR of the compiled domain. Memory ownership and + access is then configured for the domain at boot time, based on the UICR. + +compatible: "nordic,owned-memory" + +include: base.yaml + +properties: + reg: + required: true + + owner-id: + type: int + description: | + Owner ID of the domain that will own this memory region. If not defined, + the ownership will default to the domain being compiled. + + Note: owner ID is not the same as domain ID; see the product specification + for details. + + perm-read: + type: boolean + description: Owner has read access to the region. + + perm-write: + type: boolean + description: Owner has write access to the region. + + perm-execute: + type: boolean + description: Owner can execute code from the region. + + perm-secure: + type: boolean + description: Owner has secure-only access to the region. + + non-secure-callable: + type: boolean + description: Memory region is used for non-secure-callable code. diff --git a/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml b/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml new file mode 100644 index 000000000000..6be94dce25d8 --- /dev/null +++ b/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +compatible: "nordic,nrf-vpr-coprocessor" + +description: | + VPR coprocessor + + VPR is a RISC-V CPU implementation. VPR instances are exposed to other CPUs as + peripherals. + +include: base.yaml + +properties: + cpu: + type: int + description: | + Processor ID of the VPR core. + + execution-memory: + type: phandle + required: true + description: | + Memory area from which the VPR core will execute. + + source-memory: + type: phandle + description: | + Memory area or partition from which the VPR code will be loaded. diff --git a/dts/bindings/timer/nordic,nrf-grtc.yaml b/dts/bindings/timer/nordic,nrf-grtc.yaml new file mode 100644 index 000000000000..e78e57df97e2 --- /dev/null +++ b/dts/bindings/timer/nordic,nrf-grtc.yaml @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Nordic GRTC (Global RTC) + +compatible: "nordic,nrf-grtc" + +include: + - "base.yaml" + - "nordic,split-channels.yaml" + +properties: + reg: + required: true + + interrupts: + required: true + + cc-num: + description: Number of capture/compare channels + type: int + required: true diff --git a/dts/common/nordic/nrf54h20_enga.dtsi b/dts/common/nordic/nrf54h20_enga.dtsi new file mode 100644 index 000000000000..1b8f7b6f9e81 --- /dev/null +++ b/dts/common/nordic/nrf54h20_enga.dtsi @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +/delete-node/ &sw_pwm; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpuapp: cpu@2 { + compatible = "arm,cortex-m33"; + reg = <2>; + device_type = "cpu"; + clock-frequency = ; + }; + + cpurad: cpu@3 { + compatible = "arm,cortex-m33"; + reg = <3>; + device_type = "cpu"; + clock-frequency = ; + }; + + cpuppr: cpu@d { + compatible = "nordic,vpr"; + reg = <13>; + device_type = "cpu"; + clock-frequency = ; + riscv,isa = "rv32emc"; + nordic,bus-width = <32>; + }; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + cpurad_uicr_ext: memory@e1ff000 { + reg = <0xe1ff000 DT_SIZE_K(2)>; + }; + + cpuapp_uicr_ext: memory@e1ff800 { + reg = <0xe1ff800 DT_SIZE_K(2)>; + }; + }; + + clocks { + fll16m: fll16m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + mram1x: mram@e000000 { + compatible = "nordic,mram"; + reg = <0xe000000 DT_SIZE_K(2048)>; + write-block-size = <16>; + }; + + cpuapp_uicr: uicr@fff8000 { + compatible = "nordic,nrf-uicr-v2"; + reg = <0xfff8000 DT_SIZE_K(2)>; + domain = <2>; + ptr-ext-uicr = <&cpuapp_uicr_ext>; + }; + + cpurad_uicr: uicr@fffa000 { + compatible = "nordic,nrf-uicr-v2"; + reg = <0xfffa000 DT_SIZE_K(2)>; + domain = <3>; + ptr-ext-uicr = <&cpurad_uicr_ext>; + }; + + ficr: ficr@fffe000 { + compatible = "nordic,nrf-ficr"; + reg = <0xfffe000 DT_SIZE_K(2)>; + #nordic,ficr-cells = <1>; + }; + + cpuapp_ram0: sram@22000000 { + compatible = "mmio-sram"; + reg = <0x22000000 DT_SIZE_K(32)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x22000000 0x8000>; + }; + + cpurad_ram0: sram@23000000 { + compatible = "mmio-sram"; + reg = <0x23000000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x23000000 0x10000>; + }; + + cpuapp_peripherals: peripheral@52000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x52000000 0x1000000>; + + cpuapp_hsfll: clock@d000 { + compatible = "nordic,nrf-hsfll"; + #clock-cells = <0>; + reg = <0xd000 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"; + }; + }; + + cpurad_peripherals: peripheral@53000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x53000000 0x1000000>; + + cpurad_hsfll: clock@d000 { + compatible = "nordic,nrf-hsfll"; + #clock-cells = <0>; + reg = <0xd000 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_1>, + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_1>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + }; + + global_peripherals: peripheral@5f000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x5f000000 0x1000000>; + + cpuppr_vpr: vpr@908000 { + compatible = "nordic,nrf-vpr-coprocessor"; + reg = <0x908000 0x1000>; + status = "disabled"; + cpu = <13>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x908000 0x4000>; + + cpuppr_clic: interrupt-controller@1000 { + compatible = "nordic,nrf-clic"; + reg = <0x1000 0x3000>; + status = "disabled"; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; + + gpiote130: gpiote@934000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x934000 0x1000>; + status = "disabled"; + instance = <130>; + }; + + gpio0: gpio@938000 { + compatible = "nordic,nrf-gpio"; + reg = <0x938000 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <0>; + }; + + gpio1: gpio@938200 { + compatible = "nordic,nrf-gpio"; + reg = <0x938200 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <1>; + }; + + gpio2: gpio@938400 { + compatible = "nordic,nrf-gpio"; + reg = <0x938400 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <2>; + }; + + gpio6: gpio@938c00 { + compatible = "nordic,nrf-gpio"; + reg = <0x938c00 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + ngpios = <14>; + port = <6>; + }; + + gpio7: gpio@938e00 { + compatible = "nordic,nrf-gpio"; + reg = <0x938e00 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + ngpios = <8>; + port = <7>; + }; + + gpio9: gpio@939200 { + compatible = "nordic,nrf-gpio"; + reg = <0x939200 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <6>; + port = <9>; + }; + + grtc: grtc@99c000 { + compatible = "nordic,nrf-grtc"; + reg = <0x99c000 0x1000>; + status = "disabled"; + cc-num = <16>; + }; + + uart135: uart@9c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9c6000 0x1000>; + status = "disabled"; + current-speed = <115200>; + interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + uart136: uart@9d5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9d5000 0x1000>; + status = "disabled"; + current-speed = <115200>; + interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; + }; + }; + }; + + cpuapp_ppb: cpuapp-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + + cpuapp_nvic: interrupt-controller@e000e100 { + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; + + cpurad_ppb: cpurad-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpurad_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + + cpurad_nvic: interrupt-controller@e000e100 { + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; +}; diff --git a/dts/arm/nordic/nrf_common.dtsi b/dts/common/nordic/nrf_common.dtsi similarity index 86% rename from dts/arm/nordic/nrf_common.dtsi rename to dts/common/nordic/nrf_common.dtsi index 8aec8dd0c89e..cb2df6bcccd9 100644 --- a/dts/arm/nordic/nrf_common.dtsi +++ b/dts/common/nordic/nrf_common.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -43,11 +44,3 @@ #pwm-cells = <3>; }; }; - -&systick { - /* - * Nordic SoCs rely by default on the RTC for system clock - * implementation, so the SysTick node is not to be enabled. - */ - status = "disabled"; -}; diff --git a/dts/riscv/gigadevice/gd32vf103.dtsi b/dts/riscv/gigadevice/gd32vf103.dtsi index c9f37db51809..b52aee61fbc3 100644 --- a/dts/riscv/gigadevice/gd32vf103.dtsi +++ b/dts/riscv/gigadevice/gd32vf103.dtsi @@ -23,7 +23,6 @@ cpu: cpu@0 { clock-frequency = ; - mcause-exception-mask = <0x7ff>; compatible = "nuclei,bumblebee"; riscv,isa = "rv32imac_zicsr_zifencei"; reg = <0>; diff --git a/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi b/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi new file mode 100644 index 000000000000..d42a815a4b2d --- /dev/null +++ b/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuppr {}; +clic: &cpuppr_clic {}; + +/delete-node/ &cpuapp; +/delete-node/ &cpuapp_peripherals; +/delete-node/ &cpuapp_ppb; +/delete-node/ &cpuapp_ram0; +/delete-node/ &cpurad; +/delete-node/ &cpurad_peripherals; +/delete-node/ &cpurad_ppb; +/delete-node/ &cpurad_ram0; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuppr_clic>; + ranges; + }; +}; + +&gpiote130 { + interrupts = <104 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <108 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 13c2747f5a30..5050c778627e 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -26,6 +26,35 @@ #endif #define RAMABLE_REGION RAM +#if USE_PARTITION_MANAGER + +#include + +#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) +/* We are linking against S1, create symbol containing the flash ID of S0. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S0_ID; + +#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ + +#ifdef PM_S1_ID +/* We are linking against S0, create symbol containing the flash ID of S1. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S1_ID; +#endif /* PM_S1_ID */ + +#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ + +#define ROM_ADDR PM_ADDRESS +#define ROM_SIZE PM_SIZE + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -52,6 +81,23 @@ #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif +#endif /* USE_PARTITION_MANAGER */ + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) +#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) +#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) +#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) +#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) +#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) +#endif + #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/arch/riscv/arch.h b/include/zephyr/arch/riscv/arch.h index 99bccb74a08a..bbde28bdfbe3 100644 --- a/include/zephyr/arch/riscv/arch.h +++ b/include/zephyr/arch/riscv/arch.h @@ -26,7 +26,6 @@ #endif /* CONFIG_USERSPACE */ #include #include -#include #include #include #include @@ -300,7 +299,7 @@ static inline uint64_t arch_k_cycle_get_64(void) #endif /*_ASMLANGUAGE */ -#if defined(CONFIG_SOC_FAMILY_RISCV_PRIVILEGED) +#if defined(CONFIG_RISCV_PRIVILEGED) #include #endif diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index eb5c47824413..128f823c4dfe 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -11,7 +11,6 @@ * Generic Linker script for the riscv platform */ -#include #include #include diff --git a/include/zephyr/arch/riscv/irq.h b/include/zephyr/arch/riscv/irq.h index 77c0d4057aaf..fa4b3989f05a 100644 --- a/include/zephyr/arch/riscv/irq.h +++ b/include/zephyr/arch/riscv/irq.h @@ -14,16 +14,39 @@ #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ #define ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ -#ifndef _ASMLANGUAGE - #ifdef __cplusplus extern "C" { #endif +#ifndef _ASMLANGUAGE #include #include #include -#include +#endif /* !_ASMLANGUAGE */ + +/* Exceptions 0-15 (MCAUSE interrupt=0) */ + +/* Environment Call from U-mode */ +#define RISCV_EXC_ECALLU 8 +/** Environment Call from M-mode */ +#define RISCV_EXC_ECALLM 11 + +/* IRQs 0-15 (MCAUSE interrupt=1) */ + +/** Machine Software Interrupt */ +#define RISCV_IRQ_MSOFT 3 +/** Machine External Interrupt */ +#define RISCV_IRQ_MEXT 11 + +#ifdef CONFIG_64BIT +#define RISCV_MCAUSE_IRQ_POS 63U +#define RISCV_MCAUSE_IRQ_BIT BIT64(RISCV_MCAUSE_IRQ_POS) +#else +#define RISCV_MCAUSE_IRQ_POS 31U +#define RISCV_MCAUSE_IRQ_BIT BIT(RISCV_MCAUSE_IRQ_POS) +#endif + +#ifndef _ASMLANGUAGE extern void arch_irq_enable(unsigned int irq); extern void arch_irq_disable(unsigned int irq); @@ -76,7 +99,7 @@ static inline void arch_isr_direct_footer(int swap) /* Get the IRQ number */ __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; /* Clear the pending IRQ */ __soc_handle_irq(mcause); @@ -102,10 +125,10 @@ static inline void arch_isr_direct_footer(int swap) } \ static inline int name##_body(void) +#endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif -#endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */ diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 17bac991f186..03f451a3c8b7 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -209,6 +209,7 @@ enum bt_audio_metadata_type { ((struct bt_audio_codec_cfg){ \ /* Use HCI data path as default, can be overwritten by application */ \ .path_id = BT_ISO_DATA_PATH_HCI, \ + .ctlr_transcode = false, \ .id = _id, \ .cid = _cid, \ .vid = _vid, \ @@ -231,6 +232,7 @@ enum bt_audio_metadata_type { ((struct bt_audio_codec_cap){ \ /* Use HCI data path as default, can be overwritten by application */ \ .path_id = BT_ISO_DATA_PATH_HCI, \ + .ctlr_transcode = false, \ .id = (_id), \ .cid = (_cid), \ .vid = (_vid), \ @@ -316,6 +318,12 @@ struct bt_audio_codec_cap { * vendor specific ID. */ uint8_t path_id; + /** Whether or not the local controller should transcode + * + * This effectively sets the coding format for the ISO data path to @ref + * BT_HCI_CODING_FORMAT_TRANSPARENT if false, else uses the @ref bt_audio_codec_cfg.id. + */ + bool ctlr_transcode; /** Codec ID */ uint8_t id; /** Codec Company ID */ @@ -344,6 +352,12 @@ struct bt_audio_codec_cfg { * vendor specific ID. */ uint8_t path_id; + /** Whether or not the local controller should transcode + * + * This effectively sets the coding format for the ISO data path to @ref + * BT_HCI_CODING_FORMAT_TRANSPARENT if false, else uses the @ref bt_audio_codec_cfg.id. + */ + bool ctlr_transcode; /** Codec ID */ uint8_t id; /** Codec Company ID */ diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 09b8321d685d..bdc644d82e9c 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -479,6 +479,42 @@ struct bt_conn_le_tx_power { int8_t max_level; }; + +/** LE Transmit Power Reporting Structure */ +struct bt_conn_le_tx_power_report { + + /** Reason for Transmit power reporting, + * as documented in Core Spec. Version 5.4 Vol. 4, Part E, 7.7.65.33. + */ + uint8_t reason; + + /** Phy of Transmit power reporting. */ + enum bt_conn_le_tx_power_phy phy; + + /** Transmit power level + * - 0xXX - Transmit power level + * + Range: -127 to 20 + * + Units: dBm + * + * - 0x7E - Remote device is not managing power levels on this PHY. + * - 0x7F - Transmit power level is not available + */ + int8_t tx_power_level; + + /** Bit 0: Transmit power level is at minimum level. + * Bit 1: Transmit power level is at maximum level. + */ + uint8_t tx_power_level_flag; + + /** Change in transmit power level + * - 0xXX - Change in transmit power level (positive indicates increased + * power, negative indicates decreased power, zero indicates unchanged) + * Units: dB + * - 0x7F - Change is not available or is out of range. + */ + int8_t delta; +}; + /** @brief Passkey Keypress Notification type * * The numeric values are the same as in the Core specification for Pairing @@ -530,6 +566,41 @@ int bt_conn_get_remote_info(struct bt_conn *conn, 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 tx_power Transmit power level descriptor. + * + * @return Zero on success or (negative) error code on failure. + * @retval -ENOBUFS HCI command buffer is not available. + */ +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 phy PHY information. + * + * @return Zero on success or (negative) error code on failure. + * @retval -ENOBUFS HCI command buffer is not available. + */ +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 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. + */ +int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, + bool local_enable, + bool remote_enable); + /** @brief Update the connection parameters. * * If the local device is in the peripheral role then updating the connection @@ -1052,6 +1123,22 @@ struct bt_conn_cb { const struct bt_df_conn_iq_samples_report *iq_report); #endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + /** @brief LE Read Remote Transmit Power Level procedure has completed or LE + * Transmit Power Reporting event. + * + * This callback notifies the application that either the remote transmit power level + * has been read from the peer or transmit power level has changed for the local or + * remote controller when transmit power reporting is enabled for the respective side + * using @ref bt_conn_le_set_tx_power_report_enable. + * + * @param conn Connection object. + * @param report Transmit power report. + */ + void (*tx_power_report)(struct bt_conn *conn, + const struct bt_conn_le_tx_power_report *report); +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + struct bt_conn_cb *_next; }; diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index c53422648f00..eb38f765afbc 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -235,6 +235,37 @@ struct bt_gatt_cb { sys_snode_t node; }; +/** @brief GATT authorization callback structure. */ +struct bt_gatt_authorization_cb { + /** @brief Authorize the GATT read operation. + * + * This callback allows the application to authorize the GATT + * read operation for the attribute that is being read. + * + * @param conn Connection object. + * @param attr The attribute that is being read. + * + * @retval true Authorize the operation and allow it to execute. + * @retval false Reject the operation and prevent it from executing. + */ + bool (*read_operation_authorize)(struct bt_conn *conn, + const struct bt_gatt_attr *attr); + + /** @brief Authorize the GATT write operation. + * + * This callback allows the application to authorize the GATT + * write operation for the attribute that is being written. + * + * @param conn Connection object. + * @param attr The attribute that is being written. + * + * @retval true Authorize the operation and allow it to execute. + * @retval false Reject the operation and prevent it from executing. + */ + bool (*write_operation_authorize)(struct bt_conn *conn, + const struct bt_gatt_attr *attr); +}; + /** Characteristic Properties Bit field values */ /** @@ -377,6 +408,26 @@ struct bt_gatt_cpf { */ void bt_gatt_cb_register(struct bt_gatt_cb *cb); +/** @brief Register GATT authorization callbacks. + * + * Register callbacks to perform application-specific authorization of GATT + * operations on all registered GATT attributes. The callback structure must + * remain valid throughout the entire duration of the Bluetooth subsys + * activity. + * + * The @kconfig{CONFIG_BT_GATT_AUTHORIZATION_CUSTOM} Kconfig must be enabled + * to make this API functional. + * + * This API allows the user to register only one callback structure + * concurrently. Passing NULL unregisters the previous set of callbacks + * and makes it possible to register a new one. + * + * @param cb Callback struct. + * + * @return Zero on success or negative error code otherwise + */ +int bt_gatt_authorization_cb_register(const struct bt_gatt_authorization_cb *cb); + /** @brief Register GATT service. * * Register GATT service. Applications can make use of diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 4d637bbe4e28..f1cb92f372c5 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -571,6 +571,35 @@ struct bt_hci_rp_read_tx_power_level { int8_t tx_power_level; } __packed; +#define BT_HCI_LE_TX_POWER_PHY_1M 0x01 +#define BT_HCI_LE_TX_POWER_PHY_2M 0x02 +#define BT_HCI_LE_TX_POWER_PHY_CODED_S8 0x03 +#define BT_HCI_LE_TX_POWER_PHY_CODED_S2 0x04 +#define BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL BT_OP(BT_OGF_LE, 0x0076) +struct bt_hci_cp_le_read_tx_power_level { + uint16_t handle; + uint8_t phy; +} __packed; + +struct bt_hci_rp_le_read_tx_power_level { + uint8_t status; + uint16_t handle; + uint8_t phy; + int8_t current_tx_power_level; + int8_t max_tx_power_level; +} __packed; + +#define BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL BT_OP(BT_OGF_LE, 0x0077) + +#define BT_HCI_LE_TX_POWER_REPORT_DISABLE 0x00 +#define BT_HCI_LE_TX_POWER_REPORT_ENABLE 0x01 +#define BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE BT_OP(BT_OGF_LE, 0x007A) +struct bt_hci_cp_le_set_tx_power_report_enable { + uint16_t handle; + uint8_t local_enable; + uint8_t remote_enable; +} __packed; + #define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00 #define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01 #define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031) @@ -2905,6 +2934,26 @@ struct bt_hci_evt_le_req_peer_sca_complete { uint8_t sca; } __packed; +/** Reason for Transmit power reporting. + */ +/* Local Transmit power changed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_LOCAL_CHANGED 0x00 +/* Remote Transmit power changed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_REMOTE_CHANGED 0x01 +/* HCI_LE_Read_Remote_Transmit_Power_Level command completed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_READ_REMOTE_COMPLETED 0x02 + +#define BT_HCI_EVT_LE_TRANSMIT_POWER_REPORT 0x21 +struct bt_hci_evt_le_transmit_power_report { + uint8_t status; + uint16_t handle; + uint8_t reason; + uint8_t phy; + int8_t tx_power_level; + uint8_t tx_power_level_flag; + int8_t delta; +} __packed; + #define BT_HCI_EVT_LE_BIGINFO_ADV_REPORT 0x22 struct bt_hci_evt_le_biginfo_adv_report { uint16_t sync_handle; diff --git a/include/zephyr/bluetooth/mesh.h b/include/zephyr/bluetooth/mesh.h index a4ef70dc6ded..fc84814fa442 100644 --- a/include/zephyr/bluetooth/mesh.h +++ b/include/zephyr/bluetooth/mesh.h @@ -1,5 +1,5 @@ /** @file - * @brief Bluetooth mesh Profile APIs. + * @brief Bluetooth Mesh Profile APIs. */ /* diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 817fba918eff..a236ede525d8 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -713,6 +713,8 @@ struct bt_mesh_model_pub { uint8_t period_div:4, /**< Divisor for the Period. */ count:4; /**< Transmissions left. */ + uint8_t delayable:1; /**< Use random delay for publishing. */ + uint32_t period_start; /**< Start of the current period. */ /** @brief Publication buffer, containing the publication message. @@ -1011,7 +1013,7 @@ const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod); * if no SIG model with the given ID exists in the given element. */ const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, - uint16_t id); + uint16_t id); /** @brief Find a vendor model. * @@ -1023,7 +1025,7 @@ const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, * if no vendor model with the given ID exists in the given element. */ const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, - uint16_t company, uint16_t id); + uint16_t company, uint16_t id); /** @brief Get whether the model is in the primary element of the device. * diff --git a/include/zephyr/bluetooth/mesh/blob_cli.h b/include/zephyr/bluetooth/mesh/blob_cli.h index 8e239b314571..9b591cfdd350 100644 --- a/include/zephyr/bluetooth/mesh/blob_cli.h +++ b/include/zephyr/bluetooth/mesh/blob_cli.h @@ -265,10 +265,10 @@ struct blob_cli_broadcast_ctx { void (*send)(struct bt_mesh_blob_cli *cli, uint16_t dst); /** Called after every @ref blob_cli_broadcast_ctx::send callback. */ void (*send_complete)(struct bt_mesh_blob_cli *cli, uint16_t dst); - /** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes - * have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called - * after transmission has been completed. - */ + /** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes + * have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called + * after transmission has been completed. + */ void (*next)(struct bt_mesh_blob_cli *cli); /** If true, every transmission needs to be confirmed by @ref blob_cli_broadcast_rsp before * @ref blob_cli_broadcast_ctx::next is called. diff --git a/include/zephyr/bluetooth/mesh/blob_srv.h b/include/zephyr/bluetooth/mesh/blob_srv.h index bf807bad92fb..92c809bd6b5b 100644 --- a/include/zephyr/bluetooth/mesh/blob_srv.h +++ b/include/zephyr/bluetooth/mesh/blob_srv.h @@ -108,7 +108,7 @@ struct bt_mesh_blob_srv_cb { /** @brief Transfer recovery callback. * - * Called when the Bluetooth mesh subsystem is started if the device is rebooted + * Called when the Bluetooth Mesh subsystem is started if the device is rebooted * in the middle of a transfer. * * Transfers will not be resumed after a reboot if this callback is not diff --git a/include/zephyr/bluetooth/mesh/cdb.h b/include/zephyr/bluetooth/mesh/cdb.h index 800ae07edc49..8ea35ec2e55a 100644 --- a/include/zephyr/bluetooth/mesh/cdb.h +++ b/include/zephyr/bluetooth/mesh/cdb.h @@ -231,7 +231,7 @@ enum { * or BT_MESH_CDB_ITER_STOP to stop. */ typedef uint8_t (*bt_mesh_cdb_node_func_t)(struct bt_mesh_cdb_node *node, - void *user_data); + void *user_data); /** @brief Node iterator. * diff --git a/include/zephyr/bluetooth/mesh/cfg.h b/include/zephyr/bluetooth/mesh/cfg.h index 7d1ca4e868f5..9bfd067da9b8 100644 --- a/include/zephyr/bluetooth/mesh/cfg.h +++ b/include/zephyr/bluetooth/mesh/cfg.h @@ -26,7 +26,7 @@ extern "C" { #endif -/** Bluetooth mesh feature states */ +/** Bluetooth Mesh feature states */ enum bt_mesh_feat_state { /** Feature is supported, but disabled. */ BT_MESH_FEATURE_DISABLED, diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index 0e8c26131ffe..4aca0c17451d 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -96,8 +96,8 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing subscription addresses. */ void (*mod_sub_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t elem_addr, uint16_t mod_id, uint16_t cid, - struct net_buf_simple *buf); + uint16_t elem_addr, uint16_t mod_id, uint16_t cid, + struct net_buf_simple *buf); /** @brief Optional callback for Node Reset Status messages. * @@ -128,7 +128,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*ttl_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for Friend Status messages. * @@ -139,7 +139,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*friend_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for GATT Proxy Status messages. * @@ -150,7 +150,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*gatt_proxy_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for Network Transmit Status messages. * @@ -199,7 +199,7 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*net_key_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - struct net_buf_simple *buf); + struct net_buf_simple *buf); /** @brief Optional callback for AppKey Status messages. * @@ -229,7 +229,7 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*app_key_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t net_idx, struct net_buf_simple *buf); + uint16_t net_idx, struct net_buf_simple *buf); /** @brief Optional callback for Model App Status messages. * @@ -262,8 +262,8 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*mod_app_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t elem_addr, uint16_t mod_id, uint16_t cid, - struct net_buf_simple *buf); + uint16_t elem_addr, uint16_t mod_id, uint16_t cid, + struct net_buf_simple *buf); /** @brief Optional callback for Node Identity Status messages. * @@ -326,7 +326,7 @@ struct bt_mesh_cfg_cli_cb { * @param sub HB subscription configuration parameters. */ void (*hb_sub_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - struct bt_mesh_cfg_cli_hb_sub *sub); + struct bt_mesh_cfg_cli_hb_sub *sub); }; /** Mesh Configuration Client Model Context */ diff --git a/include/zephyr/bluetooth/mesh/dfu_cli.h b/include/zephyr/bluetooth/mesh/dfu_cli.h index 3cbc220d825d..ad8881ebc26e 100644 --- a/include/zephyr/bluetooth/mesh/dfu_cli.h +++ b/include/zephyr/bluetooth/mesh/dfu_cli.h @@ -9,7 +9,7 @@ * @defgroup bt_mesh_dfu_cli Firmware Uppdate Client model * @ingroup bt_mesh_dfu * @{ - * @brief API for the Bluetooth mesh Firmware Update Client model + * @brief API for the Bluetooth Mesh Firmware Update Client model */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__ diff --git a/include/zephyr/bluetooth/mesh/dfu_metadata.h b/include/zephyr/bluetooth/mesh/dfu_metadata.h index bec65897ac73..21d032236a7e 100644 --- a/include/zephyr/bluetooth/mesh/dfu_metadata.h +++ b/include/zephyr/bluetooth/mesh/dfu_metadata.h @@ -6,10 +6,10 @@ /** * @file - * @defgroup bt_mesh_dfu_metadata Bluetooth mesh Device Firmware Update (DFU) metadata + * @defgroup bt_mesh_dfu_metadata Bluetooth Mesh Device Firmware Update (DFU) metadata * @ingroup bt_mesh_dfu * @{ - * @brief Common types and functions for the Bluetooth mesh DFU metadata. + * @brief Common types and functions for the Bluetooth Mesh DFU metadata. */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_METADATA_H__ diff --git a/include/zephyr/bluetooth/mesh/dfu_srv.h b/include/zephyr/bluetooth/mesh/dfu_srv.h index e136701e6643..2beaf2d97720 100644 --- a/include/zephyr/bluetooth/mesh/dfu_srv.h +++ b/include/zephyr/bluetooth/mesh/dfu_srv.h @@ -9,7 +9,7 @@ * @defgroup bt_mesh_dfu_srv Firmware Update Server model * @ingroup bt_mesh_dfu * @{ - * @brief API for the Bluetooth mesh Firmware Update Server model + * @brief API for the Bluetooth Mesh Firmware Update Server model */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ @@ -136,7 +136,7 @@ struct bt_mesh_dfu_srv_cb { /** @brief Transfer recovery callback. * * If the device reboots in the middle of a transfer, the Firmware Update Server - * calls this function when the Bluetooth mesh subsystem is started. + * calls this function when the Bluetooth Mesh subsystem is started. * * This callback is optional, but transfers will not be recovered after * a reboot without it. diff --git a/include/zephyr/bluetooth/mesh/main.h b/include/zephyr/bluetooth/mesh/main.h index a4e98b97f8c8..a213e8ce22cd 100644 --- a/include/zephyr/bluetooth/mesh/main.h +++ b/include/zephyr/bluetooth/mesh/main.h @@ -1,5 +1,5 @@ /** @file - * @brief Bluetooth mesh Protocol APIs. + * @brief Bluetooth Mesh Protocol APIs. */ /* @@ -550,8 +550,8 @@ bool bt_mesh_is_provisioned(void); */ /** - * @brief Bluetooth mesh - * @defgroup bt_mesh Bluetooth mesh + * @brief Bluetooth Mesh + * @defgroup bt_mesh Bluetooth Mesh * @ingroup bluetooth * @{ */ @@ -607,6 +607,10 @@ void bt_mesh_reset(void); * If at all possible, the Friendship feature should be used instead, to * make the node into a Low Power Node. * + * @note Should not be called from work queue due to undefined behavior. + * This is due to k_work_flush_delayable() being used in disabling of the + * extended advertising. + * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_suspend(void); diff --git a/include/zephyr/bluetooth/mesh/msg.h b/include/zephyr/bluetooth/mesh/msg.h index e52ca85e3a41..8a7ce1a71288 100644 --- a/include/zephyr/bluetooth/mesh/msg.h +++ b/include/zephyr/bluetooth/mesh/msg.h @@ -98,6 +98,9 @@ struct bt_mesh_msg_ctx { /** Force sending reliably by using segment acknowledgment */ bool send_rel; + /** Send message with a random delay according to the Access layer transmitting rules. */ + bool rnd_delay; + /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ uint8_t send_ttl; }; diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 630a059c1553..c55958924ff8 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -41,6 +41,10 @@ extern "C" { */ #define Z_DEVICE_DEPS_ENDS INT16_MAX +/** @brief Determine if a DT node is mutable */ +#define Z_DEVICE_IS_MUTABLE(node_id) \ + COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0)) + /** @endcond */ /** @@ -924,12 +928,13 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * @param api Reference to device API. * @param ... Optional dependencies, manually specified. */ -#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ - prio, api, state, deps) \ - COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \ - const STRUCT_SECTION_ITERABLE_NAMED(device, \ - Z_DEVICE_SECTION_NAME(level, prio), \ - DEVICE_NAME_GET(dev_id)) = \ +#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \ + deps) \ + COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \ + COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \ + STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \ + device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \ + Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \ Z_DEVICE_INIT(name, pm, data, config, api, state, deps) /* deprecated device initialization levels */ @@ -961,15 +966,18 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * @param level Initialization level. * @param prio Initialization priority. */ -#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \ - Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \ - \ - static const Z_DECL_ALIGN(struct init_entry) __used __noasan \ - Z_INIT_ENTRY_SECTION(level, prio, \ - Z_DEVICE_INIT_SUB_PRIO(node_id)) \ - Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ - .init_fn = {.dev = (init_fn_)}, \ - .dev = &DEVICE_NAME_GET(dev_id), \ +#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \ + Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \ + \ + static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \ + level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \ + Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ + .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ + (init_fn_)}, \ + { \ + COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ + &DEVICE_NAME_GET(dev_id), \ + }, \ } /** @@ -1015,8 +1023,9 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * don't have a corresponding @ref device allocated. There's no way to figure * that out until after we've built the zephyr image, though. */ -#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \ - extern const struct device DEVICE_DT_NAME_GET(node_id); +#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \ + extern COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), \ + (const)) struct device DEVICE_DT_NAME_GET(node_id); DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL) diff --git a/include/zephyr/drivers/misc/devmux/devmux.h b/include/zephyr/drivers/misc/devmux/devmux.h new file mode 100644 index 000000000000..1772d719d96d --- /dev/null +++ b/include/zephyr/drivers/misc/devmux/devmux.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public APIs for the Device Multiplexer driver + */ + +#ifndef INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ +#define INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Devmux Driver APIs + * @defgroup demux_interface Devmux Driver APIs + * @ingroup misc_interfaces + * + * @details + * Devmux operates as a device multiplexer, forwarding the characteristics of + * the selected device. + * + * ``` + * +----------+ +----------+ + * | devmux | | devmux | + * | | | | + * dev0 | | dev0 | | + * +----------> \ | +----------> | + * | \ | | | + * dev1 | \ | dev0 dev1 | | dev2 + * +----------> O +----------> +----------> O +----------> + * | | | / | + * dev2 | | dev2 | / | + * +----------> | +----------> / | + * | | | | + * | | | | + * | | | | + * +-----^----+ +-----^----+ + * | | + * select == 0 | select == 2 | + * +--------------+ +---------------+ + * ``` + * @{ + */ + +/** + * @brief Get the current selection of a devmux device. + * + * Return the index of the currently selected device. + * + * @param dev the devmux device + * @return The index (>= 0) of the currently active multiplexed device on success + * @retval -EINVAL If @p dev is invalid + */ +__syscall ssize_t devmux_select_get(const struct device *dev); + +/** + * @brief Set the selection of a devmux device. + * + * Select the device at @p index. + * + * @param[in] dev the devmux device + * @param index the index representing the desired selection + * @retval 0 On success + * @retval -EINVAL If @p dev is invalid + * @retval -ENODEV If the multiplexed device at @p index is not ready + */ +__syscall int devmux_select_set(struct device *dev, size_t index); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ */ diff --git a/include/zephyr/drivers/serial/uart_async_to_irq.h b/include/zephyr/drivers/serial/uart_async_to_irq.h new file mode 100644 index 000000000000..d5116dee2c0e --- /dev/null +++ b/include/zephyr/drivers/serial/uart_async_to_irq.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ +#define ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ + +#include +#include +#include +#include +#include + +/** + * @brief UART Asynchronous to Interrupt driven API adaptation layer + * @ingroup uart_interface + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declarations. */ + +/** @brief Data structure used by the adaptation layer. + * + * Pointer to that data must be the first element of the UART device data structure. + */ +struct uart_async_to_irq_data; + +/** @brief Configuration structure used by the adaptation layer. + * + * Pointer to this data must be the first element of the UART device configuration structure. + */ +struct uart_async_to_irq_config; + +/* @brief Function that triggers trampoline to the interrupt context. + * + * This context is used to call user UART interrupt handler. It is to used to + * fulfill the requirement that UART interrupt driven API shall be called from + * the UART interrupt. Trampoline context shall have the same priority as UART. + * + * One option may be to use k_timer configured to expire immediately. + */ +typedef void (*uart_async_to_irq_trampoline)(const struct device *dev); + +/** @brief Callback to be called from trampoline context. + * + * @param dev UART device. + */ +void uart_async_to_irq_trampoline_cb(const struct device *dev); + +/** @brief Interrupt driven API initializer. + * + * It should be used in the initialization of the UART API structure in the + * driver to provide interrupt driven API functions. + */ +#define UART_ASYNC_TO_IRQ_API_INIT() \ + .fifo_fill = z_uart_async_to_irq_fifo_fill, \ + .fifo_read = z_uart_async_to_irq_fifo_read, \ + .irq_tx_enable = z_uart_async_to_irq_irq_tx_enable, \ + .irq_tx_disable = z_uart_async_to_irq_irq_tx_disable, \ + .irq_tx_ready = z_uart_async_to_irq_irq_tx_ready, \ + .irq_rx_enable = z_uart_async_to_irq_irq_rx_enable, \ + .irq_rx_disable = z_uart_async_to_irq_irq_rx_disable, \ + .irq_tx_complete = z_uart_async_to_irq_irq_tx_complete,\ + .irq_rx_ready = z_uart_async_to_irq_irq_rx_ready, \ + .irq_err_enable = z_uart_async_to_irq_irq_err_enable, \ + .irq_err_disable = z_uart_async_to_irq_irq_err_disable,\ + .irq_is_pending = z_uart_async_to_irq_irq_is_pending, \ + .irq_update = z_uart_async_to_irq_irq_update, \ + .irq_callback_set = z_uart_async_to_irq_irq_callback_set + +/** @brief Configuration structure initializer. + * + * @param _api Structure with UART asynchronous API. + * @param _trampoline Function that trampolines to the interrupt context. + * @param _baudrate UART baudrate. + * @param _tx_buf TX buffer. + * @param _tx_len TX buffer length. + * @param _rx_buf RX buffer. + * @param _rx_len RX buffer length. + * @param _rx_cnt Number of chunks into which RX buffer is divided. + * @param _log Logging instance, if not provided (empty) then default is used. + */ +#define UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(_api, _trampoline, _baudrate, _tx_buf, \ + _tx_len, _rx_buf, _rx_len, _rx_cnt, _log) \ + { \ + .tx_buf = _tx_buf, \ + .tx_len = _tx_len, \ + .async_rx = { \ + .buffer = _rx_buf, \ + .length = _rx_len, \ + .buf_cnt = _rx_cnt \ + }, \ + .api = _api, \ + .trampoline = _trampoline, \ + .baudrate = _baudrate, \ + LOG_OBJECT_PTR_INIT(log, \ + COND_CODE_1(IS_EMPTY(_log), \ + (LOG_OBJECT_PTR(UART_ASYNC_TO_IRQ_LOG_NAME)), \ + (_log) \ + ) \ + ) \ + } + +/** @brief Initialize the adaptation layer. + * + * @param data Data associated with the given adaptation layer instance. + * @param config Configuration structure. Must be persistent. + * + * @retval 0 On successful initialization. + */ +int uart_async_to_irq_init(struct uart_async_to_irq_data *data, + const struct uart_async_to_irq_config *config); + +/* @brief Enable RX for interrupt driven API. + * + * @param dev UART device. Device must support asynchronous API. + * + * @retval 0 on successful operation. + * @retval -EINVAL if adaption layer has wrong configuration. + * @retval negative value Error reported by the UART API. + */ +int uart_async_to_irq_rx_enable(const struct device *dev); + +/* @brief Disable RX for interrupt driven API. + * + * @param dev UART device. Device must support asynchronous API. + * + * @retval 0 on successful operation. + * @retval -EINVAL if adaption layer has wrong configuration. + * @retval negative value Error reported by the UART API. + */ +int uart_async_to_irq_rx_disable(const struct device *dev); + +/* Starting from here API is internal only. */ + +/** @cond INTERNAL_HIDDEN + * @brief Structure used by the adaptation layer. + */ +struct uart_async_to_irq_config { + /** Pointer to the TX buffer. */ + uint8_t *tx_buf; + + /** TX buffer length. */ + size_t tx_len; + + /** UART Asynchronous RX helper configuration. */ + struct uart_async_rx_config async_rx; + + /** Async API used by the a2i layer. */ + const struct uart_async_to_irq_async_api *api; + + /** Trampoline callback. */ + uart_async_to_irq_trampoline trampoline; + + /** Initial baudrate. */ + uint32_t baudrate; + + /** Instance logging handler. */ + LOG_INSTANCE_PTR_DECLARE(log); +}; + +/** @brief Asynchronous API used by the adaptation layer. */ +struct uart_async_to_irq_async_api { + int (*callback_set)(const struct device *dev, + uart_callback_t callback, + void *user_data); + + int (*tx)(const struct device *dev, const uint8_t *buf, size_t len, + int32_t timeout); + int (*tx_abort)(const struct device *dev); + + int (*rx_enable)(const struct device *dev, uint8_t *buf, size_t len, + int32_t timeout); + int (*rx_buf_rsp)(const struct device *dev, uint8_t *buf, size_t len); + int (*rx_disable)(const struct device *dev); +}; + +/** @brief Structure holding receiver data. */ +struct uart_async_to_irq_rx_data { + /** Asynchronous RX helper data. */ + struct uart_async_rx async_rx; + + /** Semaphore for pending on RX disable. */ + struct k_sem sem; + + /** Number of pending buffer requests which weren't handled because lack of free buffers. */ + atomic_t pending_buf_req; +}; + +/** @brief Structure holding transmitter data. */ +struct uart_async_to_irq_tx_data { + /** TX buffer. */ + uint8_t *buf; + + /** Length of the buffer. */ + size_t len; +}; + +/** @briref Data associated with the asynchronous to the interrupt driven API adaptation layer. */ +struct uart_async_to_irq_data { + /** User callback for interrupt driven API. */ + uart_irq_callback_user_data_t callback; + + /** User data. */ + void *user_data; + + /** Interrupt request counter. */ + atomic_t irq_req; + + /** RX specific data. */ + struct uart_async_to_irq_rx_data rx; + + /** TX specific data. */ + struct uart_async_to_irq_tx_data tx; + + /** Spinlock. */ + struct k_spinlock lock; + + /** Internally used flags for holding the state of the a2i layer. */ + atomic_t flags; +}; + +/** Interrupt driven FIFO fill function. */ +int z_uart_async_to_irq_fifo_fill(const struct device *dev, + const uint8_t *buf, + int len); + +/** Interrupt driven FIFO read function. */ +int z_uart_async_to_irq_fifo_read(const struct device *dev, + uint8_t *buf, + const int len); + +/** Interrupt driven transfer enabling function. */ +void z_uart_async_to_irq_irq_tx_enable(const struct device *dev); + +/** Interrupt driven transfer disabling function */ +void z_uart_async_to_irq_irq_tx_disable(const struct device *dev); + +/** Interrupt driven transfer ready function */ +int z_uart_async_to_irq_irq_tx_ready(const struct device *dev); + +/** Interrupt driven receiver enabling function */ +void z_uart_async_to_irq_irq_rx_enable(const struct device *dev); + +/** Interrupt driven receiver disabling function */ +void z_uart_async_to_irq_irq_rx_disable(const struct device *dev); + +/** Interrupt driven transfer complete function */ +int z_uart_async_to_irq_irq_tx_complete(const struct device *dev); + +/** Interrupt driven receiver ready function */ +int z_uart_async_to_irq_irq_rx_ready(const struct device *dev); + +/** Interrupt driven error enabling function */ +void z_uart_async_to_irq_irq_err_enable(const struct device *dev); + +/** Interrupt driven error disabling function */ +void z_uart_async_to_irq_irq_err_disable(const struct device *dev); + +/** Interrupt driven pending status function */ +int z_uart_async_to_irq_irq_is_pending(const struct device *dev); + +/** Interrupt driven interrupt update function */ +int z_uart_async_to_irq_irq_update(const struct device *dev); + +/** Set the irq callback function */ +void z_uart_async_to_irq_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data); + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ */ diff --git a/include/zephyr/drivers/timer/nrf_grtc_timer.h b/include/zephyr/drivers/timer/nrf_grtc_timer.h new file mode 100644 index 000000000000..172a904fdef9 --- /dev/null +++ b/include/zephyr/drivers/timer/nrf_grtc_timer.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H +#define ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** @brief GRTC timer compare event handler. + * + * Called from GRTC ISR context when processing a compare event. + * + * @param id Compare channel ID. + * + * @param expire_time An actual absolute expiration time set for a compare + * channel. It can differ from the requested target time + * and the difference can be used to determine whether the + * time set was delayed. + * + * @param user_data Pointer to a user context data. + */ +typedef void (*z_nrf_grtc_timer_compare_handler_t)(int32_t id, uint64_t expire_time, + void *user_data); + +/** @brief Allocate GRTC capture/compare channel. + * + * @retval >=0 Non-negative indicates allocated channel ID. + * @retval -ENOMEM if channel cannot be allocated. + */ +int32_t z_nrf_grtc_timer_chan_alloc(void); + +/** @brief Free GRTC capture/compare channel. + * + * @param chan Previously allocated channel ID. + */ +void z_nrf_grtc_timer_chan_free(int32_t chan); + +/** @brief Read current absolute time. + * + * @return Current absolute time. + */ +uint64_t z_nrf_grtc_timer_read(void); + +/** @brief Check COMPARE event state. + * + * @param chan Channel ID. + * + * @retval true The event has been generated. + * @retval false The event has not been generated. + */ +bool z_nrf_grtc_timer_compare_evt_check(int32_t chan); + +/** @brief Get COMPARE event register address. + * + * Address can be used for DPPIC. + * + * @param chan Channel ID. + * + * @return Register address. + */ +uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan); + +/** @brief Get CAPTURE task register address. + * + * Address can be used for DPPIC. + * + * @param chan Channel ID. + * + * @return Register address. + */ +uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan); + +/** @brief Safely disable compare event interrupt. + * + * Function returns key indicating whether interrupt was already disabled. + * + * @param chan Channel ID. + * + * @return key passed to z_nrf_grtc_timer_compare_int_unlock(). + */ +bool z_nrf_grtc_timer_compare_int_lock(int32_t chan); + +/** @brief Safely enable compare event interrupt. + * + * Event interrupt is conditionally enabled based on @p key. + * + * @param chan Channel ID. + * + * @param key Key returned by z_nrf_grtc_timer_compare_int_lock(). + */ +void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key); + +/** @brief Read compare register value. + * + * @param chan Channel ID. + * + * @retval >=0 Positive is a Value set in the compare register + * @retval -EAGAIN if compare for given channel is not set. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +uint64_t z_nrf_grtc_timer_compare_read(int32_t chan); + +/** @brief Set compare channel to given value. + * + * @param chan Channel ID. + * + * @param target_time Absolute target time in ticks. + * + * @param handler User function called in the context of the GRTC interrupt. + * + * @param user_data Data passed to the handler. + * + * @retval 0 if the compare channel was set successfully. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data); + +/** @brief Abort a timer requested with z_nrf_grtc_timer_set(). + * + * If an abort operation is performed too late it is still possible for an event + * to fire. The user can detect a spurious event by comparing absolute time + * provided in callback and a result of z_nrf_grtc_timer_read(). During this + * operation interrupt from that compare channel is disabled. Other interrupts + * are not locked during this operation. + * + * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. + */ +void z_nrf_grtc_timer_abort(int32_t chan); + +/** @brief Convert system clock time to GRTC ticks. + * + * @p t can be absolute or relative. + * + * @retval >=0 Positive value represents @p t in GRTC tick value. + * @retval -EINVAL if @p t is out of range. + */ +uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t); + +/** @brief Prepare channel for timestamp capture. + * + * Use z_nrf_grtc_timer_capture_task_address_get() to determine the register + * address that is used to trigger capture. + * + * @note Capture and compare are mutually exclusive features - they cannot be + * used simultaneously on the same GRTC channel. + * + * @param chan Channel ID. + * + * @retval 0 if the channel was successfully prepared. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +int z_nrf_grtc_timer_capture_prepare(int32_t chan); + +/** @brief Read timestamp value captured on the channel. + * + * The @p chan must be prepared using z_nrf_grtc_timer_capture_prepare(). + * + * @param chan Channel ID. + * + * @param captured_time Pointer to store the value. + * + * @retval 0 if the timestamp was successfully caught and read. + * @retval -EBUSY if capturing has not been triggered. + */ +int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time); + +/** @brief Prepare GRTC as a source of wake up event and set the wake up time. + * + * @note Calling this function should be immediately followed by low-power mode enter + * (if it executed successfully). + * + * @param wake_time_us Relative wake up time in microseconds. + * + * @retval 0 if wake up time was successfully set. + * @retval -EPERM if the SYSCOUNTER is not running. + * @retval -ENOMEM if no available GRTC channels were found. + * @retval -EINVAL if @p wake_time_us is too low. + */ +int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us); + +/** + * @brief Initialize the GRTC clock timer driver from an application- + * defined function. + * + * @retval 0 on success. + * @retval -errno Negative error code on failure. + */ +int nrf_grtc_timer_clock_driver_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H */ diff --git a/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h b/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h new file mode 100644 index 000000000000..60b788a35165 --- /dev/null +++ b/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/* autogenerated using Nordic HAL utils/gen_offsets.py script */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ + +#define NRF_FICR_BLE_ADDRTYPE 0x00CU +#define NRF_FICR_BLE_ADDR_0 0x010U +#define NRF_FICR_BLE_ADDR_1 0x014U +#define NRF_FICR_BLE_ER_0 0x018U +#define NRF_FICR_BLE_ER_1 0x01CU +#define NRF_FICR_BLE_ER_2 0x020U +#define NRF_FICR_BLE_ER_3 0x024U +#define NRF_FICR_BLE_IR_0 0x028U +#define NRF_FICR_BLE_IR_1 0x02CU +#define NRF_FICR_BLE_IR_2 0x030U +#define NRF_FICR_BLE_IR_3 0x034U +#define NRF_FICR_NFC_TAGHEADER_0 0x040U +#define NRF_FICR_NFC_TAGHEADER_1 0x044U +#define NRF_FICR_NFC_TAGHEADER_2 0x048U +#define NRF_FICR_NFC_TAGHEADER_3 0x04CU +#define NRF_FICR_INFO_CONFIGID 0x050U +#define NRF_FICR_INFO_PART 0x054U +#define NRF_FICR_INFO_VARIANT 0x058U +#define NRF_FICR_INFO_PACKAGE 0x05CU +#define NRF_FICR_INFO_RAM 0x060U +#define NRF_FICR_INFO_MRAM 0x064U +#define NRF_FICR_INFO_CODEPAGESIZE 0x068U +#define NRF_FICR_INFO_CODESIZE 0x06CU +#define NRF_FICR_INFO_DEVICETYPE 0x070U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALVREF 0x384U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_0 0x388U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_1 0x38CU +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_2 0x390U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALOFFSET 0x394U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_0 0x398U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_1 0x39CU +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_2 0x3A0U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_3 0x3A4U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_4 0x3A8U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_5 0x3ACU +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALIREF 0x3B0U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALVREFTC 0x3B4U +#define NRF_FICR_TRIM_GLOBAL_NFCT_BIASCFG 0x3BCU +#define NRF_FICR_TRIM_GLOBAL_CANPLL_TRIM_CTUNE 0x3C0U +#define NRF_FICR_TRIM_GLOBAL_COMP_REFTRIM 0x3D0U +#define NRF_FICR_TRIM_GLOBAL_COMP_RCALTRIM 0x3D4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP 0x3D8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0 0x3DCU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_1 0x3E0U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_2 0x3E4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_3 0x3E8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_4 0x3ECU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_5 0x3F0U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0 0x3F4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_1 0x3F8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_2 0x3FCU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_3 0x400U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_4 0x404U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_5 0x408U +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_0_TRIM 0x40CU +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_1_TRIM 0x410U +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_2_TRIM 0x414U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_VSUP 0x418U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_0 0x41CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_1 0x420U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_2 0x424U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_3 0x428U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_4 0x42CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_5 0x430U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_0 0x434U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_1 0x438U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_2 0x43CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_3 0x440U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_4 0x444U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_5 0x448U +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_0_TRIM 0x44CU +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_1_TRIM 0x450U +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_2_TRIM 0x454U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL0 0x458U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL1 0x45CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL2 0x460U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_RXCTRL 0x464U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_OVRRXTRIMCODE 0x468U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_RXAGC_CALIBRATION 0x46CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_PVTTOT 0x470U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_KDTC 0x474U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_TXHFGAIN 0x478U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_PVTTOFIX 0x47CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_LOOPGAIN 0x480U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h index b2dcd7ae6c98..9d7f8c2312fe 100644 --- a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h @@ -131,7 +131,6 @@ /** * @name nRF pinctrl output drive. - * @note Values match nrf_gpio_pin_drive_t constants. * @{ */ @@ -152,7 +151,7 @@ /** High drive '0', disconnect '1'. */ #define NRF_DRIVE_H0D1 7U /** Extra high drive '0', extra high drive '1'. */ -#define NRF_DRIVE_E0E1 11U +#define NRF_DRIVE_E0E1 8U /** @} */ diff --git a/include/zephyr/init.h b/include/zephyr/init.h index 9b0d2993d620..78ec454f27c9 100644 --- a/include/zephyr/init.h +++ b/include/zephyr/init.h @@ -73,6 +73,17 @@ union init_function { * @retval -errno If device initialization fails. */ int (*dev)(const struct device *dev); +#ifdef CONFIG_DEVICE_MUTABLE + /** + * Device initialization function (rw). + * + * @param dev Device instance. + * + * @retval 0 On success + * @retval -errno If device initialization fails. + */ + int (*dev_rw)(struct device *dev); +#endif }; /** @@ -96,7 +107,12 @@ struct init_entry { * If the init entry belongs to a device, this fields stores a * reference to it, otherwise it is set to NULL. */ - const struct device *dev; + union { + const struct device *dev; +#ifdef CONFIG_DEVICE_MUTABLE + struct device *dev_rw; +#endif + }; }; /** @cond INTERNAL_HIDDEN */ @@ -189,10 +205,7 @@ struct init_entry { #define SYS_INIT_NAMED(name, init_fn_, level, prio) \ static const Z_DECL_ALIGN(struct init_entry) \ Z_INIT_ENTRY_SECTION(level, prio, 0) __used __noasan \ - Z_INIT_ENTRY_NAME(name) = { \ - .init_fn = {.sys = (init_fn_)}, \ - .dev = NULL, \ - } + Z_INIT_ENTRY_NAME(name) = {.init_fn = {.sys = (init_fn_)}} /** @} */ diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index c03351abf989..7bb6e55f1c18 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -137,6 +137,10 @@ ITERABLE_SECTION_RAM(zbus_channel_observation_mask, 1) #endif /* CONFIG_ZBUS */ +#if defined(CONFIG_DEVICE_MUTABLE) + ITERABLE_SECTION_RAM(device_mutable, 4) +#endif + #ifdef CONFIG_USERSPACE _static_kernel_objects_end = .; #endif diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index 71c1c1e089f5..2aa46dfecf51 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -21,3 +21,7 @@ #if defined(CONFIG_COAP_SERVER) ITERABLE_SECTION_ROM(coap_service, 4) #endif + +#if defined(CONFIG_NET_SOCKETS_SERVICE) + ITERABLE_SECTION_ROM(net_socket_service_desc, 4) +#endif diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index 3cc53da7d882..3102f17cf1ae 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -97,6 +97,25 @@ struct llext_loader { /** @endcond */ }; +static inline int llext_read(struct llext_loader *l, void *buf, size_t len) +{ + return l->read(l, buf, len); +} + +static inline int llext_seek(struct llext_loader *l, size_t pos) +{ + return l->seek(l, pos); +} + +static inline void *llext_peek(struct llext_loader *l, size_t pos) +{ + if (l->peek) { + return l->peek(l, pos); + } + + return NULL; +} + /** * @} */ diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index b1aef67413e9..84e43d22b5bc 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -78,6 +78,16 @@ struct llext_symtable { .name = STRINGIFY(x), .addr = &x, \ } +/** + * @brief Export a system call to a table of symbols + * + * Takes a system call name and uses @a EXPORT_SYMBOL() to export the respective + * function. + * + * @param x System call to export + */ +#define EXPORT_SYSCALL(x) EXPORT_SYMBOL(z_impl_ ## x) + /** * @} */ diff --git a/include/zephyr/logging/log_msg.h b/include/zephyr/logging/log_msg.h index fabc7a16b0cb..39cbf1cedbc5 100644 --- a/include/zephyr/logging/log_msg.h +++ b/include/zephyr/logging/log_msg.h @@ -241,7 +241,7 @@ enum z_log_msg_mode { #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_0(fmt) 1 #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_1(fmt, arg) Z_CBPRINTF_IS_WORD_NUM(arg) #define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_2(fmt, arg0, arg1) \ - Z_CBPRINTF_IS_WORD_NUM(arg0) || Z_CBPRINTF_IS_WORD_NUM(arg1) + Z_CBPRINTF_IS_WORD_NUM(arg0) && Z_CBPRINTF_IS_WORD_NUM(arg1) /** brief Determine if string arguments types allow to use simplified message creation mode. * diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index a907d1311e16..cd57c560bee4 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -238,29 +238,6 @@ typedef int (*coap_method_t)(struct coap_resource *resource, typedef void (*coap_notify_t)(struct coap_resource *resource, struct coap_observer *observer); -/** - * @brief Event types for observer event callbacks. - */ -enum coap_observer_event { - /** An observer was added. */ - COAP_OBSERVER_ADDED = 0, - /** An observer was removed. */ - COAP_OBSERVER_REMOVED, -}; - -/** - * @typedef coap_observer_event_handler_t - * @brief Type of the handler being called when a resource's observers has been modified. - * Either an observer was added or removed. - * - * @param resource A pointer to a CoAP resource for which the event occurred - * @param observer The observer being added/removed - * @param event The event type - */ -typedef void (*coap_observer_event_handler_t)(struct coap_resource *resource, - struct coap_observer *observer, - enum coap_observer_event event); - /** * @brief Description of CoAP resource. * @@ -275,13 +252,6 @@ struct coap_resource { void *user_data; sys_slist_t observers; int age; -#if defined(CONFIG_COAP_OBSERVER_EVENTS) || defined(DOXYGEN) - /** - * Optional observer event callback function - * Only available when @kconfig{CONFIG_COAP_OBSERVER_EVENTS} is enabled. - */ - coap_observer_event_handler_t observer_event_handler; -#endif }; /** @@ -339,6 +309,18 @@ typedef int (*coap_reply_t)(const struct coap_packet *response, struct coap_reply *reply, const struct sockaddr *from); +/** + * @brief CoAP transmission parameters. + */ +struct coap_transmission_parameters { + /** Initial ACK timeout. Value is used as a base value to retry pending CoAP packets. */ + uint32_t ack_timeout; + /** Set CoAP retry backoff factor. A value of 200 means a factor of 2.0. */ + uint16_t coap_backoff_percent; + /** Maximum number of retransmissions. */ + uint8_t max_retransmission; +}; + /** * @brief Represents a request awaiting for an acknowledgment (ACK). */ @@ -350,6 +332,7 @@ struct coap_pending { uint8_t *data; /**< User allocated buffer */ uint16_t len; /**< Length of the CoAP packet */ uint8_t retries; /**< Number of times the request has been sent */ + struct coap_transmission_parameters params; /**< Transmission parameters */ }; /** @@ -1019,14 +1002,15 @@ void coap_reply_init(struct coap_reply *reply, * confirmation message, initialized with data from @a request * @param request Message waiting for confirmation * @param addr Address to send the retransmission - * @param retries Maximum number of retransmissions of the message. + * @param params Pointer to the CoAP transmission parameters struct, + * or NULL to use default values * * @return 0 in case of success or negative in case of error. */ int coap_pending_init(struct coap_pending *pending, const struct coap_packet *request, const struct sockaddr *addr, - uint8_t retries); + const struct coap_transmission_parameters *params); /** * @brief Returns the next available pending struct, that can be used @@ -1128,6 +1112,15 @@ void coap_pending_clear(struct coap_pending *pending); */ void coap_pendings_clear(struct coap_pending *pendings, size_t len); +/** + * @brief Count number of pending requests. + * + * @param len Number of elements in array. + * @param pendings Array of pending requests. + * @return count of elements where timeout is not zero. + */ +size_t coap_pendings_count(struct coap_pending *pendings, size_t len); + /** * @brief Cancels awaiting for this reply, so it becomes available * again. User responsibility to free the memory associated with data. @@ -1164,6 +1157,20 @@ int coap_resource_notify(struct coap_resource *resource); */ bool coap_request_is_observe(const struct coap_packet *request); +/** + * @brief Get currently active CoAP transmission parameters. + * + * @return CoAP transmission parameters structure. + */ +struct coap_transmission_parameters coap_get_transmission_parameters(void); + +/** + * @brief Set CoAP transmission parameters. + * + * @param params Pointer to the transmission parameters structure. + */ +void coap_set_transmission_parameters(const struct coap_transmission_parameters *params); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h index c3de1abee27c..e48048d5c265 100644 --- a/include/zephyr/net/coap_client.h +++ b/include/zephyr/net/coap_client.h @@ -83,7 +83,6 @@ struct coap_client_internal_request { uint32_t offset; uint32_t last_id; uint8_t request_tkl; - uint8_t retry_count; bool request_ongoing; struct coap_block_context recv_blk_ctx; struct coap_block_context send_blk_ctx; @@ -131,12 +130,12 @@ int coap_client_init(struct coap_client *client, const char *info); * @param sock Open socket file descriptor. * @param addr the destination address of the request, NULL if socket is already connected. * @param req CoAP request structure - * @param retries How many times to retry or -1 to use default. + * @param params Pointer to transmission parameters structure or NULL to use default values. * @return zero when operation started successfully or negative error code otherwise. */ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries); + struct coap_client_request *req, struct coap_transmission_parameters *params); /** * @} diff --git a/include/zephyr/net/coap_mgmt.h b/include/zephyr/net/coap_mgmt.h new file mode 100644 index 000000000000..f19eec6eb4b4 --- /dev/null +++ b/include/zephyr/net/coap_mgmt.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief CoAP Events code public header + */ + +#ifndef ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ +#define ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief CoAP Manager Events + * @defgroup coap_mgmt CoAP Manager Events + * @ingroup networking + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +/* CoAP events */ +#define _NET_COAP_LAYER NET_MGMT_LAYER_L4 +#define _NET_COAP_CODE 0x1c0 +#define _NET_COAP_IF_BASE (NET_MGMT_EVENT_BIT | \ + NET_MGMT_LAYER(_NET_COAP_LAYER) | \ + NET_MGMT_LAYER_CODE(_NET_COAP_CODE)) + +struct coap_service; +struct coap_resource; +struct coap_observer; + +/** @endcond */ + +enum net_event_coap_cmd { + /* Service events */ + NET_EVENT_COAP_CMD_SERVICE_STARTED = 1, + NET_EVENT_COAP_CMD_SERVICE_STOPPED, + /* Observer events */ + NET_EVENT_COAP_CMD_OBSERVER_ADDED, + NET_EVENT_COAP_CMD_OBSERVER_REMOVED, +}; + +/** + * @brief coap_mgmt event raised when a service has started + */ +#define NET_EVENT_COAP_SERVICE_STARTED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STARTED) + +/** + * @brief coap_mgmt event raised when a service has stopped + */ +#define NET_EVENT_COAP_SERVICE_STOPPED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STOPPED) + +/** + * @brief coap_mgmt event raised when an observer has been added to a resource + */ +#define NET_EVENT_COAP_OBSERVER_ADDED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_ADDED) + +/** + * @brief coap_mgmt event raised when an observer has been removed from a resource + */ +#define NET_EVENT_COAP_OBSERVER_REMOVED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_REMOVED) + +/** + * @brief CoAP Service event structure. + */ +struct net_event_coap_service { + /* The CoAP service for which the event is emitted */ + const struct coap_service *service; +}; + +/** + * @brief CoAP Observer event structure. + */ +struct net_event_coap_observer { + /* The CoAP resource for which the event is emitted */ + struct coap_resource *resource; + /* The observer that is added/removed */ + struct coap_observer *observer; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ */ diff --git a/include/zephyr/net/coap_service.h b/include/zephyr/net/coap_service.h index 3e3201308b94..b894fecf519e 100644 --- a/include/zephyr/net/coap_service.h +++ b/include/zephyr/net/coap_service.h @@ -57,7 +57,9 @@ struct coap_service { }; #define __z_coap_service_define(_name, _host, _port, _flags, _res_begin, _res_end) \ - static struct coap_service_data coap_service_data_##_name; \ + static struct coap_service_data coap_service_data_##_name = { \ + .sock_fd = -1, \ + }; \ const STRUCT_SECTION_ITERABLE(coap_service, _name) = { \ .name = STRINGIFY(_name), \ .host = _host, \ @@ -197,7 +199,7 @@ struct coap_service { * @param service Pointer to CoAP service * @retval 0 in case of success. * @retval -EALREADY in case of an already running service. - * @retval -ENOMEM in case the server has no available context. + * @retval -ENOTSUP in case the server has no valid host and port configuration. */ int coap_service_start(const struct coap_service *service); @@ -212,6 +214,18 @@ int coap_service_start(const struct coap_service *service); */ int coap_service_stop(const struct coap_service *service); +/** + * @brief Query the provided @p service running state. + * + * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE. + * + * @param service Pointer to CoAP service + * @retval 1 if the service is running + * @retval 0 if the service is stopped + * @retval negative in case of an error. + */ +int coap_service_is_running(const struct coap_service *service); + /** * @brief Send a CoAP message from the provided @p service . * @@ -221,10 +235,12 @@ int coap_service_stop(const struct coap_service *service); * @param cpkt CoAP Packet to send * @param addr Peer address * @param addr_len Peer address length + * @param params Pointer to transmission parameters structure or NULL to use default values. * @return 0 in case of success or negative in case of error. */ int coap_service_send(const struct coap_service *service, const struct coap_packet *cpkt, - const struct sockaddr *addr, socklen_t addr_len); + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params); /** * @brief Send a CoAP message from the provided @p resource . @@ -235,10 +251,12 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack * @param cpkt CoAP Packet to send * @param addr Peer address * @param addr_len Peer address length + * @param params Pointer to transmission parameters structure or NULL to use default values. * @return 0 in case of success or negative in case of error. */ int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt, - const struct sockaddr *addr, socklen_t addr_len); + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params); /** * @brief Parse a CoAP observe request for the provided @p resource . diff --git a/include/zephyr/net/dhcpv4_server.h b/include/zephyr/net/dhcpv4_server.h new file mode 100644 index 000000000000..18c4af114cda --- /dev/null +++ b/include/zephyr/net/dhcpv4_server.h @@ -0,0 +1,118 @@ +/** @file + * @brief DHCPv4 Server API + */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ +#define ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DHCPv4 server + * @defgroup dhcpv4_server DHCPv4 server + * @ingroup networking + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +struct net_if; + +#define DHCPV4_CLIENT_ID_MAX_SIZE 20 + +enum dhcpv4_server_addr_state { + DHCPV4_SERVER_ADDR_FREE, + DHCPV4_SERVER_ADDR_RESERVED, + DHCPV4_SERVER_ADDR_ALLOCATED, + DHCPV4_SERVER_ADDR_DECLINED, +}; + +struct dhcpv4_client_id { + uint8_t buf[DHCPV4_CLIENT_ID_MAX_SIZE]; + uint8_t len; +}; + +struct dhcpv4_addr_slot { + enum dhcpv4_server_addr_state state; + struct dhcpv4_client_id client_id; + struct in_addr addr; + uint32_t lease_time; + k_timepoint_t expiry; +}; + +/** @endcond */ + +/** + * @brief Start DHCPv4 server instance on an iface + * + * @details Start DHCPv4 server on a given interface. The server will start + * listening for DHCPv4 Discover/Request messages on the interface and assign + * IPv4 addresses from the configured address pool accordingly. + * + * @param iface A valid pointer on an interface + * @param base_addr First IPv4 address from the DHCPv4 address pool. The number + * of addresses in the pool is configured statically with Kconfig + * (CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT). + * + * @return 0 on success, a negative error code otherwise. + */ +int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr); + +/** + * @brief Stop DHCPv4 server instance on an iface + * + * @details Stop DHCPv4 server on a given interface. DHCPv4 requests will no + * longer be handled on the interface, and all of the allocations are cleared. + * + * @param iface A valid pointer on an interface + * + * @return 0 on success, a negative error code otherwise. + */ +int net_dhcpv4_server_stop(struct net_if *iface); + +/** + * @typedef net_dhcpv4_lease_cb_t + * @brief Callback used while iterating over active DHCPv4 address leases + * + * @param iface Pointer to the network interface + * @param lease Pointer to the DHPCv4 address lease slot + * @param user_data A valid pointer to user data or NULL + */ +typedef void (*net_dhcpv4_lease_cb_t)(struct net_if *iface, + struct dhcpv4_addr_slot *lease, + void *user_data); + +/** + * @brief Iterate over all DHCPv4 address leases on a given network interface + * and call callback for each lease. In case no network interface is provided + * (NULL interface pointer), will iterate over all interfaces running DHCPv4 + * server instance. + * + * @param iface Pointer to the network interface, can be NULL + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +int net_dhcpv4_server_foreach_lease(struct net_if *iface, + net_dhcpv4_lease_cb_t cb, + void *user_data); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ */ diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index a47ec767a608..faa6cf7fc0b4 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -179,6 +179,9 @@ enum ethernet_hw_caps { /** TXTIME supported */ ETHERNET_TXTIME = BIT(19), + + /** TX-Injection supported */ + ETHERNET_TXINJECTION_MODE = BIT(20), }; /** @cond INTERNAL_HIDDEN */ @@ -196,6 +199,8 @@ enum ethernet_config_type { ETHERNET_CONFIG_TYPE_PRIORITY_QUEUES_NUM, ETHERNET_CONFIG_TYPE_FILTER, ETHERNET_CONFIG_TYPE_PORTS_NUM, + ETHERNET_CONFIG_TYPE_T1S_PARAM, + ETHERNET_CONFIG_TYPE_TXINJECTION_MODE, }; enum ethernet_qav_param_type { @@ -206,7 +211,53 @@ enum ethernet_qav_param_type { ETHERNET_QAV_PARAM_TYPE_STATUS, }; +enum ethernet_t1s_param_type { + ETHERNET_T1S_PARAM_TYPE_PLCA_CONFIG, +}; + /** @endcond */ +struct ethernet_t1s_param { + /** Type of T1S parameter */ + enum ethernet_t1s_param_type type; + union { + /* PLCA is the Physical Layer (PHY) Collision + * Avoidance technique employed with multidrop + * 10Base-T1S standard. + * + * The PLCA parameters are described in standard [1] + * as registers in memory map 4 (MMS = 4) (point 9.6). + * + * IDVER (PLCA ID Version) + * CTRL0 (PLCA Control 0) + * CTRL1 (PLCA Control 1) + * STATUS (PLCA Status) + * TOTMR (PLCA TO Control) + * BURST (PLCA Burst Control) + * + * Those registers are implemented by each OA TC6 + * compliant vendor (like for e.g. LAN865x - e.g. [2]). + * + * Documents: + * [1] - "OPEN Alliance 10BASE-T1x MAC-PHY Serial + * Interface" (ver. 1.1) + * [2] - "DS60001734C" - LAN865x data sheet + */ + struct { + /** T1S PLCA enabled */ + bool enable; + /** T1S PLCA node id range: 0 to 254 */ + uint8_t node_id; + /** T1S PLCA node count range: 1 to 255 */ + uint8_t node_count; + /** T1S PLCA burst count range: 0x0 to 0xFF */ + uint8_t burst_count; + /** T1S PLCA burst timer */ + uint8_t burst_timer; + /** T1S PLCA TO value */ + uint8_t to_timer; + } plca; + }; +}; struct ethernet_qav_param { /** ID of the priority queue to use */ @@ -395,6 +446,7 @@ struct ethernet_config { bool auto_negotiation; bool full_duplex; bool promisc_mode; + bool txinjection_mode; struct { bool link_10bt; @@ -404,6 +456,7 @@ struct ethernet_config { struct net_eth_addr mac_address; + struct ethernet_t1s_param t1s_param; struct ethernet_qav_param qav_param; struct ethernet_qbv_param qbv_param; struct ethernet_qbu_param qbu_param; @@ -981,6 +1034,17 @@ void net_eth_carrier_off(struct net_if *iface); */ int net_eth_promisc_mode(struct net_if *iface, bool enable); +/** + * @brief Set TX-Injection mode either ON or OFF. + * + * @param iface Network interface + * + * @param enable on (true) or off (false) + * + * @return 0 if mode set or unset was successful, <0 otherwise. + */ +int net_eth_txinjection_mode(struct net_if *iface, bool enable); + /** * @brief Return PTP clock that is tied to this ethernet network interface. * diff --git a/include/zephyr/net/ethernet_mgmt.h b/include/zephyr/net/ethernet_mgmt.h index 9d95fa7a42e7..18039e9f3aae 100644 --- a/include/zephyr/net/ethernet_mgmt.h +++ b/include/zephyr/net/ethernet_mgmt.h @@ -51,6 +51,9 @@ enum net_request_ethernet_cmd { NET_REQUEST_ETHERNET_CMD_GET_QBV_PARAM, NET_REQUEST_ETHERNET_CMD_GET_QBU_PARAM, NET_REQUEST_ETHERNET_CMD_GET_TXTIME_PARAM, + NET_REQUEST_ETHERNET_CMD_SET_T1S_PARAM, + NET_REQUEST_ETHERNET_CMD_SET_TXINJECTION_MODE, + NET_REQUEST_ETHERNET_CMD_GET_TXINJECTION_MODE, }; #define NET_REQUEST_ETHERNET_SET_AUTO_NEGOTIATION \ @@ -128,6 +131,21 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBU_PARAM); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXTIME_PARAM); +#define NET_REQUEST_ETHERNET_SET_T1S_PARAM \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_T1S_PARAM) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_T1S_PARAM); + +#define NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_TXINJECTION_MODE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE); + +#define NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_GET_TXINJECTION_MODE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE); + struct net_eth_addr; struct ethernet_qav_param; struct ethernet_qbv_param; @@ -139,6 +157,7 @@ struct ethernet_req_params { bool auto_negotiation; bool full_duplex; bool promisc_mode; + bool txinjection_mode; struct { bool link_10bt; @@ -152,6 +171,7 @@ struct ethernet_req_params { struct ethernet_qbv_param qbv_param; struct ethernet_qbu_param qbu_param; struct ethernet_txtime_param txtime_param; + struct ethernet_t1s_param t1s_param; int priority_queues_num; int ports_num; diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index d5fdc712b499..3270f9942483 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -59,12 +59,6 @@ struct net_pkt_cb_ieee802154 { */ uint8_t rssi; }; -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - /* TX packets */ - struct { - int8_t txpwr; /* TX power in dBm. */ - }; -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ }; /* Flags */ @@ -185,18 +179,6 @@ static inline void net_pkt_set_ieee802154_rssi_dbm(struct net_pkt *pkt, int16_t CODE_UNREACHABLE; } -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) -static inline int8_t net_pkt_ieee802154_txpwr(struct net_pkt *pkt) -{ - return net_pkt_cb_ieee802154(pkt)->txpwr; -} - -static inline void net_pkt_set_ieee802154_txpwr(struct net_pkt *pkt, int8_t txpwr) -{ - net_pkt_cb_ieee802154(pkt)->txpwr = txpwr; -} -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ - static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt) { return net_pkt_cb_ieee802154(pkt)->ack_fpb; diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 59608fac391b..259d67b43214 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -592,11 +592,16 @@ struct ieee802154_filter { * IEEE802154_CONFIG_MAC_KEYS. */ struct ieee802154_key { + /** Key material */ uint8_t *key_value; + /** Initial value of frame counter associated with the key, see section 9.4.3 */ uint32_t key_frame_counter; + /** Indicates if per-key frame counter should be used, see section 9.4.3 */ bool frame_counter_per_key; + /** Key Identifier Mode, see section 9.4.2.3, Table 9-7 */ uint8_t key_id_mode; - uint8_t key_index; + /** Key Identifier, see section 9.4.4 */ + uint8_t *key_id; }; /** IEEE 802.15.4 Transmission mode. */ @@ -1236,6 +1241,15 @@ struct ieee802154_config { * in CPU byte order */ uint16_t short_addr; + + /** + * Flag for purging enh ACK header IEs. + * When flag is set to true, driver should remove all existing + * header IEs, and all other entries in config should be ignored. + * This means that purging current header IEs and + * configuring a new one in the same call is not allowed. + */ + bool purge_ie; } ack_ie; }; }; diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index a57b5542f888..c643c32f0bf1 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -134,6 +134,22 @@ typedef void (*lwm2m_ctx_event_cb_t)(struct lwm2m_ctx *ctx, enum lwm2m_rd_client_event event); +/** + * @brief Different traffic states of the LwM2M socket. + * + * This information can be used to give hints for the network interface + * that can decide what kind of power management should be used. + * + * These hints are given from CoAP layer messages, so usage of DTLS might affect the + * actual number of expected datagrams. + */ +enum lwm2m_socket_states { + LWM2M_SOCKET_STATE_ONGOING, /**< Ongoing traffic is expected. */ + LWM2M_SOCKET_STATE_ONE_RESPONSE, /**< One response is expected for the next message. */ + LWM2M_SOCKET_STATE_LAST, /**< Next message is the last one. */ + LWM2M_SOCKET_STATE_NO_DATA, /**< No more data is expected. */ +}; + /** * @brief LwM2M context structure to maintain information for a single * LwM2M connection. @@ -249,6 +265,14 @@ struct lwm2m_ctx { * copied into the actual resource buffer. */ uint8_t validate_buf[CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE]; + + /** + * Callback to indicate transmission states. + * Client application may request LwM2M engine to indicate hints about + * transmission states and use that information to control various power + * saving modes. + */ + void (*set_socket_state)(int fd, enum lwm2m_socket_states state); }; /** @@ -551,7 +575,6 @@ void lwm2m_firmware_set_cancel_cb_inst(uint16_t obj_inst_id, lwm2m_engine_user_c */ lwm2m_engine_user_cb_t lwm2m_firmware_get_cancel_cb_inst(uint16_t obj_inst_id); -#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set data callback to handle firmware update execute events. * @@ -588,8 +611,6 @@ void lwm2m_firmware_set_update_cb_inst(uint16_t obj_inst_id, lwm2m_engine_execut */ lwm2m_engine_execute_cb_t lwm2m_firmware_get_update_cb_inst(uint16_t obj_inst_id); #endif -#endif - #if defined(CONFIG_LWM2M_SWMGMT_OBJ_SUPPORT) || defined(__DOXYGEN__) @@ -988,11 +1009,16 @@ int lwm2m_engine_set_u64(const char *pathstr, uint64_t value); /** * @brief Set resource (instance) value (u64) * + * @deprecated Unsigned 64bit value type does not exits. + * This is internally handled as a int64_t. + * Use lwm2m_set_s64() instead. + * * @param[in] path LwM2M path as a struct * @param[in] value u64 value * * @return 0 for success or negative in case of error. */ +__deprecated int lwm2m_set_u64(const struct lwm2m_obj_path *path, uint64_t value); /** @@ -1314,11 +1340,16 @@ int lwm2m_engine_get_u64(const char *pathstr, uint64_t *value); /** * @brief Get resource (instance) value (u64) * + * @deprecated Unsigned 64bit value type does not exits. + * This is internally handled as a int64_t. + * Use lwm2m_get_s64() instead. + * @param[in] path LwM2M path as a struct * @param[out] value u64 buffer to copy data into * * @return 0 for success or negative in case of error. */ +__deprecated int lwm2m_get_u64(const struct lwm2m_obj_path *path, uint64_t *value); /** @@ -2075,6 +2106,7 @@ enum lwm2m_rd_client_event { LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, LWM2M_RD_CLIENT_EVENT_REG_UPDATE, LWM2M_RD_CLIENT_EVENT_DEREGISTER, + LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED, }; /** diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index f1071af64f26..906cd8f6be62 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -356,6 +356,9 @@ struct mqtt_sec_config { /** Indicates the list of security tags to be used for the session. */ const sec_tag_t *sec_tag_list; + /** Indicates the preference for enabling TLS session caching. */ + int session_cache; + /** Peer hostname for ceritificate verification. * May be NULL to skip hostname verification. */ @@ -363,6 +366,9 @@ struct mqtt_sec_config { /** Indicates the preference for copying certificates to the heap. */ int cert_nocopy; + + /** Set socket to native TLS */ + bool set_native_tls; }; /** @brief MQTT transport type. */ diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 788c33163918..f1e5be67cf75 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -2217,6 +2217,15 @@ struct in_addr *net_if_ipv4_get_ll(struct net_if *iface, struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface, enum net_addr_state addr_state); +/** + * @brief Get IPv4 netmask of an interface. + * + * @param iface Interface to use. + * + * @return The netmask set on the interface, unspecified address if not found. + */ +struct in_addr net_if_ipv4_get_netmask(struct net_if *iface); + /** * @brief Set IPv4 netmask for an interface. * diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 91f9193bbf83..f32753a7952e 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h new file mode 100644 index 000000000000..a80e1ddc2388 --- /dev/null +++ b/include/zephyr/net/socket_ncs.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ + +/** + * @file + * @brief NCS specific additions to the BSD sockets API definitions + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* When CONFIG_NET_SOCKETS_OFFLOAD is enabled, offloaded sockets take precedence + * when creating a new socket. Combine this flag with a socket type when + * creating a socket, to enforce native socket creation (e. g. SOCK_STREAM | SOCK_NATIVE). + * If it's desired to create a native TLS socket, but still offload the + * underlying TCP/UDP socket, use e. g. SOCK_STREAM | SOCK_NATIVE_TLS. + */ +#define SOCK_NATIVE 0x80000000 +#define SOCK_NATIVE_TLS 0x40000000 + +/* NCS specific TLS level socket options */ + +/** Socket option to set DTLS handshake timeout, specifically for nRF sockets. + * The option accepts an integer, indicating the total handshake timeout, + * including retransmissions, in seconds. + * Accepted values for the option are: 1, 3, 7, 15, 31, 63, 123. + */ +#define TLS_DTLS_HANDSHAKE_TIMEO 18 + +/** Socket option to save DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_SAVE 19 + +/** Socket option to load DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_LOAD 20 + +/** Socket option to get result of latest TLS/DTLS completed handshakes end status, + * specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0 and 1. + */ +#define TLS_DTLS_HANDSHAKE_STATUS 21 + +/* Valid values for TLS_SESSION_CACHE option */ +#define TLS_SESSION_CACHE_DISABLED 0 /**< Disable TLS session caching. */ +#define TLS_SESSION_CACHE_ENABLED 1 /**< Enable TLS session caching. */ + +/* Valid values for TLS_DTLS_HANDSHAKE_TIMEO option */ +#define TLS_DTLS_HANDSHAKE_TIMEO_NONE 0 /**< No timeout */ +#define TLS_DTLS_HANDSHAKE_TIMEO_1S 1 /**< 1 second */ +#define TLS_DTLS_HANDSHAKE_TIMEO_3S 3 /**< 1s + 2s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_7S 7 /**< 1s + 2s + 4s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_15S 15 /**< 1s + 2s + 4s + 8s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_31S 31 /**< 1s + 2s + 4s + 8s + 16s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_63S 63 /**< 1s + 2s + 4s + 8s + 16s + 32s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_123S 123 /**< 1s + 2s + 4s + 8s + 16s + 32s + 60s */ + +/* Valid values for TLS_DTLS_HANDSHAKE_STATUS option */ +#define TLS_DTLS_HANDSHAKE_STATUS_FULL 0 +#define TLS_DTLS_HANDSHAKE_STATUS_CACHED 1 + +/* NCS specific socket options */ + +/** sockopt: enable sending data as part of exceptional events */ +#define SO_EXCEPTIONAL_DATA 33 +/** sockopt: bind to PDN */ +#define SO_BINDTOPDN 40 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * application will not send any more data. + */ +#define SO_RAI_NO_DATA 50 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * next call to send/sendto will be the last one for some time. + */ +#define SO_RAI_LAST 51 +/** sockopt: Release Assistance Indication feature: This will indicate that + * after the next call to send/sendto, the application is expecting to receive + * one more data packet before this socket will not be used again for some time. + */ +#define SO_RAI_ONE_RESP 52 +/** sockopt: Release Assistance Indication feature: If a client application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call which will keep the network up longer. + */ +#define SO_RAI_ONGOING 53 +/** sockopt: Release Assistance Indication feature: If a server application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call. + */ +#define SO_RAI_WAIT_MORE 54 + +/* NCS specific IPPROTO_ALL level socket options */ + +/** IPv4 and IPv6 protocol level (pseudo-val) for nRF sockets. */ +#define IPPROTO_ALL 512 +/** sockopt: disable all replies to unexpected traffics */ +#define SO_SILENCE_ALL 30 + +/* NCS specific IPPROTO_IP level socket options */ + +/** sockopt: enable IPv4 ICMP replies */ +#define SO_IP_ECHO_REPLY 31 + +/* NCS specific IPPROTO_IPV6 level socket options */ + +/** sockopt: enable IPv6 ICMP replies */ +#define SO_IPV6_ECHO_REPLY 32 + +/* NCS specific TCP level socket options */ + +/** sockopt: Configurable TCP server session timeout in minutes. + * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). + */ +#define SO_TCP_SRV_SESSTIMEO 55 + +/* NCS specific gettaddrinfo() flags */ + +/** Assume `service` contains a Packet Data Network (PDN) ID. + * When specified together with the AI_NUMERICSERV flag, + * `service` shall be formatted as follows: "port:pdn_id" + * where "port" is the port number and "pdn_id" is the PDN ID. + * Example: "8080:1", port 8080 PDN ID 1. + * Example: "42:0", port 42 PDN ID 0. + */ +#define AI_PDNSERV 0x1000 + +/* NCS specific send() and sendto() flags */ + +/** Request a blocking send operation until the request is acknowledged. + * When used in send() or sendto(), the request will not return until the + * send operation is completed by lower layers, or until the timeout, given by the SO_SNDTIMEO + * socket option, is reached. Valid timeout values are 1 to 600 seconds. + */ +#define MSG_WAITACK 0x200 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ */ diff --git a/include/zephyr/net/socket_service.h b/include/zephyr/net/socket_service.h new file mode 100644 index 000000000000..a4e21f00a333 --- /dev/null +++ b/include/zephyr/net/socket_service.h @@ -0,0 +1,246 @@ +/** + * @file + * @brief BSD Socket service API + * + * API can be used to install a k_work that is called + * if there is data received to a socket. + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ + +/** + * @brief BSD socket service API + * @defgroup bsd_socket_service BSD socket service API + * @ingroup networking + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This struct contains information which socket triggered + * calls to the callback function. + */ +struct net_socket_service_event { + /** k_work that is done when there is desired activity in file descriptor. */ + struct k_work work; + /** Callback to be called for desired socket activity */ + k_work_handler_t callback; + /** Socket information that triggered this event. */ + struct zsock_pollfd event; + /** User data */ + void *user_data; + /** Service back pointer */ + struct net_socket_service_desc *svc; +}; + +/** + * Main structure holding socket service configuration information. + * The k_work item is created so that when there is data coming + * to those fds, the k_work callback is then called. + * The workqueue can be set NULL in which case system workqueue is used. + * The service descriptor should be created at built time, and then used + * as a parameter to register the sockets to be monitored. + * User should create needed sockets and then setup the poll struct and + * then register the sockets to be monitored at runtime. + */ +struct net_socket_service_desc { +#if CONFIG_NET_SOCKETS_LOG_LEVEL >= LOG_LEVEL_DBG + /** + * Owner name. This can be used in debugging to see who has + * registered this service. + */ + const char *owner; +#endif + /** Workqueue where the work is submitted. */ + struct k_work_q *work_q; + /** Pointer to the list of services that we are listening */ + struct net_socket_service_event *pev; + /** Length of the pollable socket array for this service. */ + int pev_len; + /** Where are my pollfd entries in the global list */ + int *idx; +}; + +#define __z_net_socket_svc_get_name(_svc_id) __z_net_socket_service_##_svc_id +#define __z_net_socket_svc_get_idx(_svc_id) __z_net_socket_service_idx_##_svc_id +#define __z_net_socket_svc_get_owner __FILE__ ":" STRINGIFY(__LINE__) + +extern void net_socket_service_callback(struct k_work *work); + +#if CONFIG_NET_SOCKETS_LOG_LEVEL >= LOG_LEVEL_DBG +#define NET_SOCKET_SERVICE_OWNER .owner = __z_net_socket_svc_get_owner, +#else +#define NET_SOCKET_SERVICE_OWNER +#endif + +#define NET_SOCKET_SERVICE_CALLBACK_MODE(_flag) \ + IF_ENABLED(_flag, \ + (.work = Z_WORK_INITIALIZER(net_socket_service_callback),)) + +#define __z_net_socket_service_define(_name, _work_q, _cb, _count, _async, ...) \ + static int __z_net_socket_svc_get_idx(_name); \ + static struct net_socket_service_event \ + __z_net_socket_svc_get_name(_name)[_count] = { \ + [0 ... ((_count) - 1)] = { \ + .event.fd = -1, /* Invalid socket */ \ + NET_SOCKET_SERVICE_CALLBACK_MODE(_async) \ + .callback = _cb, \ + } \ + }; \ + COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), (), __VA_ARGS__) \ + const STRUCT_SECTION_ITERABLE(net_socket_service_desc, _name) = { \ + NET_SOCKET_SERVICE_OWNER \ + .work_q = (_work_q), \ + .pev = __z_net_socket_svc_get_name(_name), \ + .pev_len = (_count), \ + .idx = &__z_net_socket_svc_get_idx(_name), \ + } + +/** + * @brief Statically define a network socket service. + * The user callback is called asynchronously for this service meaning that + * the service API will not wait until the user callback returns before continuing + * with next socket service. + * + * The socket service can be accessed outside the module where it is defined using: + * + * @code extern struct net_socket_service_desc ; @endcode + * + * @note This macro cannot be used together with a static keyword. + * If such a use-case is desired, use NET_SOCKET_SERVICE_ASYNC_DEFINE_STATIC + * instead. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_ASYNC_DEFINE(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 1) + +/** + * @brief Statically define a network socket service in a private (static) scope. + * The user callback is called asynchronously for this service meaning that + * the service API will not wait until the user callback returns before continuing + * with next socket service. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_ASYNC_DEFINE_STATIC(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 1, static) + +/** + * @brief Statically define a network socket service. + * The user callback is called synchronously for this service meaning that + * the service API will wait until the user callback returns before continuing + * with next socket service. + * + * The socket service can be accessed outside the module where it is defined using: + * + * @code extern struct net_socket_service_desc ; @endcode + * + * @note This macro cannot be used together with a static keyword. + * If such a use-case is desired, use NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC + * instead. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_SYNC_DEFINE(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 0) + +/** + * @brief Statically define a network socket service in a private (static) scope. + * The user callback is called synchronously for this service meaning that + * the service API will wait until the user callback returns before continuing + * with next socket service. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 0, static) + +/** + * @brief Register pollable sockets. + * + * @param service Pointer to a service description. + * @param fds Socket array to poll. + * @param len Length of the socket array. + * @param user_data User specific data. + * + * @retval 0 No error + * @retval -ENOENT Service is not found. + * @retval -ENINVAL Invalid parameter. + */ +__syscall int net_socket_service_register(const struct net_socket_service_desc *service, + struct zsock_pollfd *fds, int len, void *user_data); + +/** + * @brief Unregister pollable sockets. + * + * @param service Pointer to a service description. + * + * @retval 0 No error + * @retval -ENOENT Service is not found. + * @retval -ENINVAL Invalid parameter. + */ +static inline int net_socket_service_unregister(const struct net_socket_service_desc *service) +{ + return net_socket_service_register(service, NULL, 0, NULL); +} + +/** + * @typedef net_socket_service_cb_t + * @brief Callback used while iterating over socket services. + * + * @param svc Pointer to current socket service. + * @param user_data A valid pointer to user data or NULL + */ +typedef void (*net_socket_service_cb_t)(const struct net_socket_service_desc *svc, + void *user_data); + +/** + * @brief Go through all the socket services and call callback for each service. + * + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +void net_socket_service_foreach(net_socket_service_cb_t cb, void *user_data); + +#ifdef __cplusplus +} +#endif + +#include + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ */ diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 5c7d5b493fae..c49d6ad0f66b 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -345,6 +345,14 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; +/** Wi-Fi Target Wake Time (TWT) teradown status. */ +enum wifi_twt_teardown_status { + /** TWT teardown success */ + WIFI_TWT_TEARDOWN_SUCCESS = 0, + /** TWT teardown failure */ + WIFI_TWT_TEARDOWN_FAILED, +}; + /** @cond INTERNAL_HIDDEN */ static const char * const wifi_twt_err_code_tbl[] = { [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index faf83b42b840..982184a103b1 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -81,6 +81,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_PACKET_FILTER, /** Set or get Wi-Fi channel for Monitor or TX-Injection mode */ NET_REQUEST_WIFI_CMD_CHANNEL, + /** Disconnect a STA from AP */ + NET_REQUEST_WIFI_CMD_AP_STA_DISCONNECT, NET_REQUEST_WIFI_CMD_MAX }; @@ -158,6 +160,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL); +#define NET_REQUEST_WIFI_AP_STA_DISCONNECT \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_AP_STA_DISCONNECT) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT); + /** Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -180,6 +187,14 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, /** Disconnect complete */ NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, + /** AP mode enable result */ + NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT, + /** AP mode disable result */ + NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, + /** STA connected to AP */ + NET_EVENT_WIFI_CMD_AP_STA_CONNECTED, + /** STA disconnected from AP */ + NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -209,6 +224,18 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) +#define NET_EVENT_WIFI_AP_ENABLE_RESULT \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT) + +#define NET_EVENT_WIFI_AP_DISABLE_RESULT \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT) + +#define NET_EVENT_WIFI_AP_STA_CONNECTED \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) + +#define NET_EVENT_WIFI_AP_STA_DISCONNECTED \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED) + /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -321,9 +348,66 @@ struct wifi_connect_req_params { int timeout; }; +/** Wi-Fi connect result codes. To be overlaid on top of \ref wifi_status + * in the connect result event for detailed status. + */ +enum wifi_conn_status { + /** Connection successful */ + WIFI_STATUS_CONN_SUCCESS = 0, + /** Connection failed - generic failure */ + WIFI_STATUS_CONN_FAIL, + /** Connection failed - wrong password */ + WIFI_STATUS_CONN_WRONG_PASSWORD, + /** Connection timed out */ + WIFI_STATUS_CONN_TIMEOUT, + /** Connection failed - AP not found */ + WIFI_STATUS_CONN_AP_NOT_FOUND, +}; + +/** Wi-Fi disconnect reason codes. To be overlaid on top of \ref wifi_status + * in the disconnect result event for detailed reason. + */ +enum wifi_disconn_reason { + /** Unspecified reason */ + WIFI_REASON_DISCONN_UNSPECIFIED = 0, + /** Disconnected due to user request */ + WIFI_REASON_DISCONN_USER_REQUEST, + /** Disconnected due to AP leaving */ + WIFI_REASON_DISCONN_AP_LEAVING, + /** Disconnected due to inactivity */ + WIFI_REASON_DISCONN_INACTIVITY, +}; + +/** Wi-Fi AP mode result codes. To be overlaid on top of \ref wifi_status + * in the AP mode enable or disable result event for detailed status. + */ +enum wifi_ap_status { + /** AP mode enable or disable successful */ + WIFI_STATUS_AP_SUCCESS = 0, + /** AP mode enable or disable failed - generic failure */ + WIFI_STATUS_AP_FAIL, + /** AP mode enable failed - channel not supported */ + WIFI_STATUS_AP_CHANNEL_NOT_SUPPORTED, + /** AP mode enable failed - channel not allowed */ + WIFI_STATUS_AP_CHANNEL_NOT_ALLOWED, + /** AP mode enable failed - SSID not allowed */ + WIFI_STATUS_AP_SSID_NOT_ALLOWED, + /** AP mode enable failed - authentication type not supported */ + WIFI_STATUS_AP_AUTH_TYPE_NOT_SUPPORTED, + /** AP mode enable failed - operation not supported */ + WIFI_STATUS_AP_OP_NOT_SUPPORTED, + /** AP mode enable failed - operation not permitted */ + WIFI_STATUS_AP_OP_NOT_PERMITTED, +}; + /** Generic Wi-Fi status for commands and events */ struct wifi_status { - int status; + union { + int status; + enum wifi_conn_status conn_status; + enum wifi_disconn_reason disconn_reason; + enum wifi_ap_status ap_status; + }; }; /** Wi-Fi interface status */ @@ -393,6 +477,8 @@ struct wifi_twt_params { enum wifi_twt_setup_cmd setup_cmd; /** TWT setup response status, see enum wifi_twt_setup_resp_status */ enum wifi_twt_setup_resp_status resp_status; + /** TWT teardown cmd status, see enum wifi_twt_teardown_status */ + enum wifi_twt_teardown_status teardown_status; /** Dialog token, used to map requests to responses */ uint8_t dialog_token; /** Flow ID, used to map setup with teardown */ @@ -412,6 +498,12 @@ struct wifi_twt_params { bool announce; /** Wake up time */ uint32_t twt_wake_interval; + /* Wake ahead notification is sent earlier than + * TWT Service period (SP) start based on this duration. + * This should give applications ample time to + * prepare the data before TWT SP starts. + */ + uint32_t twt_wake_ahead_duration; } setup; /** Teardown specific parameters */ struct { @@ -428,6 +520,7 @@ struct wifi_twt_params { #define WIFI_MAX_TWT_INTERVAL_US (LONG_MAX - 1) /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 +#define WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US (LONG_MAX - 1) /** Wi-Fi TWT flow information */ struct wifi_twt_flow_info { @@ -449,6 +542,8 @@ struct wifi_twt_flow_info { bool announce; /** Wake up time */ uint32_t twt_wake_interval; + /* wake ahead duration */ + uint32_t twt_wake_ahead_duration; }; /** Wi-Fi power save configuration */ @@ -469,6 +564,22 @@ enum wifi_mgmt_op { WIFI_MGMT_SET = 1, }; +#define MAX_REG_CHAN_NUM 42 + +/** Per-channel regulatory attributes */ +struct wifi_reg_chan_info { + /** Center frequency in MHz */ + unsigned short center_frequency; + /** Maximum transmission power (in dBm) */ + unsigned short max_power:8; + /** Is channel supported or not */ + unsigned short supported:1; + /** Passive transmissions only */ + unsigned short passive_only:1; + /** Is a DFS channel */ + unsigned short dfs:1; +} __packed; + /** Regulatory domain information or configuration */ struct wifi_reg_domain { /* Regulatory domain operation */ @@ -477,6 +588,10 @@ struct wifi_reg_domain { bool force; /** Country code: ISO/IEC 3166-1 alpha-2 */ uint8_t country_code[WIFI_COUNTRY_CODE_LEN]; + /** Number of channels supported */ + unsigned int num_channels; + /** Channels information */ + struct wifi_reg_chan_info *chan_info; }; /** Wi-Fi TWT sleep states */ @@ -501,6 +616,18 @@ struct wifi_raw_scan_result { }; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ +/** AP mode - connected STA details */ +struct wifi_ap_sta_info { + /** Link mode, see enum wifi_link_mode */ + enum wifi_link_mode link_mode; + /** MAC address */ + uint8_t mac[WIFI_MAC_ADDR_LEN]; + /** MAC address length */ + uint8_t mac_length; + /** is TWT capable ? */ + bool twt_capable; +}; + /* for use in max info size calculations */ union wifi_mgmt_events { struct wifi_scan_result scan_result; @@ -510,6 +637,7 @@ union wifi_mgmt_events { struct wifi_raw_scan_result raw_scan_result; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct wifi_twt_params twt_params; + struct wifi_ap_sta_info ap_sta_info; }; /** Wi-Fi mode setup */ @@ -614,6 +742,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*ap_disable)(const struct device *dev); + /** Disconnect a STA from AP + * + * @param dev Pointer to the device structure for the driver instance. + * @param mac MAC address of the STA to disconnect + * + * @return 0 if ok, < 0 if error + */ + int (*ap_sta_disconnect)(const struct device *dev, const uint8_t *mac); /** Get interface status * * @param dev Pointer to the device structure for the driver instance. @@ -768,6 +904,35 @@ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, */ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); +/** Wi-Fi management AP mode enable result event + * + * @param iface Network interface + * @param status AP mode enable result status + */ +void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, enum wifi_ap_status status); + +/** Wi-Fi management AP mode disable result event + * + * @param iface Network interface + * @param status AP mode disable result status + */ +void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, enum wifi_ap_status status); + +/** Wi-Fi management AP mode STA connected event + * + * @param iface Network interface + * @param sta_info STA information + */ +void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info); + +/** Wi-Fi management AP mode STA disconnected event + * @param iface Network interface + * @param sta_info STA information + */ +void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info); + /** * @} */ diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index c16eef0e5b27..537db7876482 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -103,6 +103,49 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, struct wifi_band_channel *chan, uint8_t max_channels); + +/** + * @brief Validate a channel against a band. + * + * @param band Band to validate the channel against. + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan(uint8_t band, + uint16_t chan); + +/** + * @brief Validate a channel against the 2.4 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_2g(uint16_t chan); + +/** + * @brief Validate a channel against the 5 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_5g(uint16_t chan); + +/** + * @brief Validate a channel against the 6 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_6g(uint16_t chan); + /** * @} */ diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 380e58691e9a..cc4a246105d3 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -271,6 +271,10 @@ const char *flash_area_label(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); +#if USE_PARTITION_MANAGER +#include +#else + #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -343,6 +347,8 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) +#endif /* USE_PARTITION_MANAGER */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index e694bce55cca..722bacd76d58 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -495,6 +495,9 @@ static inline uint32_t arch_proc_id(void); */ void arch_sched_ipi(void); + +int arch_smp_init(void); + #endif /* CONFIG_SMP */ /** diff --git a/include/zephyr/sys/iterable_sections.h b/include/zephyr/sys/iterable_sections.h index fe1976363ca7..3ec4af5e9a08 100644 --- a/include/zephyr/sys/iterable_sections.h +++ b/include/zephyr/sys/iterable_sections.h @@ -234,6 +234,16 @@ extern "C" { #define STRUCT_SECTION_ITERABLE_NAMED(struct_type, name, varname) \ TYPE_SECTION_ITERABLE(struct struct_type, varname, struct_type, name) +/** + * @brief Defines a new element for an iterable section with a custom name, + * placed in a custom section. + * + * The name can be used to customize how iterable section entries are sorted. + * @see STRUCT_SECTION_ITERABLE_NAMED() + */ +#define STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(struct_type, secname, name, varname) \ + TYPE_SECTION_ITERABLE(struct struct_type, varname, secname, name) + /** * @brief Iterate over a specified iterable section (alternate). * diff --git a/kernel/Kconfig b/kernel/Kconfig index 6280e80a400b..d5e737e76556 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1260,6 +1260,13 @@ config DEVICE_DEPS_DYNAMIC Option that makes it possible to manipulate device dependencies at runtime. +config DEVICE_MUTABLE + bool "Mutable devices [EXPERIMENTAL]" + select EXPERIMENTAL + help + Support mutable devices. Mutable devices are instantiated in SRAM + instead of Flash and are runtime modifiable in kernel mode. + endmenu rsource "Kconfig.vm" diff --git a/kernel/mutex.c b/kernel/mutex.c index 6d22ce83f226..622422aef7ba 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -37,6 +37,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); /* We use a global spinlock here because some of the synchronization @@ -195,6 +196,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) return -EAGAIN; } +EXPORT_SYSCALL(k_mutex_lock); #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_lock(struct k_mutex *mutex, @@ -280,6 +282,7 @@ int z_impl_k_mutex_unlock(struct k_mutex *mutex) return 0; } +EXPORT_SYSCALL(k_mutex_unlock); #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_mutex_unlock(struct k_mutex *mutex) diff --git a/kernel/thread.c b/kernel/thread.c index 8f60054e7986..fc31f4b36d8b 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -29,6 +29,7 @@ #include #include #include +#include #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -141,6 +142,7 @@ bool k_is_in_isr(void) { return arch_is_in_isr(); } +EXPORT_SYMBOL(k_is_in_isr); /* * This function tags the current thread as essential to system operation. diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index e3a5db6f7d53..2f469d673e4b 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -25,6 +25,20 @@ #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); +#if USE_PARTITION_MANAGER + +#include + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + +#define RAM_SIZE (KB((size_t) CONFIG_SRAM_SIZE)) +#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS + +#endif /* USE_PARTITION_MANAGER */ + #ifdef CONFIG_COMMON_LIBC_MALLOC #if (CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE != 0) @@ -106,8 +120,8 @@ static POOL_SECTION unsigned char __aligned(HEAP_ALIGN) malloc_arena[HEAP_SIZE]; extern char _heap_sentry[]; # define HEAP_SIZE ROUND_DOWN((POINTER_TO_UINT(_heap_sentry) - HEAP_BASE), HEAP_ALIGN) # else -# define HEAP_SIZE ROUND_DOWN((KB((size_t) CONFIG_SRAM_SIZE) - \ - ((size_t) HEAP_BASE - (size_t) CONFIG_SRAM_BASE_ADDRESS)), HEAP_ALIGN) +# define HEAP_SIZE ROUND_DOWN((RAM_SIZE - \ + ((size_t) HEAP_BASE - (size_t) RAM_ADDR)), HEAP_ALIGN) # endif /* else CONFIG_XTENSA */ # endif /* else CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE > 0 */ diff --git a/lib/os/Kconfig.heap b/lib/os/Kconfig.heap index b913d6100dcd..f6e8d93ae504 100644 --- a/lib/os/Kconfig.heap +++ b/lib/os/Kconfig.heap @@ -51,7 +51,7 @@ config HEAP_LISTENER choice prompt "Supported heap sizes" depends on !64BIT - default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) + default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256) && !PARTITION_MANAGER_ENABLED default SYS_HEAP_AUTO help Heaps using reduced-size chunk headers can accommodate so called diff --git a/lib/os/assert.c b/lib/os/assert.c index b6a33ae73202..1fee487bff64 100644 --- a/lib/os/assert.c +++ b/lib/os/assert.c @@ -7,7 +7,7 @@ #include #include #include - +#include /** * @brief Assert Action Handler @@ -42,6 +42,7 @@ __weak void assert_post_action(const char *file, unsigned int line) k_panic(); } +EXPORT_SYMBOL(assert_post_action); void assert_print(const char *fmt, ...) { @@ -53,3 +54,4 @@ void assert_print(const char *fmt, ...) va_end(ap); } +EXPORT_SYMBOL(assert_print); diff --git a/modules/cmsis/Kconfig b/modules/cmsis/Kconfig index 4b5a8ee28557..eff0be6f40c2 100644 --- a/modules/cmsis/Kconfig +++ b/modules/cmsis/Kconfig @@ -21,4 +21,11 @@ config HAS_CMSIS_CORE_R config HAS_CMSIS_CORE_M bool +config CMSIS_M_CHECK_DEVICE_DEFINES + bool "Check device defines" + default n + depends on HAS_CMSIS_CORE_M + help + This options enables the validation of CMSIS configuration flags. + endif diff --git a/modules/cmsis/cmsis_core_m.h b/modules/cmsis/cmsis_core_m.h index 880ff614b5b6..e73826339453 100644 --- a/modules/cmsis/cmsis_core_m.h +++ b/modules/cmsis/cmsis_core_m.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2023 Arm Limited * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,95 +15,57 @@ #ifndef ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ #define ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ +#if defined(CONFIG_CMSIS_M_CHECK_DEVICE_DEFINES) && CONFIG_CMSIS_M_CHECK_DEVICE_DEFINES == 1U +#define __CHECK_DEVICE_DEFINES 1U +#endif + #include #include -#ifdef __cplusplus -extern "C" { +#if __NVIC_PRIO_BITS != NUM_IRQ_PRIO_BITS +#error "NUM_IRQ_PRIO_BITS and __NVIC_PRIO_BITS are not set to the same value" +#endif + +#if __MPU_PRESENT != CONFIG_CPU_HAS_ARM_MPU +#error "__MPU_PRESENT and CONFIG_CPU_HAS_ARM_MPU are not set to the same value" +#endif + +#if __FPU_PRESENT != CONFIG_CPU_HAS_FPU +#error "__FPU_PRESENT and CONFIG_CPU_HAS_FPU are not set to the same value" #endif -/* Fill in CMSIS required values for non-CMSIS compliant SoCs. - * Use __NVIC_PRIO_BITS as it is required and simple to check, but - * ultimately all SoCs will define their own CMSIS types and constants. + +/* VTOR is only optional on armv6-m and armv8-m baseline. __VTOR_PRESENT is often + * left undefined on platform where it is not optional. */ -#ifndef __NVIC_PRIO_BITS -typedef enum { - Reset_IRQn = -15, - NonMaskableInt_IRQn = -14, - HardFault_IRQn = -13, -#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - MemoryManagement_IRQn = -12, - BusFault_IRQn = -11, - UsageFault_IRQn = -10, -#if defined(CONFIG_ARM_SECURE_FIRMWARE) - SecureFault_IRQn = -9, -#endif /* CONFIG_ARM_SECURE_FIRMWARE */ -#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ - SVCall_IRQn = -5, - DebugMonitor_IRQn = -4, - PendSV_IRQn = -2, - SysTick_IRQn = -1, - Max_IRQn = CONFIG_NUM_IRQS, -} IRQn_Type; - -#if defined(CONFIG_CPU_CORTEX_M0) -#define __CM0_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M0PLUS) -#define __CM0PLUS_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M1) -#define __CM1_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M3) -#define __CM3_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M4) -#define __CM4_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M7) -#define __CM7_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M23) -#define __CM23_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M33) -#define __CM33_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M55) -#define __CM55_REV 0 -#else -#error "Unknown Cortex-M device" +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && \ + (__VTOR_PRESENT != CONFIG_CPU_CORTEX_M_HAS_VTOR) +#error "__VTOR_PRESENT and CONFIG_CPU_CORTEX_M_HAS_VTOR are not set to the same value." #endif -#ifndef __MPU_PRESENT -#define __MPU_PRESENT 0U +/* Some platform’s sdk incorrectly define __DSP_PRESENT for Cortex-M4 & Cortex-M7 + * DSP extension. __ARM_FEATURE_DSP is set by the compiler for these. So ignore + * __DSP_PRESENT discrepancy when __ARM_FEATURE_DSP is defined. + */ +#if !defined(__ARM_FEATURE_DSP) && (__DSP_PRESENT != CONFIG_ARMV8_M_DSP) +#error "__DSP_PRESENT and CONFIG_ARMV8_M_DSP are not set to the same value" #endif -#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS -#define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ -#endif /* __NVIC_PRIO_BITS */ -#if __NVIC_PRIO_BITS != NUM_IRQ_PRIO_BITS -#error "NUM_IRQ_PRIO_BITS and __NVIC_PRIO_BITS are not set to the same value" +#if __ICACHE_PRESENT != CONFIG_CPU_HAS_ICACHE +#error "__ICACHE_PRESENT and CONFIG_CPU_HAS_ICACHE are not set to the same value" +#endif + +#if __DCACHE_PRESENT != CONFIG_CPU_HAS_DCACHE +#error "__DCACHE_PRESENT and CONFIG_CPU_HAS_DCACHE are not set to the same value" #endif -#ifdef __cplusplus -} +#if __MVE_PRESENT != CONFIG_ARMV8_1_M_MVEI +#error "__MVE_PRESENT and CONFIG_ARMV8_1_M_MVEI are not set to the same value" #endif -#if defined(CONFIG_CPU_CORTEX_M0) -#include -#elif defined(CONFIG_CPU_CORTEX_M0PLUS) -#include -#elif defined(CONFIG_CPU_CORTEX_M1) -#include -#elif defined(CONFIG_CPU_CORTEX_M3) -#include -#elif defined(CONFIG_CPU_CORTEX_M4) -#include -#elif defined(CONFIG_CPU_CORTEX_M7) -#include -#elif defined(CONFIG_CPU_CORTEX_M23) -#include -#elif defined(CONFIG_CPU_CORTEX_M33) -#include -#elif defined(CONFIG_CPU_CORTEX_M55) -#include -#else -#error "Unknown Cortex-M device" +#if __SAUREGION_PRESENT != CONFIG_CPU_HAS_ARM_SAU +#error "__SAUREGION_PRESENT and CONFIG_CPU_HAS_ARM_SAU are not set to the same value" #endif #endif /* ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ */ diff --git a/modules/cmsis/cmsis_core_m_defaults.h b/modules/cmsis/cmsis_core_m_defaults.h new file mode 100644 index 000000000000..bef62665493d --- /dev/null +++ b/modules/cmsis/cmsis_core_m_defaults.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2023 Arm Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief CMSIS interface file + * + * This header populates the default values required to configure the + * ARM CMSIS Core headers. + */ + +#ifndef ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ +#define ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Fill in CMSIS required values for non-CMSIS compliant SoCs. + * Use __NVIC_PRIO_BITS as it is required and simple to check, but + * ultimately all SoCs will define their own CMSIS types and constants. + */ +#ifndef __NVIC_PRIO_BITS +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, +#if defined(CONFIG_ARM_SECURE_FIRMWARE) + SecureFault_IRQn = -9, +#endif /* CONFIG_ARM_SECURE_FIRMWARE */ +#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + Max_IRQn = CONFIG_NUM_IRQS, +} IRQn_Type; + +#if defined(CONFIG_CPU_CORTEX_M0) +#define __CM0_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M0PLUS) +#define __CM0PLUS_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M1) +#define __CM1_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M3) +#define __CM3_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M4) +#define __CM4_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M7) +#define __CM7_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M23) +#define __CM23_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M33) +#define __CM33_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M55) +#define __CM55_REV 0 +#else +#error "Unknown Cortex-M device" +#endif + +#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS +#define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ +#endif /* __NVIC_PRIO_BITS */ + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#endif + +#ifndef __FPU_PRESENT +#define __FPU_PRESENT CONFIG_CPU_HAS_FPU +#endif + +#ifndef __FPU_DP +#define __FPU_DP CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION +#endif + +#ifndef __VTOR_PRESENT +#define __VTOR_PRESENT CONFIG_CPU_CORTEX_M_HAS_VTOR +#endif + +#ifndef __DSP_PRESENT +#define __DSP_PRESENT CONFIG_ARMV8_M_DSP +#endif + +#ifndef __ICACHE_PRESENT +#define __ICACHE_PRESENT CONFIG_CPU_HAS_ICACHE +#endif + +#ifndef __DCACHE_PRESENT +#define __DCACHE_PRESENT CONFIG_CPU_HAS_DCACHE +#endif + +#ifndef __MVE_PRESENT +#define __MVE_PRESENT CONFIG_ARMV8_1_M_MVEI +#endif + +#ifndef __SAUREGION_PRESENT +#define __SAUREGION_PRESENT CONFIG_CPU_HAS_ARM_SAU +#endif + +#ifndef __PMU_PRESENT +#define __PMU_PRESENT CONFIG_ARMV8_1_M_PMU +#define __PMU_NUM_EVENTCNT CONFIG_ARMV8_1_M_PMU_EVENTCNT +#endif + +#ifdef __cplusplus +} +#endif + +#if defined(CONFIG_CPU_CORTEX_M0) +#include +#elif defined(CONFIG_CPU_CORTEX_M0PLUS) +#include +#elif defined(CONFIG_CPU_CORTEX_M1) +#include +#elif defined(CONFIG_CPU_CORTEX_M3) +#include +#elif defined(CONFIG_CPU_CORTEX_M4) +#include +#elif defined(CONFIG_CPU_CORTEX_M7) +#include +#elif defined(CONFIG_CPU_CORTEX_M23) +#include +#elif defined(CONFIG_CPU_CORTEX_M33) +#include +#elif defined(CONFIG_CPU_CORTEX_M55) +#include +#else +#error "Unknown Cortex-M device" +#endif + +#endif /* ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ */ diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt index 693400aba76e..6f5364ac8de4 100644 --- a/modules/hal_nordic/CMakeLists.txt +++ b/modules/hal_nordic/CMakeLists.txt @@ -6,3 +6,19 @@ if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) endif (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) add_subdirectory_ifdef(CONFIG_HAS_NRFX nrfx) + +if(CONFIG_NRF_REGTOOL_GENERATE_UICR) + list(APPEND nrf_regtool_components GENERATE:UICR) +endif() +if(DEFINED nrf_regtool_components) + find_package(nrf-regtool 5.0.1 + COMPONENTS ${nrf_regtool_components} + PATHS ${CMAKE_CURRENT_LIST_DIR}/nrf-regtool + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_PACKAGE_REGISTRY + NO_CMAKE_SYSTEM_PATH + NO_CMAKE_SYSTEM_PACKAGE_REGISTRY + ) +endif() diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index f842d2cb646b..c9cc93e93293 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -43,30 +43,6 @@ config NRF_802154_MULTIPROTOCOL_SUPPORT in the driver, this option must be enabled. Otherwise, the driver assumes that access to the radio peripheral is granted indefinitely. -config NRF_802154_ENCRYPTION - bool "nRF 802.15.4 AES-CCM* authentication & encryption" - depends on !CRYPTO_NRF_ECB - -choice NRF_802154_CCA_MODE - prompt "nRF IEEE 802.15.4 CCA mode" - default NRF_802154_CCA_MODE_ED - help - CCA mode - -config NRF_802154_CCA_MODE_ED - bool "Energy Above Threshold" - -config NRF_802154_CCA_MODE_CARRIER - bool "Carrier Seen" - -config NRF_802154_CCA_MODE_CARRIER_AND_ED - bool "Energy Above Threshold AND Carrier Seen" - -config NRF_802154_CCA_MODE_CARRIER_OR_ED - bool "Energy Above Threshold OR Carrier Seen" - -endchoice - choice NRF_802154_SL_TYPE prompt "nRF IEEE 802.15.4 Service Layer Type" @@ -77,43 +53,6 @@ config NRF_802154_SL_OPENSOURCE endchoice -config NRF_802154_CCA_ED_THRESHOLD - int "nRF IEEE 802.15.4 CCA Energy Detection threshold" - default 45 - help - If energy detected in a given channel is above the value then the - channel is deemed busy. The unit is defined as per 802.15.4-2006 spec. - -config NRF_802154_CCA_CORR_THRESHOLD - int "nRF IEEE 802.15.4 CCA Correlator threshold" - default 45 - -config NRF_802154_CCA_CORR_LIMIT - int "nRF IEEE 802.15.4 CCA Correlator limit" - default 2 - help - Limit for occurrences above correlator threshold. When not equal to - zero the correlator based signal detect is enabled. - -config NRF_802154_PENDING_SHORT_ADDRESSES - int "nRF 802.15.4 pending short addresses" - default 16 - help - Number of slots containing short addresses of nodes for which pending data is stored - -config NRF_802154_PENDING_EXTENDED_ADDRESSES - int "nRF 802.15.4 pending extended addresses" - default 16 - help - Number of slots containing extended addresses of nodes for which pending data is stored - -config NRF_802154_RX_BUFFERS - int "nRF 802.15.4 receive buffers" - default 16 - help - Number of buffers in nRF 802.15.4 driver receive queue. If this value is modified, - its serialization host counterpart must be set to the exact same value. - config NRF_802154_TEMPERATURE_UPDATE bool "nRF 802.15.4 temperature update" default y @@ -192,7 +131,47 @@ config NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT This option specifies default timeout of spinel status response in milliseconds. -if NRF_802154_SER_HOST +endmenu # NRF_802154_SER_HOST || NRF_802154_SER_RADIO + +if NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION + +choice NRF_802154_CCA_MODE + prompt "nRF IEEE 802.15.4 CCA mode" + default NRF_802154_CCA_MODE_ED + help + CCA mode + +config NRF_802154_CCA_MODE_ED + bool "Energy Above Threshold" + +config NRF_802154_CCA_MODE_CARRIER + bool "Carrier Seen" + +config NRF_802154_CCA_MODE_CARRIER_AND_ED + bool "Energy Above Threshold AND Carrier Seen" + +config NRF_802154_CCA_MODE_CARRIER_OR_ED + bool "Energy Above Threshold OR Carrier Seen" + +endchoice + +config NRF_802154_CCA_ED_THRESHOLD + int "nRF IEEE 802.15.4 CCA Energy Detection threshold" + default 45 + help + If energy detected in a given channel is above the value then the + channel is deemed busy. The unit is defined as per 802.15.4-2006 spec. + +config NRF_802154_CCA_CORR_THRESHOLD + int "nRF IEEE 802.15.4 CCA Correlator threshold" + default 45 + +config NRF_802154_CCA_CORR_LIMIT + int "nRF IEEE 802.15.4 CCA Correlator limit" + default 2 + help + Limit for occurrences above correlator threshold. When not equal to + zero the correlator based signal detect is enabled. config NRF_802154_RX_BUFFERS int "nRF 802.15.4 receive buffers" @@ -201,17 +180,60 @@ config NRF_802154_RX_BUFFERS Number of buffers in nRF 802.15.4 driver serialization host's receive queue. If this value is modified, its remote counterpart must be set to the exact same value. -endif +config NRF_802154_PENDING_SHORT_ADDRESSES + int "nRF 802.15.4 pending short addresses" + default 16 + help + Number of slots containing short addresses of nodes for which pending data is stored -endmenu # NRF_802154_SER_HOST || NRF_802154_SER_RADIO +config NRF_802154_PENDING_EXTENDED_ADDRESSES + int "nRF 802.15.4 pending extended addresses" + default 16 + help + Number of slots containing extended addresses of nodes for which pending data is stored + +config NRF_802154_ENCRYPTION + bool "nRF 802.15.4 AES-CCM* authentication & encryption" + depends on !CRYPTO_NRF_ECB + +config NRF_802154_SECURITY_KEY_STORAGE_SIZE + int "nRF 802.15.4 security key storage size" + default 3 + help + Number of encryption keys that the nRF 802.15.4 Radio Driver can store simultaneously. config NRF_802154_CARRIER_FUNCTIONS bool "nRF 802.15.4 carrier functions" - depends on NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION help This option enables functions such as modulated carrier and continuous carrier. If this option is modified on a multicore SoC, its remote counterpart must be set to the exact same value. +choice NRF_802154_ASSERT_CHOICE + prompt "nRF 802.15.4 assert implementation" + default NRF_802154_ASSERT_ZEPHYR_MINIMAL + +config NRF_802154_ASSERT_ZEPHYR_MINIMAL + bool "nRF 802.15.4 minimal assertions" + help + This option provides minimal run-time checking of the nRF 802.15.4 Radio Driver's operation, + even if kernel-wide CONFIG_ASSERT is disabled. In case of an abnormal condition the function + `nrf_802154_assert_handler()` is called. File and line debug information are not provided + to save memory of the image file. Default implementation of the `nrf_802154_assert_handler` + involves a call to `k_panic`/`k_oops` and allows further tweaking of the behavior. + You can also provide your own implementation of `nrf_802154_assert_handler`. + +config NRF_802154_ASSERT_ZEPHYR + bool "nRF 802.15.4 Radio Driver assertions as Zephyr's standard __ASERT_NO_MSG" + help + The run-time checking of the nRF 802.15.4 Radio Driver depends fully on the configuration + of the `__ASSERT_NO_MSG` macro, including the ability to completely turn off the run-time + checking. + +endchoice # NRF_802154_ASSERT_CHOICE + +endif # NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION + endmenu # HAS_NORDIC_DRIVERS rsource "nrfx/Kconfig" +rsource "Kconfig.nrf_regtool" diff --git a/modules/hal_nordic/Kconfig.nrf_regtool b/modules/hal_nordic/Kconfig.nrf_regtool new file mode 100644 index 000000000000..81659bcf0bb8 --- /dev/null +++ b/modules/hal_nordic/Kconfig.nrf_regtool @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "nrf-regtool options" + depends on SOC_SERIES_NRF54HX + +config NRF_REGTOOL_GENERATE_UICR + bool "Generate UICR" + help + Generate a UICR hex based on devicetree contents using nrf-regtool. + CPU domains that require UICR allocation aren't bootable without it + being programmed alongside the firmware. + +config NRF_REGTOOL_VERBOSITY + int "Verbosity level of console output" + range 0 3 + default 0 + help + Level of verbose output that nrf-regtool will print to the console. + + 0. Only critical information and warnings. + 1. Print a pretty, human-readable representation of a peripheral's + configuration. This is recommended for inspecting register values. + 2. Print extra details for debugging purposes, such as memory maps of + the peripheral configurations, but in a less readable format. + 3. Print even more details, which are typically only useful for + nrf-regtool developers. + +config NRF_REGTOOL_EXTRA_GENERATE_ARGS + string "Extra arguments to 'nrf-regtool generate'" + help + List of additional arguments to every nrf-regtool invocation used for + generating hex files. Example value: "--fill all --fill-byte 0xff". + Run "nrf-regtool generate -h" to see all of the available options. + +endmenu diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake new file mode 100644 index 000000000000..d057c735e3f5 --- /dev/null +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +function(nrf_regtool_generate_hex_from_dts peripheral) + string(TOLOWER "${peripheral}.hex" generated_hex_name) + string(TOLOWER "${peripheral}_merged.hex" merged_hex_name) + + # Prepare common argument sub-lists. + string(REPEAT "-v;" ${CONFIG_NRF_REGTOOL_VERBOSITY} verbosity) + list(TRANSFORM CACHED_DTS_ROOT_BINDINGS PREPEND "--bindings-dir;" OUTPUT_VARIABLE bindings_dirs) + separate_arguments(extra_args UNIX_COMMAND "${CONFIG_NRF_REGTOOL_EXTRA_GENERATE_ARGS}") + + set(generated_hex_file ${PROJECT_BINARY_DIR}/${generated_hex_name}) + execute_process( + COMMAND ${NRF_REGTOOL} ${verbosity} generate + --peripheral ${peripheral} + --svd-file ${SOC_SVD_FILE} + --dts-file ${ZEPHYR_DTS} + ${bindings_dirs} + --output-file ${generated_hex_file} + ${extra_args} + WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} + COMMAND_ERROR_IS_FATAL ANY + ) + message(STATUS "Generated ${peripheral} hex file: ${generated_hex_file}") + + set(merged_hex_file ${PROJECT_BINARY_DIR}/${merged_hex_name}) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${merged_hex_file} + ${generated_hex_file} + ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} + ) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${merged_hex_file}) +endfunction() + + +foreach(component IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS) + string(REGEX MATCH "(^.*):(.*$)" match ${component}) + set(operation "${CMAKE_MATCH_1}") + set(peripheral "${CMAKE_MATCH_2}") + + if(operation STREQUAL "GENERATE") + nrf_regtool_generate_hex_from_dts(${peripheral}) + else() + message(FATAL_ERROR "Unrecognized package component: \"${component}\"") + endif() +endforeach() diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake new file mode 100644 index 000000000000..e147d1b05326 --- /dev/null +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +find_program(NRF_REGTOOL nrf-regtool) + +if(NRF_REGTOOL) + execute_process( + COMMAND ${NRF_REGTOOL} --version + OUTPUT_VARIABLE version + RESULT_VARIABLE result + ) + + if(result EQUAL 0 AND version MATCHES "version ([0-9]+[.][0-9]+[.][0-9]+)") + set(PACKAGE_VERSION ${CMAKE_MATCH_1}) + if(PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() + + message(STATUS + "Found nrf-regtool (found suitable version \"${PACKAGE_VERSION}\", " + "minimum required is \"${PACKAGE_FIND_VERSION}\")" + ) + return() + endif() + endif() +endif() + +# We only get here if we don't pass the version check. +set(PACKAGE_VERSION_UNSUITABLE TRUE) +set(NRF_REGTOOL NRF_REGTOOL-NOTFOUND CACHE INTERNAL "Path to a program") diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index c338981b651c..763f9625be8d 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -12,24 +12,6 @@ if (CONFIG_NRF_802154_RADIO_DRIVER) sl_opensource/platform/nrf_802154_irq_zephyr.c sl_opensource/platform/nrf_802154_temperature_zephyr.c ) - - target_compile_definitions(zephyr-802154-interface - INTERFACE - # CCA mode options - NRF_802154_CCA_CORR_LIMIT_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_LIMIT} - NRF_802154_CCA_CORR_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_THRESHOLD} - NRF_802154_CCA_ED_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_ED_THRESHOLD} - ) - - if (CONFIG_NRF_802154_CCA_MODE_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_ED) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_AND_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_AND_ED) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_OR_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_OR_ED) - endif() endif () if (CONFIG_NRF_802154_SERIALIZATION) @@ -69,8 +51,26 @@ target_compile_definitions(zephyr-802154-interface # ACK timeout NRF_802154_ACK_TIMEOUT_ENABLED=1 + + # CCA mode options + NRF_802154_CCA_CORR_LIMIT_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_LIMIT} + NRF_802154_CCA_CORR_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_THRESHOLD} + NRF_802154_CCA_ED_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_ED_THRESHOLD} + + # Key storage size + NRF_802154_SECURITY_KEY_STORAGE_SIZE=${CONFIG_NRF_802154_SECURITY_KEY_STORAGE_SIZE} ) +if (CONFIG_NRF_802154_CCA_MODE_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_ED) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_AND_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_AND_ED) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_OR_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_OR_ED) +endif() + if (CONFIG_NRF_802154_ENCRYPTION) target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENCRYPTION_ENABLED=1) target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_SECURITY_WRITER_ENABLED=1) @@ -93,8 +93,12 @@ else() target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CARRIER_FUNCTIONS_ENABLED=0) endif() -if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENERGY_DETECTED_VERSION=1) +target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENERGY_DETECTED_VERSION=1) + +if (CONFIG_NRF_802154_ASSERT_ZEPHYR OR CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + target_include_directories(zephyr-802154-interface INTERFACE include) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_PLATFORM_ASSERT_INCLUDE=\"nrf_802154_assert_zephyr.h\") + target_sources(nrf-802154-platform PRIVATE nrf_802154_assert_handler.c) endif() set(NRF52_SERIES ${CONFIG_SOC_SERIES_NRF52X}) diff --git a/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h b/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h new file mode 100644 index 000000000000..ecd09de609ad --- /dev/null +++ b/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRF_802154_ASSERT_ZEPHYR_H__ +#define NRF_802154_ASSERT_ZEPHYR_H__ + +#if defined(CONFIG_NRF_802154_ASSERT_ZEPHYR) + +#include + +#define NRF_802154_ASSERT(condition) __ASSERT_NO_MSG(condition) + +#elif defined(CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + +extern void nrf_802154_assert_handler(void); + +#define NRF_802154_ASSERT(condition) \ + do { \ + if (!(condition)) { \ + nrf_802154_assert_handler(); \ + } \ + } while (0) + +#endif /* CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL */ + +#endif /* NRF_802154_ASSERT_ZEPHYR_H__*/ diff --git a/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c b/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c new file mode 100644 index 000000000000..14d964724c6d --- /dev/null +++ b/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "nrf_802154_assert_zephyr.h" + +#if defined(CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + +__weak void nrf_802154_assert_handler(void) +{ +#ifdef CONFIG_USERSPACE + /* User threads aren't allowed to induce kernel panics; generate + * an oops instead. + */ + if (k_is_user_context()) { + k_oops(); + } +#endif + + k_panic(); +} + +#endif /* CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL */ diff --git a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c index 06ad1f003e6b..b2629eef67b7 100644 --- a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c +++ b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c @@ -9,6 +9,7 @@ #include #include +#include "nrf_802154.h" #include "nrf_802154_spinel_backend_callouts.h" #include "nrf_802154_serialization_error.h" #include "../../spinel_base/spinel.h" @@ -71,9 +72,11 @@ nrf_802154_ser_err_t nrf_802154_backend_init(void) } /* Send packet thread details */ -#define RING_BUFFER_LEN 16 #define SEND_THREAD_STACK_SIZE 1024 +/* Make the ring buffer long enough to hold all notifications that the driver can produce */ +#define RING_BUFFER_LEN (NRF_802154_MAX_PENDING_NOTIFICATIONS + 1) + static K_SEM_DEFINE(send_sem, 0, RING_BUFFER_LEN); K_THREAD_STACK_DEFINE(send_thread_stack, SEND_THREAD_STACK_SIZE); struct k_thread send_thread_data; diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 69afbcc9c513..ffd2e9aebc1d 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -31,9 +31,18 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUAPP NRF5340_XXAA_APP zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP NRF5340_XXAA_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUNET NRF5340_XXAA_NETWORK) zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET NRF5340_XXAA_NETWORK) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L15_ENGA NRF54L15_ENGA_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L15_ENGA_CPUAPP NRF_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9120 NRF9120_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9160 NRF9160_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUAPP NRF54H20_ENGA_XXAA + NRF_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPURAD NRF54H20_ENGA_XXAA + NRF_RADIOCORE) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUPPR NRF54H20_ENGA_XXAA + NRF_PPR) + zephyr_compile_definitions_ifdef(CONFIG_NRF_APPROTECT_LOCK ENABLE_APPROTECT) zephyr_compile_definitions_ifdef(CONFIG_NRF_APPROTECT_USER_HANDLING @@ -64,6 +73,8 @@ zephyr_library_sources_ifdef(CONFIG_SOC_NRF52833 ${MDK_DIR}/system_nrf5283 zephyr_library_sources_ifdef(CONFIG_SOC_NRF52840 ${MDK_DIR}/system_nrf52840.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP ${MDK_DIR}/system_nrf5340_application.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUNET ${MDK_DIR}/system_nrf5340_network.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54HX ${MDK_DIR}/system_nrf54h.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54LX ${MDK_DIR}/system_nrf54l.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91X ${MDK_DIR}/system_nrf91.c) zephyr_library_sources(nrfx_glue.c) @@ -79,6 +90,7 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_COMP ${SRC_DIR}/nrfx_comp.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) +zephyr_library_sources_ifdef(CONFIG_NRFX_GRTC ${SRC_DIR}/nrfx_grtc.c) zephyr_library_sources_ifdef(CONFIG_NRFX_I2S ${SRC_DIR}/nrfx_i2s.c) zephyr_library_sources_ifdef(CONFIG_NRFX_IPC ${SRC_DIR}/nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_NRFX_LPCOMP ${SRC_DIR}/nrfx_lpcomp.c) @@ -111,6 +123,10 @@ if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) zephyr_library_sources(${SRC_DIR}/nrfx_twi_twim.c) endif() +if (CONFIG_NRF_GRTC_TIMER AND CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) + zephyr_library_compile_definitions(NRF_GRTC_HAS_EXTENDED=1) +endif() + # Inject HAL "CONFIG_NFCT_PINS_AS_GPIOS" definition if user requests to # configure the NFCT pins as GPIOS. Do the same with "CONFIG_GPIO_AS_PINRESET" # to configure the reset GPIO as nRESET. This way, the HAL will take care of @@ -128,3 +144,38 @@ if(DEFINED uicr_path) zephyr_library_compile_definitions(CONFIG_GPIO_AS_PINRESET) endif() endif() + +if(CONFIG_SOC_NRF54L15) + dt_prop(clock_frequency PATH "/cpus/cpu@0" PROPERTY "clock-frequency") + math(EXPR clock_frequency_mhz "${clock_frequency} / 1000000") + zephyr_compile_definitions("NRF_CONFIG_CPU_FREQ_MHZ=${clock_frequency_mhz}") +endif() + +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_CLOCK_CONFIG NRF_SKIP_CLOCK_CONFIGURATION) + +if(CONFIG_SOC_SERIES_NRF54LX AND CONFIG_NRFX_DPPI) + zephyr_library_sources(${HELPERS_DIR}/nrfx_gppi_dppi_ppib_lumos.c) +endif() + +# Get the SVD file for the current SoC +macro(mdk_svd_ifdef feature_toggle filename) + if(${feature_toggle}) + set(SOC_SVD_FILE ${MDK_DIR}/${filename} CACHE FILEPATH "Path to a CMSIS-SVD file") + endif() +endmacro() + +mdk_svd_ifdef(CONFIG_SOC_SERIES_NRF51X nrf51.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52805 nrf52805.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52810 nrf52810.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52811 nrf52811.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52820 nrf52820.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52832 nrf52.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52833 nrf52833.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52840 nrf52840.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF5340_CPUAPP nrf5340_application.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF5340_CPUNET nrf5340_network.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUAPP nrf54h20_enga_application.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUPPR nrf54h20_enga_ppr.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPURAD nrf54h20_enga_radiocore.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF9120 nrf9120.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF9160 nrf9160.svd) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 5dcda73c9be9..ee1bd76b52f7 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -63,8 +63,37 @@ config NRFX_EGU5 select NRFX_EGU config NRFX_GPIOTE - bool "GPIOTE driver" - depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + bool + +config NRFX_GPIOTE0 + bool "GPIOTE0 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote0,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE1 + bool "GPIOTE1 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote1,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE20 + bool "NRFX_GPIOTE20 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote20,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE30 + bool "NRFX_GPIOTE30 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote30,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE130 + bool "NRFX_GPIOTE130 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote130,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE131 + bool "NRFX_GPIOTE131 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote131,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE config NRFX_GPIOTE_NUM_OF_EVT_HANDLERS int "Number of event handlers" @@ -74,6 +103,10 @@ config NRFX_GPIOTE_NUM_OF_EVT_HANDLERS Specifies number of handlers that can be registered to nrfx_gpiote driver by the user. +config NRFX_GRTC + bool "GRTC driver" + depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_GRTC)) + config NRFX_I2S bool @@ -389,6 +422,41 @@ config NRFX_TIMER4 depends on $(dt_nodelabel_has_compat,timer4,$(DT_COMPAT_NORDIC_NRF_TIMER)) select NRFX_TIMER +config NRFX_TIMER00 + bool "TIMER00 driver instance" + depends on $(dt_nodelabel_has_compat,timer00,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER10 + bool "TIMER10 driver instance" + depends on $(dt_nodelabel_has_compat,timer10,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER20 + bool "TIMER20 driver instance" + depends on $(dt_nodelabel_has_compat,timer20,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER21 + bool "TIMER21 driver instance" + depends on $(dt_nodelabel_has_compat,timer21,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER22 + bool "TIMER22 driver instance" + depends on $(dt_nodelabel_has_compat,timer22,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER23 + bool "TIMER23 driver instance" + depends on $(dt_nodelabel_has_compat,timer23,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER24 + bool "TIMER24 driver instance" + depends on $(dt_nodelabel_has_compat,timer24,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + config NRFX_TWI bool @@ -544,6 +612,97 @@ config NRFX_UARTE3 depends on $(dt_nodelabel_has_compat,uart3,$(DT_COMPAT_NORDIC_NRF_UARTE)) select NRFX_UARTE +config NRFX_UARTE00 + bool "UARTE00 driver instance" + depends on $(dt_nodelabel_has_compat,uart00,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE20 + bool "UARTE20 driver instance" + depends on $(dt_nodelabel_has_compat,uart20,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE21 + bool "UARTE21 driver instance" + depends on $(dt_nodelabel_has_compat,uart21,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE22 + bool "UARTE22 driver instance" + depends on $(dt_nodelabel_has_compat,uart22,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE30 + bool "UARTE30 driver instance" + depends on $(dt_nodelabel_has_compat,uart30,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE120 + bool "UARTE120 driver instance" + depends on $(dt_nodelabel_has_compat,uart120,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE130 + bool "UARTE130 driver instance" + depends on $(dt_nodelabel_has_compat,uart130,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE131 + bool "UARTE131 driver instance" + depends on $(dt_nodelabel_has_compat,uart131,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE132 + bool "UARTE132 driver instance" + depends on $(dt_nodelabel_has_compat,uart132,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE133 + bool "UARTE133 driver instance" + depends on $(dt_nodelabel_has_compat,uart133,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE134 + bool "UARTE134 driver instance" + depends on $(dt_nodelabel_has_compat,uart134,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE135 + bool "UARTE135 driver instance" + depends on $(dt_nodelabel_has_compat,uart135,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE136 + bool "UARTE136 driver instance" + depends on $(dt_nodelabel_has_compat,uart136,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE137 + bool "UARTE137 driver instance" + depends on $(dt_nodelabel_has_compat,uart137,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG + bool "UARTE GPIO configuration support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG + bool "UARTE PSEL configuration support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_TX_LINK + bool "UARTE TX transfer linking support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + bool "UARTE RX caching support" + default y if $(dt_nodelabel_has_compat,ram3x,$(DT_COMPAT_MMIO_SRAM)) + depends on NRFX_UARTE + help + Feature might be enabled on platforms which has limitations regarding addresses + to which receiver can write data. If enabled then internal driver buffers + (cache buffers) are used for DMA transfers and data is copied to the user buffer. + config NRFX_USBREG bool "USBREG driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_USBREG)) @@ -561,6 +720,21 @@ config NRFX_WDT1 depends on $(dt_nodelabel_has_compat,wdt1,$(DT_COMPAT_NORDIC_NRF_WDT)) select NRFX_WDT +config NRFX_WDT30 + bool "WDT30 driver instance" + depends on $(dt_nodelabel_has_compat,wdt30,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT31 + bool "WDT31 driver instance" + depends on $(dt_nodelabel_has_compat,wdt31,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT130 + bool "WDT130 driver instance" + depends on $(dt_nodelabel_has_compat,wdt130,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + menu "Peripheral Resource Sharing module" config NRFX_PRS diff --git a/modules/hal_nordic/nrfx/Kconfig.logging b/modules/hal_nordic/nrfx/Kconfig.logging index 7f7b785e70c7..b24d683d3de1 100644 --- a/modules/hal_nordic/nrfx/Kconfig.logging +++ b/modules/hal_nordic/nrfx/Kconfig.logging @@ -28,6 +28,10 @@ config NRFX_GPIOTE_LOG bool "GPIOTE driver logging" depends on NRFX_GPIOTE +config NRFX_GRTC_LOG + bool "GRTC driver logging" + depends on NRFX_GRTC + config NRFX_I2S_LOG bool "I2S driver logging" depends on NRFX_I2S diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index aaf317510042..26d662be39d5 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -9,12 +9,6 @@ #include -/* - * NRFX API version 2.10 flag. - * When the flag is set NRFX API is compatible with the newest NRFX release. - */ -#define NRFX_CONFIG_API_VER_2_10 1 - /* * These are mappings of Kconfig options enabling nrfx drivers and particular * peripheral instances to the corresponding symbols used inside of nrfx. @@ -115,17 +109,33 @@ #define NRFX_EGU5_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_NRFX_GPIOTE #define NRFX_GPIOTE_ENABLED 1 -#if (defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_SERIES_NRF53X)) \ - && defined(NRF_TRUSTZONE_NONSECURE) -#define NRFX_GPIOTE1_ENABLED 1 -#else +#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_GPIOTE_LOG -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 1 +#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 @@ -441,6 +451,27 @@ #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_TWI #define NRFX_TWI_ENABLED 1 @@ -560,6 +591,60 @@ #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 @@ -580,12 +665,23 @@ #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_WDT130 +#define NRFX_WDT130_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 defined(CONFIG_SOC_SERIES_BSIM_NRFXX) @@ -606,6 +702,27 @@ #define NRF_PERIPH(P) P##_S #endif +/* 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_CONFIG_BIT_DT(node_id, prop, idx) \ + BIT(DT_PROP_BY_IDX(node_id, prop, idx)) +#define NRFX_CONFIG_GRTC_MASK_DT(prop) \ + (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST(0, nordic_nrf_grtc), prop), \ + (DT_FOREACH_PROP_ELEM_SEP(DT_INST(0, nordic_nrf_grtc), prop, \ + NRFX_CONFIG_BIT_DT, (|))), \ + (0))) + +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK \ + (NRFX_CONFIG_GRTC_MASK_DT(owned_channels) & \ + ~NRFX_CONFIG_GRTC_MASK_DT(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) */ + #include #if defined(NRF51) #include @@ -627,8 +744,16 @@ #include #elif defined(NRF5340_XXAA_NETWORK) #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(NRF9120_XXAA) || defined(NRF9160_XXAA) #include +#elif defined(NRF54L15_ENGA_XXAA) && defined(NRF_APPLICATION) + #include #else #error "Unknown device." #endif diff --git a/modules/hal_nordic/nrfx/nrfx_config_common.h b/modules/hal_nordic/nrfx/nrfx_config_common.h index 8c0a58713a05..28a3a15b0def 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_common.h +++ b/modules/hal_nordic/nrfx/nrfx_config_common.h @@ -18,7 +18,7 @@ /** @brief Symbol specifying minor version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MINOR -#define NRFX_CONFIG_API_VER_MINOR 0 +#define NRFX_CONFIG_API_VER_MINOR 2 #endif /** @brief Symbol specifying micro version of the nrfx API to be used. */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h index 4a42f92ca98f..18bcc40b2ac3 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h @@ -83,6 +83,7 @@ * 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 @@ -91,20 +92,14 @@ #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 -/* Fixups for the GPIOTE driver. */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#else -#define NRF_GPIOTE NRF_GPIOTE0 -#endif - - /** * @brief NRFX_DEFAULT_IRQ_PRIORITY * diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h new file mode 100644 index 000000000000..e6c79341b9ab --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h @@ -0,0 +1,1935 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_APPLICATION_H__ +#define NRFX_CONFIG_NRF54H20_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_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_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_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_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_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_ENGA_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h new file mode 100644 index 000000000000..369fe18a81f3 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h @@ -0,0 +1,1855 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_PPR_H__ +#define NRFX_CONFIG_NRF54H20_ENGA_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 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_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_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_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_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_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_ENGA_PPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h new file mode 100644 index 000000000000..7b9a1c4b7336 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h @@ -0,0 +1,2016 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_RADIOCORE_H__ +#define NRFX_CONFIG_NRF54H20_ENGA_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_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_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_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_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_ENGA_RADIOCORE_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h new file mode 100644 index 000000000000..a694a07955d8 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h @@ -0,0 +1,1522 @@ +/* + * 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_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 0 +#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 0 +#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 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 0 +#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 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 + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_EGU_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_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_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 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_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 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 0 +#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 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_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 11 +#endif + +/** + * @brief GRTC CC channels ownership mask. + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000007ff +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#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 0 +#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 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 0 +#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 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 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID + * + * Boolean. Accepted values 0 and 1. + */ +#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 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 0 +#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 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 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_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_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 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#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_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 0 +#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 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#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_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 0 +#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 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#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_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 0 +#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 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 0 +#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 0 +#endif + +/** + * @brief NRFX_SPI_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI_ENABLED +#define NRFX_SPI_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI00_ENABLED +#define NRFX_SPI00_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI20_ENABLED +#define NRFX_SPI20_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI21_ENABLED +#define NRFX_SPI21_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI22_ENABLED +#define NRFX_SPI22_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI30_ENABLED +#define NRFX_SPI30_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 0 +#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 0 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#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_SPIM_EXTENDED_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM_EXTENDED_ENABLED +#define NRFX_SPIM_EXTENDED_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 0 +#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 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#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_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 0 +#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 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 0 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_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_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 0 +#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 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#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_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 0 +#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 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS00_ENABLED +#define NRFX_TWIS00_ENABLED 0 +#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_TWIS_ASSUME_INIT_AFTER_RESET_ONLY + * + * 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 + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 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 0 +#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_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 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#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_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 0 +#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 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#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 + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 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 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 0 +#endif + +#endif /* NRFX_CONFIG_NRF54L15_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h index 873be583a35b..c6029a186284 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h @@ -67,25 +67,21 @@ * 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 -/* Fixups for the GPIOTE driver. */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#else -#define NRF_GPIOTE NRF_GPIOTE0 -#endif - /** * @brief NRFX_DEFAULT_IRQ_PRIORITY * diff --git a/modules/hal_nordic/nrfx/nrfx_glue.h b/modules/hal_nordic/nrfx/nrfx_glue.h index 2257ea879a3d..0edda4401124 100644 --- a/modules/hal_nordic/nrfx/nrfx_glue.h +++ b/modules/hal_nordic/nrfx/nrfx_glue.h @@ -7,6 +7,13 @@ #ifndef NRFX_GLUE_H__ #define NRFX_GLUE_H__ +#if defined(CONFIG_CPU_CORTEX_M) +/* Workaround for missing __ICACHE_PRESENT and __DCACHE_PRESENT symbols in MDK + * SoC definitions. To be removed when this is fixed. + */ +#include +#endif + #include #include #include @@ -35,6 +42,11 @@ extern "C" { #define NRFX_ASSERT(expression) __ASSERT_NO_MSG(expression) #endif +#if defined(CONFIG_RISCV) +/* included here due to dependency on NRFX_ASSERT definition */ +#include +#endif + /** * @brief Macro for placing a compile time assertion. * @@ -84,14 +96,22 @@ extern "C" { * * @param irq_number IRQ number. */ -#define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_PENDING_SET(irq_number) nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number) +#endif /** * @brief Macro for clearing the pending status of a specific IRQ. * * @param irq_number IRQ number. */ -#define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_PENDING_CLEAR(irq_number) nrf_vpr_clic_int_pending_clear(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number) +#endif /** * @brief Macro for checking the pending status of a specific IRQ. @@ -99,7 +119,11 @@ extern "C" { * @retval true If the IRQ is pending. * @retval false Otherwise. */ -#define NRFX_IRQ_IS_PENDING(irq_number) (NVIC_GetPendingIRQ(irq_number) == 1) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_IS_PENDING(irq_number) nrf_vpr_clic_int_pending_check(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_IS_PENDING(irq_number) (NVIC_GetPendingIRQ(irq_number) == 1) +#endif /** @brief Macro for entering into a critical section. */ #define NRFX_CRITICAL_SECTION_ENTER() { unsigned int irq_lock_key = irq_lock(); diff --git a/modules/mbedtls/CMakeLists.txt b/modules/mbedtls/CMakeLists.txt index f061605c0270..a6277f654b52 100644 --- a/modules/mbedtls/CMakeLists.txt +++ b/modules/mbedtls/CMakeLists.txt @@ -16,9 +16,17 @@ zephyr_interface_library_named(mbedTLS) MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" ) + if (CONFIG_BUILD_WITH_TFM) + target_include_directories(mbedTLS INTERFACE + $/api_ns/interface/include + ) + endif() + # Add regular includes target_include_directories(mbedTLS INTERFACE ${ZEPHYR_CURRENT_MODULE_DIR}/include + ${ZEPHYR_CURRENT_MODULE_DIR}/include/library + ${ZEPHYR_CURRENT_MODULE_DIR}/library configs include ) @@ -28,30 +36,24 @@ zephyr_interface_library_named(mbedTLS) # Base mbed TLS files list(APPEND mbedtls_base_src + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aes.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aesni.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aria.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1parse.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1write.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/base64.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_core.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod_raw.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/nist_kw.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/oid.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/padlock.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform_util.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/version.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/constant_time.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aes.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aesni.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aria.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/camellia.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ccm.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/chacha20.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/chachapoly.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher_wrap.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/cmac.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/constant_time.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ctr_drbg.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/debug.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/des.c @@ -59,22 +61,27 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdh.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdsa.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecjpake.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp_curves_new.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp_curves.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy_poll.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/error.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/gcm.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/hash_info.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/hkdf.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/hmac_drbg.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/lmots.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/lms.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/md5.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/md.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/md5.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/memory_buffer_alloc.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_reader.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_trace.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/nist_kw.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/oid.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/padlock.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform_util.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/poly1305.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_util.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ripemd160.c @@ -86,6 +93,7 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/threading.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/timing.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/version_features.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/version.c zephyr_init.c ) @@ -107,11 +115,11 @@ zephyr_interface_library_named(mbedTLS) zephyr_library_named(mbedTLSCrypto) - if (CONFIG_MBEDTLS_PSA_CRYPTO_C) + if (CONFIG_MBEDTLS_PSA_CRYPTO_C AND NOT CONFIG_BUILD_WITH_TFM) list(APPEND crypto_source ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_aead.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_cipher.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_driver_wrappers.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_driver_wrappers_no_static.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_ecp.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_hash.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_mac.c @@ -119,11 +127,6 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_se.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_storage.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_its_file.c - ) - endif() - - if (NOT CONFIG_BUILD_WITH_TFM) - list(APPEND crypto_source ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_client.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_slot_management.c diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 67277fb24c40..2a05ee28d36c 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -5,6 +5,7 @@ config ZEPHYR_MBEDTLS_MODULE bool + config MBEDTLS_PROMPTLESS bool help @@ -13,7 +14,6 @@ config MBEDTLS_PROMPTLESS mbed TLS menu prompt and instead handle the selection of MBEDTLS from dependent sub-configurations and thus prevent stuck symbol behavior. - menuconfig MBEDTLS bool "mbed TLS Support" if !MBEDTLS_PROMPTLESS help @@ -27,6 +27,7 @@ choice MBEDTLS_IMPLEMENTATION config MBEDTLS_BUILTIN bool "Use Zephyr in-tree mbedTLS version" + depends on ! DISABLE_MBEDTLS_BUILTIN help Link with mbedTLS sources included with Zephyr distribution. Included mbedTLS version is well integrated with and supported @@ -40,6 +41,11 @@ config MBEDTLS_LIBRARY endchoice +# subsystems cannot deselect MBEDTLS_BUILTIN, but they can select +# DISABLE_MBEDTLS_BUILTIN. +config DISABLE_MBEDTLS_BUILTIN + bool + config CUSTOM_MBEDTLS_CFG_FILE bool "Custom mbed TLS configuration file" help @@ -233,3 +239,6 @@ config APP_LINK_WITH_MBEDTLS issues for 'app'. endif # MBEDTLS + +# Add PSA configurations +rsource "Kconfig.psa" diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa new file mode 100644 index 000000000000..831aca736764 --- /dev/null +++ b/modules/mbedtls/Kconfig.psa @@ -0,0 +1,758 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# +menu "PSA RNG support" + +config PSA_WANT_GENERATE_RANDOM + bool + prompt "PSA RNG support" + help + Provide random number generator (RNG) support. + +config PSA_WANT_ALG_CTR_DRBG + bool + prompt "PSA RNG using CTR-DRBG as PRNG" + help + Provide random number generator (RNG) using CTR-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). + +config PSA_WANT_ALG_HMAC_DRBG + bool + prompt "PSA RNG using HMAC-DRBG as PRNG" + help + Provide random number generator (RNG) using HMAC-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). + +endmenu # RNG support + +menu "PSA key type support" + +config PSA_HAS_KEY_SUPPORT + bool + default y + depends on PSA_WANT_KEY_TYPE_DERIVE || \ + PSA_WANT_KEY_TYPE_HMAC || \ + PSA_WANT_KEY_TYPE_RAW_DATA || \ + PSA_WANT_KEY_TYPE_PASSWORD || \ + PSA_WANT_KEY_TYPE_PASSWORD_HASH || \ + PSA_WANT_KEY_TYPE_PEPPER || \ + PSA_WANT_KEY_TYPE_AES || \ + PSA_WANT_KEY_TYPE_ARIA || \ + PSA_WANT_KEY_TYPE_DES || \ + PSA_WANT_KEY_TYPE_CAMELLIA || \ + PSA_WANT_KEY_TYPE_SM4 || \ + PSA_WANT_KEY_TYPE_ARC4 || \ + PSA_WANT_KEY_TYPE_CHACHA20 || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + +config PSA_WANT_KEY_TYPE_DERIVE + bool "PSA derive key type support" + help + This key type is for high-entropy secrets only. + For low-entropy secrets, password key type should be used instead. + +config PSA_WANT_KEY_TYPE_RAW_DATA + bool "PSA raw data key type support" + help + A "key" of this type cannot be used for any cryptographic operation. + Applications can use this type to store arbitrary data in the keystore. + +config PSA_WANT_KEY_TYPE_HMAC + bool "PSA HMAC key type support" + help + HMAC key. + +config PSA_WANT_KEY_TYPE_PASSWORD + bool "PSA password key type support" + help + A low-entropy secret for password hashing or key derivation. + +config PSA_WANT_KEY_TYPE_PASSWORD_HASH + bool "PSA password hash key type support" + help + A secret value that can be used to verify a password hash. + +config PSA_WANT_KEY_TYPE_PEPPER + bool "PSA pepper key type support" + help + A secret value that can be used when computing a password hash. + +config PSA_WANT_KEY_TYPE_AES + bool "PSA AES key type support" + help + Key for cipher, AEAD or MAC algorithm based on the AES block cipher. + +config PSA_WANT_KEY_TYPE_ARIA + bool "PSA ARIA key type support" + +config PSA_WANT_KEY_TYPE_DES + bool "PSA DES key type support (weak)" + help + Warning: Single DES and 2-key 3DES are weak and strongly deprecated + and are only recommended for decrypting legacy data. + 3-key 3DES is weak and deprecated and is only recommended for use in + legacy protocols. + +config PSA_WANT_KEY_TYPE_CAMELLIA + bool "PSA CAMELLIA key type support" + +config PSA_WANT_KEY_TYPE_SM4 + bool "PSA SM4 key type support" + +config PSA_WANT_KEY_TYPE_ARC4 + bool "PSA ARC4 key type support (weak)" + help + Warning: The ARC4 cipher is weak and deprecated and is only + recommended for use in legacy protocols. + +config PSA_WANT_KEY_TYPE_CHACHA20 + bool "PSA ChaCha20 key type support" + default y + depends on PSA_WANT_ALG_CHACHA20_POLY1305 || \ + PSA_WANT_ALG_STREAM_CIPHER + help + Key for the ChaCha20 stream cipher or the ChaCha20-Poly1305 AEAD algorithm. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + bool "PSA ECC key pair support" + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + bool "PSA ECC public key support" + help + Elliptic curve public key. + + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + bool "PSA ECC import key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: import for both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT + bool "PSA ECC export key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: export for both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE + bool "PSA ECC generate key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: generate for both the private and public key. + +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 + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE + bool + default y + depends on PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + bool "PSA RSA key pair type support" + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + bool "PSA RSA public key support" + help + RSA public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT + bool "PSA RSA key pair import key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: import key for both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT + bool "PSA RSA key pair export key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: export key for both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE + bool "PSA RSA key pair generate key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: key generation for both the private and public key. + +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 + bool "PSA DH key pair type support" + select PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + help + Finite-field Diffie-Hellman key pair: both the private key and public key. + +config PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + bool "PSA DH public key support" + help + Finite-field Diffie-Hellman public key. + +endmenu # PSA Key type support + +menu "PSA AEAD support" + +config PSA_HAS_AEAD_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CCM || \ + PSA_WANT_ALG_GCM || \ + PSA_WANT_ALG_CHACHA20_POLY1305 + help + Prompt-less configuration that states that AEAD is supported. + +config PSA_WANT_ALG_CCM + bool + prompt "PSA CCM support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_GCM + bool + prompt "PSA GCM support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CHACHA20_POLY1305 + bool + prompt "PSA ChaCha20-Poly1305 support" if !PSA_PROMPTLESS + +endmenu # PSA AEAD support + + +menu "PSA MAC support" + +config PSA_HAS_MAC_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CBC_MAC || \ + PSA_WANT_ALG_CMAC || \ + PSA_WANT_ALG_HMAC + help + Prompt-less configuration that states that MAC is supported. + +config PSA_WANT_ALG_CBC_MAC + bool + prompt "PSA CBC-MAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CMAC + bool + prompt "PSA CMAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_HMAC + bool + prompt "PSA HMAC support" if !PSA_PROMPTLESS + +endmenu # PSA MAC support + + +menu "PSA Hash support" + +config PSA_HAS_HASH_SUPPORT + bool + default y + depends on PSA_WANT_ALG_SHA_1 || \ + PSA_WANT_ALG_SHA_224 || \ + PSA_WANT_ALG_SHA_256 || \ + PSA_WANT_ALG_SHA_384 || \ + PSA_WANT_ALG_SHA_512 || \ + PSA_WANT_ALG_SHA_512_224 || \ + PSA_WANT_ALG_SHA_512_256 || \ + PSA_WANT_ALG_SHA3_224 || \ + PSA_WANT_ALG_SHA3_256 || \ + PSA_WANT_ALG_SHA3_384 || \ + PSA_WANT_ALG_SHA3_512 || \ + PSA_WANT_ALG_SM3 || \ + PSA_WANT_ALG_SHAKE256_512 || \ + PSA_WANT_ALG_RIPEMD160 || \ + PSA_WANT_ALG_MD2 || \ + PSA_WANT_ALG_MD4 || \ + PSA_WANT_ALG_MD5 + help + Prompt-less configuration that states that hash is supported. + +config PSA_WANT_ALG_SHA_1 + bool + prompt "PSA SHA-1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The SHA-1 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_SHA_224 + bool + prompt "PSA SHA-224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_256 + bool + prompt "PSA SHA-256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_384 + bool + prompt "PSA SHA-384 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512 + bool + prompt "PSA SHA-512 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512_224 + bool + prompt "PSA SHA-512/224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512_256 + bool + prompt "PSA SHA-512/256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_224 + bool + prompt "PSA SHA3-224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_256 + bool + prompt "PSA SHA3-256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_384 + bool + prompt "PSA SHA3-384 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_512 + bool + prompt "PSA SHA3-512 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SM3 + bool + prompt "PSA SM3 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHAKE256_512 + bool + prompt "PSA SHAKE256 512 bits support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RIPEMD160 + bool + prompt "PSA RIPEMD-160 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_MD2 + bool + prompt "PSA MD2 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD2 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_MD4 + bool + prompt "PSA MD4 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD4 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_MD5 + bool + prompt "PSA MD5 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD5 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +endmenu # PSA Hash support + +menu "PSA Cipher support" + +config PSA_HAS_CIPHER_SUPPORT + bool + default y + depends on PSA_WANT_ALG_ECB_NO_PADDING || \ + PSA_WANT_ALG_CBC_NO_PADDING || \ + PSA_WANT_ALG_CBC_PKCS7 || \ + PSA_WANT_ALG_CCM_STAR_NO_TAG || \ + PSA_WANT_ALG_CFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_OFB || \ + PSA_WANT_ALG_XTS || \ + PSA_WANT_ALG_STREAM_CIPHER + help + Prompt-less configuration that states that cipher is supported. + +config PSA_WANT_ALG_ECB_NO_PADDING + bool + prompt "PSA ECB block cipher mode support (with no padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CBC_NO_PADDING + bool + prompt "PSA CBC block cipher mode support (with no padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CBC_PKCS7 + bool + prompt "PSA CBC block cipher mode support (with PKCS#7 padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CFB + bool + prompt "PSA stream cipher using CFB block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CTR + bool + prompt "PSA stream cipher using CTR block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_OFB + bool + prompt "PSA stream cipher using OFB block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_XTS + bool + prompt "PSA XTS block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CCM_STAR_NO_TAG + bool + prompt "PSA CCM* with no tag support" if !PSA_PROMPTLESS + help + Unauthenticated version of CCM. Uses the cipher API instead of the AEAD API. + +config PSA_WANT_ALG_STREAM_CIPHER + bool + prompt "PSA stream cipher support" if !PSA_PROMPTLESS + +endmenu # PSA Cipher Support + +menu "PSA Key agreement support" + +config PSA_HAS_KEY_AGREEMENT + bool + default y + depends on PSA_WANT_ALG_ECDH + depends on PSA_WANT_ALG_FFDH + help + Promt-less configuration that states that key agreement is supported. + +config PSA_WANT_ALG_ECDH + bool + prompt "PSA ECDH support" if !PSA_PROMPTLESS + + +config PSA_WANT_ALG_FFDH + bool + prompt "PSA FFDH support" if !PSA_PROMPTLESS + +endmenu # PSA Key agreement support + +menu "PSA Key derivation support" + +config PSA_HAS_KEY_DERIVATION + bool + default y + depends on PSA_WANT_ALG_HKDF || \ + PSA_WANT_ALG_HKDF_EXPAND || \ + PSA_WANT_ALG_HKDF_EXTRACT || \ + PSA_WANT_ALG_PBKDF2_HMAC || \ + PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 || \ + PSA_WANT_ALG_TLS12_PRF || \ + PSA_WANT_ALG_TLS12_PSK_TO_MS || \ + PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + help + Prompt-less configuration that states that key derivation is supported. + +config PSA_WANT_ALG_HKDF + bool + prompt "PSA HKDF support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_HKDF_EXTRACT + bool + prompt "PSA HKDF extract support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_HKDF_EXPAND + bool + prompt "PSA HKDF expand support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_PBKDF2_HMAC + bool + prompt "PSA PBKDF2 HMAC support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 + bool + prompt "PSA PBKDF2-AES-CMAC-PRF-128 support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_CMAC + +config PSA_WANT_ALG_TLS12_PRF + bool + prompt "PSA PRF support (TLS1.2)" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_TLS12_PSK_TO_MS + bool + prompt "PSA TLS 1.2 PSK to MS support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + bool + prompt "PSA TLS 1.2 EC J-PAKE to PMS support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_SHA_256 + +endmenu # PSA Key derivation support + + +menu "PSA Asymmetric support" + +config PSA_HAS_ASYM_ENCRYPT_SUPPORT + bool + default y + depends on PSA_WANT_ALG_RSA_OAEP || \ + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + help + Prompt-less configuration that states that asymmetric encryption + is supported. + + +config PSA_HAS_ASYM_SIGN_SUPPORT + bool + default y + depends on PSA_WANT_ALG_DETERMINISTIC_ECDSA || \ + PSA_WANT_ALG_ECDSA || \ + PSA_WANT_ALG_ECDSA_ANY || \ + PSA_WANT_ALG_PURE_EDDSA || \ + PSA_WANT_ALG_ED25519PH || \ + PSA_WANT_ALG_ED448PH || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW || \ + PSA_WANT_ALG_RSA_PSS || \ + PSA_WANT_ALG_RSA_PSS_ANY_SALT + help + Prompt-less configuration that states that asymmetric signing + is supported. + +config PSA_WANT_ALG_ECDSA + bool + prompt "PSA ECDSA support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ECDSA_ANY + bool + prompt "PSA ECDSA support, without hashing" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_DETERMINISTIC_ECDSA + bool + prompt "PSA ECDSA support (deterministic mode)" if !PSA_PROMPTLESS + +menu "Elliptic Curve type support" + +config PSA_WANT_ECC_BRAINPOOL_P_R1_160 + bool + prompt "PSA ECC BrainpoolP160r1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 160-bit curve brainpoolP160r1 is weak and deprecated and + is only recommended for use in legacy protocols. + +config PSA_WANT_ECC_BRAINPOOL_P_R1_192 + bool + prompt "PSA ECC BrainpoolP192r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_224 + bool + prompt "PSA ECC BrainpoolP224r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_256 + bool + prompt "PSA ECC BrainpoolP256r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_320 + bool + prompt "PSA ECC BrainpoolP320r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_384 + bool + prompt "PSA ECC BrainpoolP384r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_512 + bool + prompt "PSA ECC BrainpoolP512r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_MONTGOMERY_255 + bool + prompt "PSA ECC Curve25519 (X25519) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_MONTGOMERY_448 + bool + prompt "PSA ECC Curve448 (X448) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_TWISTED_EDWARDS_255 + bool + prompt "PSA ECC Edwards25519 (Ed25519) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_TWISTED_EDWARDS_448 + bool + prompt "PSA ECC Edwards448 (Ed448) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_192 + bool + prompt "PSA ECC secp192k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_224 + bool + prompt "PSA ECC secp224k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_256 + bool + prompt "PSA ECC secp256k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_192 + bool + prompt "PSA ECC secp192r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_224 + bool + prompt "PSA ECC secp224r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_256 + bool + prompt "PSA ECC secp256r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_384 + bool + prompt "PSA ECC secp384r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_521 + bool + prompt "PSA ECC secp521r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R2_160 + bool + prompt "PSA ECC secp160r2 support (weak)" if !PSA_PROMPTLESS + help + Warning: his family of curves is weak and deprecated. + +config PSA_WANT_ECC_SECT_K1_163 + bool + prompt "PSA ECC sect163k1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163k1 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_SECT_K1_233 + bool + prompt "PSA ECC sect233k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_239 + bool + prompt "PSA ECC sect239k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_283 + bool + prompt "PSA ECC sect283k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_409 + bool + prompt "PSA ECC sect409k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_571 + bool + prompt "PSA ECC sect571k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_163 + bool + prompt "PSA ECC sect163r1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163r1 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_SECT_R1_233 + bool + prompt "PSA ECC sect233r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_283 + bool + prompt "PSA ECC sect283r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_409 + bool + prompt "PSA ECC sect409r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_571 + bool + prompt "PSA ECC sect571r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R2_163 + bool + prompt "PSA ECC sect163r2 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163r2 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_FRP_V1_256 + bool + prompt "PSA ECC FRP256v1 support" if !PSA_PROMPTLESS + +endmenu # Elliptic Curve type support + +config PSA_WANT_ALG_RSA_OAEP + bool + prompt "PSA RSA OAEP asymmetric encryption support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + bool + prompt "PSA RSA PKCS#1 v1.5 asymmetric encryption support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN + bool + prompt "PSA RSA PKCS#1 v1.5 message signature support, with hashing" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW + bool + prompt "PSA RSA raw PKCS#1 v1.5 message signature support, without hashing)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PSS + bool + prompt "PSA RSA PSS message signature support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PSS_ANY_SALT + bool + prompt "PSA RSA PSS message signature support, any salt length" if !PSA_PROMPTLESS + +endmenu # PSA Asymmetric support + +config PSA_WANT_ALG_JPAKE + bool + prompt "PSA EC J-PAKE support" if !PSA_PROMPTLESS + select EXPERIMENTAL if !NET_L2_OPENTHREAD + +config PSA_WANT_ALG_SPAKE2P + bool + prompt "PSA SPAKE2+ support" if !PSA_PROMPTLESS + select EXPERIMENTAL if !CHIP + +config PSA_WANT_ALG_SRP_6 + bool + prompt "PSA SRP-6 support" if !PSA_PROMPTLESS + select EXPERIMENTAL + +config PSA_WANT_ALG_PURE_EDDSA + bool + prompt "PSA PURE_EDDSA support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED25519PH + bool + prompt "PSA ED25519PH support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED448PH + bool + prompt "PSA ED448PH support" if !PSA_PROMPTLESS diff --git a/modules/mbedtls/Kconfig.tls-generic b/modules/mbedtls/Kconfig.tls-generic index 3c0e17c0fe35..d629c1b1d2a0 100644 --- a/modules/mbedtls/Kconfig.tls-generic +++ b/modules/mbedtls/Kconfig.tls-generic @@ -9,6 +9,8 @@ menu "TLS configuration" menu "Supported TLS version" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_TLS_VERSION_1_0 bool "Support for TLS 1.0" select MBEDTLS_CIPHER @@ -33,6 +35,8 @@ config MBEDTLS_DTLS bool "Support for DTLS" depends on MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 +endif + config MBEDTLS_SSL_EXPORT_KEYS bool "Support for exporting SSL key block and master secret" depends on MBEDTLS_TLS_VERSION_1_0 || MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 @@ -47,6 +51,8 @@ menu "Ciphersuite configuration" comment "Supported key exchange modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_ALL_ENABLED bool "All available ciphersuite modes" select MBEDTLS_KEY_EXCHANGE_PSK_ENABLED @@ -81,6 +87,8 @@ config MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +endif + config MBEDTLS_PSK_MAX_LEN int "Max size of TLS pre-shared keys" default 32 @@ -88,6 +96,8 @@ config MBEDTLS_PSK_MAX_LEN help Max size of TLS pre-shared keys, in bytes. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_RSA_ENABLED bool "RSA-only based ciphersuite modes" default y if !NET_L2_OPENTHREAD @@ -202,6 +212,7 @@ config MBEDTLS_ECP_NIST_OPTIM bool "NSIT curves optimization" endif +endif # !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) comment "Supported hash" @@ -226,6 +237,8 @@ config MBEDTLS_HASH_SHA512_ENABLED comment "Supported cipher modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CIPHER_ALL_ENABLED bool "All available ciphers" select MBEDTLS_CIPHER_AES_ENABLED @@ -299,8 +312,12 @@ config MBEDTLS_CHACHAPOLY_AEAD_ENABLED bool "ChaCha20-Poly1305 AEAD algorithm" depends on MBEDTLS_CIPHER_CHACHA20_ENABLED || MBEDTLS_MAC_POLY1305_ENABLED +endif + comment "Supported message authentication methods" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MAC_ALL_ENABLED bool "All available MAC methods" select MBEDTLS_MAC_MD4_ENABLED @@ -349,10 +366,14 @@ config MBEDTLS_MAC_CMAC_ENABLED bool "CMAC (Cipher-based Message Authentication Code) mode for block ciphers." depends on MBEDTLS_CIPHER_AES_ENABLED || MBEDTLS_CIPHER_DES_ENABLED +endif + endmenu comment "Random number generators" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CTR_DRBG_ENABLED bool "CTR_DRBG AES-256-based random generator" depends on MBEDTLS_CIPHER_AES_ENABLED @@ -362,14 +383,20 @@ config MBEDTLS_HMAC_DRBG_ENABLED bool "HMAC_DRBG random generator" select MBEDTLS_MD +endif + comment "Other configurations" config MBEDTLS_CIPHER bool "generic cipher layer." +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MD bool "generic message digest layer." +endif + config MBEDTLS_GENPRIME_ENABLED bool "prime-number generation code." @@ -387,11 +414,15 @@ config MBEDTLS_HAVE_ASM of asymmetric cryptography, however this might have an impact on the code size. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_ENTROPY_ENABLED bool "MbedTLS generic entropy pool" depends on MBEDTLS_MAC_SHA256_ENABLED || MBEDTLS_MAC_SHA384_ENABLED || MBEDTLS_MAC_SHA512_ENABLED default y if MBEDTLS_ZEPHYR_ENTROPY +endif + config MBEDTLS_OPENTHREAD_OPTIMIZATIONS_ENABLED bool "MbedTLS optimizations for OpenThread" depends on NET_L2_OPENTHREAD diff --git a/modules/mbedtls/configs/config-mini-tls1_1.h b/modules/mbedtls/configs/config-mini-tls1_1.h index 2bce8647caf2..da8bf795c1d8 100644 --- a/modules/mbedtls/configs/config-mini-tls1_1.h +++ b/modules/mbedtls/configs/config-mini-tls1_1.h @@ -59,6 +59,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_CIPHER_MODE_CBC diff --git a/modules/mbedtls/configs/config-no-entropy.h b/modules/mbedtls/configs/config-no-entropy.h index b5295bf1fb7b..b3406a394b42 100644 --- a/modules/mbedtls/configs/config-no-entropy.h +++ b/modules/mbedtls/configs/config-no-entropy.h @@ -62,6 +62,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_CIPHER_MODE_CBC diff --git a/modules/mbedtls/configs/config-suite-b.h b/modules/mbedtls/configs/config-suite-b.h index 6f2cc963bd14..7468f7633580 100644 --- a/modules/mbedtls/configs/config-suite-b.h +++ b/modules/mbedtls/configs/config-suite-b.h @@ -66,6 +66,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_ECP_DP_SECP256R1_ENABLED diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index 7cf85731c857..2d1b53c54fdc 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -37,6 +37,7 @@ #if defined(CONFIG_MBEDTLS_HAVE_TIME_DATE) #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE +#define MBEDTLS_PLATFORM_MS_TIME_ALT #endif #if defined(CONFIG_MBEDTLS_TEST) diff --git a/modules/mbedtls/zephyr_init.c b/modules/mbedtls/zephyr_init.c index d882b0aedb8f..49c9ffc8aff1 100644 --- a/modules/mbedtls/zephyr_init.c +++ b/modules/mbedtls/zephyr_init.c @@ -15,6 +15,8 @@ #include #include #include +#include + #include @@ -45,7 +47,7 @@ static void init_heap(void) #define init_heap(...) #endif /* CONFIG_MBEDTLS_ENABLE_HEAP && MBEDTLS_MEMORY_BUFFER_ALLOC_C */ -#if defined(CONFIG_MBEDTLS_ZEPHYR_ENTROPY) +#if defined(CONFIG_MBEDTLS_ZEPHYR_ENTROPY) && !defined(CONFIG_NRF_CC3XX_PLATFORM) static const struct device *const entropy_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); @@ -107,3 +109,9 @@ int mbedtls_init(void) { return _mbedtls_init(); } + +/* TLS 1.3 ticket lifetime needs a timing interface */ +mbedtls_ms_time_t mbedtls_ms_time(void) +{ + return (mbedtls_ms_time_t)k_uptime_get(); +} diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 2b2b593f82f7..5b64d3be2f5f 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -3,10 +3,19 @@ if(CONFIG_OPENTHREAD_SOURCES) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +macro(kconfig_to_ot_option kconfig_option ot_config description) + if(${kconfig_option}) + set(${ot_config} ON CACHE BOOL "${description}" FORCE) + else() + set(${ot_config} OFF CACHE BOOL "${description}" FORCE) + endif() +endmacro() + # OpenThread options set(OT_BUILD_EXECUTABLES OFF CACHE BOOL "Disable OpenThread samples") set(OT_BUILTIN_MBEDTLS_MANAGEMENT OFF CACHE BOOL "Use Zephyr's mbedTLS heap") set(OT_PLATFORM "zephyr" CACHE STRING "Zephyr as a target platform") +set(OT_PLATFORM_POWER_CALIBRATION OFF CACHE BOOL "Use Zephyr's power calibration handled by Radio Driver") set(OT_THREAD_VERSION ${CONFIG_OPENTHREAD_THREAD_VERSION} CACHE STRING "User selected Thread stack version") set(OT_CLI_TRANSPORT "CONSOLE" CACHE STRING "Set CLI to use console interpreter") @@ -28,476 +37,96 @@ elseif(CONFIG_OPENTHREAD_MTD) set(OT_MTD ON CACHE BOOL "Enable MTD" FORCE) endif() -if(CONFIG_OPENTHREAD_ANYCAST_LOCATOR) - set(OT_ANYCAST_LOCATOR ON CACHE BOOL "Enable anycast locator" FORCE) -else() - set(OT_ANYCAST_LOCATOR OFF CACHE BOOL "Enable anycast locator" FORCE) -endif() - -if(CONFIG_ASSERT) - set(OT_ASSERT ON CACHE BOOL "Enable assert function OT_ASSERT()" FORCE) -else() - set(OT_ASSERT OFF CACHE BOOL "Enable assert function OT_ASSERT()" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER) - set(OT_BACKBONE_ROUTER ON CACHE BOOL "Enable backbone router functionality" FORCE) -else() - set(OT_BACKBONE_ROUTER OFF CACHE BOOL "Enable backbone router functionality" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING) - set(OT_BACKBONE_ROUTER_DUA_NDPROXYING ON CACHE BOOL "Enable BBR DUA ND Proxy support" FORCE) -else() - set(OT_BACKBONE_ROUTER_DUA_NDPROXYING OFF CACHE BOOL "Enable BBR DUA ND Proxy support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING) - set(OT_BACKBONE_ROUTER_MULTICAST_ROUTING ON CACHE BOOL "Enable BBR MR support" FORCE) -else() - set(OT_BACKBONE_ROUTER_MULTICAST_ROUTING OFF CACHE BOOL "Enable BBR MR support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_AGENT) - set(OT_BORDER_AGENT ON CACHE BOOL "Enable Border Agent" FORCE) -else() - set(OT_BORDER_AGENT OFF CACHE BOOL "Enable Border Agent" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTER) - set(OT_BORDER_ROUTER ON CACHE BOOL "Enable Border Router" FORCE) -else() - set(OT_BORDER_ROUTER OFF CACHE BOOL "Enable Border Router" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING) - set(OT_BORDER_ROUTING ON CACHE BOOL "Enable Border routing" FORCE) -else() - set(OT_BORDER_ROUTING OFF CACHE BOOL "Enable Border routing" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING_COUNTERS) - set(OT_BORDER_ROUTING_COUNTERS ON CACHE BOOL "Enable Border routing counters" FORCE) -else() - set(OT_BORDER_ROUTING_COUNTERS OFF CACHE BOOL "Enable Border routing counters" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD) - set(OT_BORDER_ROUTING_DHCP6_PD ON CACHE BOOL "DHCPv6-PD support in border routing" FORCE) -else() - set(OT_BORDER_ROUTING_DHCP6_PD OFF CACHE BOOL "DHCPv6-PD support in border routing" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CHANNEL_MANAGER) - set(OT_CHANNEL_MANAGER ON CACHE BOOL "Enable channel manager support" FORCE) -else() - set(OT_CHANNEL_MANAGER OFF CACHE BOOL "Enable channel manager support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CHANNEL_MONITOR) - set(OT_CHANNEL_MONITOR ON CACHE BOOL "Enable channel monitor support" FORCE) -else() - set(OT_CHANNEL_MONITOR OFF CACHE BOOL "Enable channel monitor support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP) - set(OT_COAP ON CACHE BOOL "Enable CoAP API" FORCE) -else() - set(OT_COAP OFF CACHE BOOL "Enable CoAP API" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP_BLOCK) - set(OT_COAP_BLOCK ON CACHE BOOL "Enable CoAP Block-wise option support" FORCE) -else() - set(OT_COAP_BLOCK OFF CACHE BOOL "Enable CoAP Block-wise option support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP_OBSERVE) - set(OT_COAP_OBSERVE ON CACHE BOOL "Enable CoAP Observe option support" FORCE) -else() - set(OT_COAP_OBSERVE OFF CACHE BOOL "Enable CoAP Observe option support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAPS) - set(OT_COAPS ON CACHE BOOL "Enable secure CoAP API support" FORCE) -else() - set(OT_COAPS OFF CACHE BOOL "Enable secure CoAP API support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COMMISSIONER) - set(OT_COMMISSIONER ON CACHE BOOL "Enable Commissioner" FORCE) -else() - set(OT_COMMISSIONER OFF CACHE BOOL "Enable Commissioner" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_AUTO_SYNC) - set(OT_CSL_AUTO_SYNC ON CACHE BOOL "Enable csl autosync" FORCE) -else() - set(OT_CSL_AUTO_SYNC OFF CACHE BOOL "Enable csl autosync" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_DEBUG) - set(OT_CSL_DEBUG ON CACHE BOOL "Enable CSL debug" FORCE) -else() - set(OT_CSL_DEBUG OFF CACHE BOOL "Enable CSL debug" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_RECEIVER) - set(OT_CSL_RECEIVER ON CACHE BOOL "Enable CSL receiver feature for Thread 1.2" FORCE) -else() - set(OT_CSL_RECEIVER OFF CACHE BOOL "Enable CSL receiver feature for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC) - set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC ON CACHE BOOL "Use local time for CSL sync" FORCE) -else() - set(OT_CSL_RECEIVER_LOCAL_TIME_SYNC OFF CACHE BOOL "Use local time for CSL sync" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DATASET_UPDATER) - set(OT_DATASET_UPDATER ON CACHE BOOL "Enable Dataset updater" FORCE) -else() - set(OT_DATASET_UPDATER OFF CACHE BOOL "Enable Dataset updater" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT) - set(OT_DEVICE_PROP_LEADER_WEIGHT ON CACHE BOOL "Enable device props for leader weight" FORCE) -else() - set(OT_DEVICE_PROP_LEADER_WEIGHT OFF CACHE BOOL "Enable device props for leader weight" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DHCP6_CLIENT) - set(OT_DHCP6_CLIENT ON CACHE BOOL "Enable DHCPv6 Client" FORCE) -else() - set(OT_DHCP6_CLIENT OFF CACHE BOOL "Enable DHCPv6 Client" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DHCP6_SERVER) - set(OT_DHCP6_SERVER ON CACHE BOOL "Enable DHCPv6 Server" FORCE) -else() - set(OT_DHCP6_SERVER OFF CACHE BOOL "Enable DHCPv6 Server" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DIAG) - set(OT_DIAGNOSTIC ON CACHE BOOL "Enable Diagnostics support" FORCE) -else() - set(OT_DIAGNOSTIC OFF CACHE BOOL "Enable Diagnostics support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_CLIENT) - set(OT_DNS_CLIENT ON CACHE BOOL "Enable DNS client support" FORCE) -else() - set(OT_DNS_CLIENT OFF CACHE BOOL "Enable DNS client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_CLIENT_OVER_TCP) - set(OT_DNS_CLIENT_OVER_TCP ON CACHE BOOL "Enable dns query over tcp" FORCE) -else() - set(OT_DNS_CLIENT_OVER_TCP OFF CACHE BOOL "Enable dns query over tcp" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_DSO) - set(OT_DNS_DSO ON CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) -else() - set(OT_DNS_DSO OFF CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY) - set(OT_DNS_UPSTREAM_QUERY ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) -else() - set(OT_DNS_UPSTREAM_QUERY OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNSSD_SERVER) - set(OT_DNSSD_SERVER ON CACHE BOOL "Enable DNS-SD server support" FORCE) -else() - set(OT_DNSSD_SERVER OFF CACHE BOOL "Enable DNS-SD server support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DUA) - set(OT_DUA ON CACHE BOOL "Enable Domain Unicast Address feature for Thread 1.2" FORCE) -else() - set(OT_DUA OFF CACHE BOOL "Enable Domain Unicast Address feature for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_ECDSA) - set(OT_ECDSA ON CACHE BOOL "Enable ECDSA support" FORCE) -else() - set(OT_ECDSA OFF CACHE BOOL "Enable ECDSA support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_ENABLE_SERVICE) - set(OT_SERVICE ON CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) -else() - set(OT_SERVICE OFF CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) -endif() - -if(CONFIG_OPENTHREAD_EXTERNAL_HEAP) - set(OT_EXTERNAL_HEAP ON CACHE BOOL "Enable external heap support" FORCE) -else() - set(OT_EXTERNAL_HEAP OFF CACHE BOOL "Enable external heap support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_FIREWALL) - set(OT_FIREWALL ON CACHE BOOL "Enable firewall" FORCE) -else() - set(OT_FIREWALL OFF CACHE BOOL "Enable firewall" FORCE) -endif() - -if(CONFIG_OPENTHREAD_FULL_LOGS) - set(OT_FULL_LOGS ON CACHE BOOL "Enable full logs" FORCE) -else() - set(OT_FULL_LOGS OFF CACHE BOOL "Enable full logs" FORCE) -endif() - -if(CONFIG_OPENTHREAD_HISTORY_TRACKER) - set(OT_HISTORY_TRACKER ON CACHE BOOL "Enable history tracker support." FORCE) -else() - set(OT_HISTORY_TRACKER OFF CACHE BOOL "Enable history tracker support." FORCE) -endif() - -if(CONFIG_OPENTHREAD_IP6_FRAGM) - set(OT_IP6_FRAGM ON CACHE BOOL "Enable IPv6 fragmentation support" FORCE) -else() - set(OT_IP6_FRAGM OFF CACHE BOOL "Enable IPv6 fragmentation support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_JAM_DETECTION) - set(OT_JAM_DETECTION ON CACHE BOOL "Enable Jam Detection" FORCE) -else() - set(OT_JAM_DETECTION OFF CACHE BOOL "Enable Jam Detection" FORCE) -endif() +kconfig_to_ot_option(CONFIG_OPENTHREAD_ANYCAST_LOCATOR OT_ANYCAST_LOCATOR "Enable anycast locator") +kconfig_to_ot_option(CONFIG_ASSERT OT_ASSERT "Enable assert function OT_ASSERT()") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER OT_BACKBONE_ROUTER "Enable backbone router functionality") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING OT_BACKBONE_ROUTER_DUA_NDPROXYING "Enable BBR DUA ND Proxy support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING OT_BACKBONE_ROUTER_MULTICAST_ROUTING "Enable BBR MR support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BLE_TCAT OT_BLE_TCAT "Enable BLE TCAT support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_AGENT OT_BORDER_AGENT "Enable Border Agent") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTER OT_BORDER_ROUTER "Enable Border Router") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING OT_BORDER_ROUTING "Enable Border routing") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_COUNTERS OT_BORDER_ROUTING_COUNTERS "Enable Border routing counters") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD OT_BORDER_ROUTING_DHCP6_PD "DHCPv6-PD support in border routing") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MANAGER OT_CHANNEL_MANAGER "Enable channel manager support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MONITOR OT_CHANNEL_MONITOR "Enable channel monitor support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP OT_COAP "Enable CoAP API") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP_BLOCK OT_COAP_BLOCK "Enable CoAP Block-wise option support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP_OBSERVE OT_COAP_OBSERVE "Enable CoAP Observe option support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAPS OT_COAPS "Enable secure CoAP API support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COMMISSIONER OT_COMMISSIONER "Enable Commissioner") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_AUTO_SYNC OT_CSL_AUTO_SYNC "Enable csl autosync") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_DEBUG OT_CSL_DEBUG "Enable CSL debug") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_RECEIVER OT_CSL_RECEIVER "Enable CSL receiver feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC OT_CSL_RECEIVER_LOCAL_TIME_SYNC "Use local time for CSL sync") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DATASET_UPDATER OT_DATASET_UPDATER "Enable Dataset updater") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT OT_DEVICE_PROP_LEADER_WEIGHT "Enable device props for leader weight") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DHCP6_CLIENT OT_DHCP6_CLIENT "Enable DHCPv6 Client") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DHCP6_SERVER OT_DHCP6_SERVER "Enable DHCPv6 Server") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DIAG OT_DIAGNOSTIC "Enable Diagnostics support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_CLIENT OT_DNS_CLIENT "Enable DNS client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_CLIENT_OVER_TCP OT_DNS_CLIENT_OVER_TCP "Enable dns query over tcp") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_DSO OT_DNS_DSO "Enable DNS Stateful Operations (DSO) support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY OT_DNS_UPSTREAM_QUERY "Enable forwarding DNS queries to upstream") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNSSD_SERVER OT_DNSSD_SERVER "Enable DNS-SD server support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DUA OT_DUA "Enable Domain Unicast Address feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_ECDSA OT_ECDSA "Enable ECDSA support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_ENABLE_SERVICE OT_SERVICE "Enable Service entries in Thread Network Data") +kconfig_to_ot_option(CONFIG_OPENTHREAD_EXTERNAL_HEAP OT_EXTERNAL_HEAP "Enable external heap support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_FIREWALL OT_FIREWALL "Enable firewall") +kconfig_to_ot_option(CONFIG_OPENTHREAD_FULL_LOGS OT_FULL_LOGS "Enable full logs") +kconfig_to_ot_option(CONFIG_OPENTHREAD_HISTORY_TRACKER OT_HISTORY_TRACKER "Enable history tracker support.") +kconfig_to_ot_option(CONFIG_OPENTHREAD_IP6_FRAGM OT_IP6_FRAGM "Enable IPv6 fragmentation support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_JAM_DETECTION OT_JAM_DETECTION "Enable Jam Detection") +kconfig_to_ot_option(CONFIG_OPENTHREAD_JOINER OT_JOINER "Enable Joiner") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LEGACY OT_LEGACY "Enable legacy network support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR OT_LINK_METRICS_INITIATOR "Enable Link Metrics initiator for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_MANAGER OT_LINK_METRICS_MANAGER "Enable Link Metrics manager for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT OT_LINK_METRICS_SUBJECT "Enable Link Metrics subject for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC OT_LOG_LEVEL_DYNAMIC "Enable dynamic log level control") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MAC_FILTER OT_MAC_FILTER "Enable MAC filter support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MESH_DIAG OT_MESH_DIAG "Enable Mesh Diagnostics") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MESSAGE_USE_HEAP OT_MESSAGE_USE_HEAP "Enable heap allocator for message buffers") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MLE_LONG_ROUTES OT_MLE_LONG_ROUTES "Enable MLE long routes support (Experimental)") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MLR OT_MLR "Enable Multicast Listener Registration feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MULTIPAN_RCP OT_MULTIPAN_RCP "Enable Multi-PAN RCP") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE OT_MULTIPLE_INSTANCE "Enable multiple instances") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NAT64_BORDER_ROUTING OT_NAT64_BORDER_ROUTING "Enable border routing NAT64 support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NAT64_TRANSLATOR OT_NAT64_TRANSLATOR "Enable NAT64 translator") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT OT_NEIGHBOR_DISCOVERY_AGENT "Enable neighbor discovery agent support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NETDIAG_CLIENT OT_NETDIAG_CLIENT "Enable TMF network diagnostics on clients") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NETDATA_PUBLISHER OT_NETDATA_PUBLISHER "Enable Thread Network Data publisher") +kconfig_to_ot_option(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT OT_OPERATIONAL_DATASET_AUTO_INIT "Enable operational dataset auto init") +kconfig_to_ot_option(CONFIG_OPENTHREAD_OTNS OT_OTNS "Enable OTNS support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PING_SENDER OT_PING_SENDER "Enable ping sender support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE OT_PLATFORM_BOOTLOADER_MODE "Enable platform bootloader mode support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_KEY_REF OT_PLATFORM_KEY_REF "Enable platform key reference support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_NETIF OT_PLATFORM_NETIF "Enable platform netif support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_UDP OT_PLATFORM_UDP "Enable platform UDP support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE OT_15_4 "Enable 802.15.4 radio") +kconfig_to_ot_option(CONFIG_OPENTHREAD_RAW OT_LINK_RAW "Enable Link Raw") +kconfig_to_ot_option(CONFIG_OPENTHREAD_REFERENCE_DEVICE OT_REFERENCE_DEVICE "Enable Thread Certification Reference Device") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SETTINGS_RAM OT_SETTINGS_RAM "Enable volatile-only storage of settings") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SLAAC OT_SLAAC "Enable SLAAC") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SNTP_CLIENT OT_SNTP_CLIENT "Enable SNTP Client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_CLIENT OT_SRP_CLIENT "Enable SRP Client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_SERVER OT_SRP_SERVER "Enable SRP Server support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TCP_ENABLE OT_TCP "Enable TCP support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TIME_SYNC OT_TIME_SYNC "Enable the time synchronization service feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TREL OT_TREL "Enable TREL radio link for Thread over Infrastructure feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TX_BEACON_PAYLOAD OT_TX_BEACON_PAYLOAD "Enable tx beacon payload support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TX_QUEUE_STATISTICS OT_TX_QUEUE_STATS "Enable tx queue statistics") +kconfig_to_ot_option(CONFIG_OPENTHREAD_UDP_FORWARD OT_UDP_FORWARD "Enable UDP forward feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_UPTIME OT_UPTIME "Enable support for tracking OpenThread instance's uptime") -if(CONFIG_OPENTHREAD_JOINER) - set(OT_JOINER ON CACHE BOOL "Enable Joiner" FORCE) -else() - set(OT_JOINER OFF CACHE BOOL "Enable Joiner" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LEGACY) - set(OT_LEGACY ON CACHE BOOL "Enable legacy network support" FORCE) -else() - set(OT_LEGACY OFF CACHE BOOL "Enable legacy network support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR) - set(OT_LINK_METRICS_INITIATOR ON CACHE BOOL "Enable Link Metrics initiator for Thread 1.2" FORCE) -else() - set(OT_LINK_METRICS_INITIATOR OFF CACHE BOOL "Enable Link Metrics initiator for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LINK_METRICS_MANAGER) - set(OT_LINK_METRICS_MANAGER ON CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) -else() - set(OT_LINK_METRICS_MANAGER OFF CACHE BOOL "Enable Link Metrics manager for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT) - set(OT_LINK_METRICS_SUBJECT ON CACHE BOOL "Enable Link Metrics subject for Thread 1.2" FORCE) -else() - set(OT_LINK_METRICS_SUBJECT OFF CACHE BOOL "Enable Link Metrics subject for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC) - set(OT_LOG_LEVEL_DYNAMIC ON CACHE BOOL "Enable dynamic log level control" FORCE) -else() - set(OT_LOG_LEVEL_DYNAMIC OFF CACHE BOOL "Enable dynamic log level control" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MAC_FILTER) - set(OT_MAC_FILTER ON CACHE BOOL "Enable MAC filter support" FORCE) -else() - set(OT_MAC_FILTER OFF CACHE BOOL "Enable MAC filter support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MESH_DIAG) - set(OT_MESH_DIAG ON CACHE BOOL "Enable Mesh Diagnostics" FORCE) -else() - set(OT_MESH_DIAG OFF CACHE BOOL "Enable Mesh Diagnostics" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MESSAGE_USE_HEAP) - set(OT_MESSAGE_USE_HEAP ON CACHE BOOL "Enable heap allocator for message buffers" FORCE) -else() - set(OT_MESSAGE_USE_HEAP OFF CACHE BOOL "Enable heap allocator for message buffers" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MLE_LONG_ROUTES) - set(OT_MLE_LONG_ROUTES ON CACHE BOOL "Enable MLE long routes support (Experimental)" FORCE) -else() - set(OT_MLE_LONG_ROUTES OFF CACHE BOOL "Enable MLE long routes support (Experimental)" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MLR) - set(OT_MLR ON CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) -else() - set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) - set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) -else() - set(OT_MULTIPLE_INSTANCE OFF CACHE BOOL "Enable multiple instances" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NAT64_BORDER_ROUTING) - set(OT_NAT64_BORDER_ROUTING ON CACHE BOOL "Enable border routing NAT64 support" FORCE) -else() - set(OT_NAT64_BORDER_ROUTING OFF CACHE BOOL "Enable border routing NAT64 support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NAT64_TRANSLATOR) - set(OT_NAT64_TRANSLATOR ON CACHE BOOL "Enable NAT64 translator" FORCE) -else() - set(OT_NAT64_TRANSLATOR OFF CACHE BOOL "Enable NAT64 translator" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT) - set(OT_NEIGHBOR_DISCOVERY_AGENT ON CACHE BOOL "Enable neighbor discovery agent support" FORCE) -else() - set(OT_NEIGHBOR_DISCOVERY_AGENT OFF CACHE BOOL "Enable neighbor discovery agent support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NETDIAG_CLIENT) - set(OT_NETDIAG_CLIENT ON CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -else() - set(OT_NETDIAG_CLIENT OFF CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NETDATA_PUBLISHER) - set(OT_NETDATA_PUBLISHER ON CACHE BOOL "Enable Thread Network Data publisher" FORCE) -else() - set(OT_NETDATA_PUBLISHER OFF CACHE BOOL "Enable Thread Network Data publisher" FORCE) -endif() - -if(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT) - set(OT_OPERATIONAL_DATASET_AUTO_INIT ON CACHE BOOL "Enable operational dataset auto init" FORCE) -else() - set(OT_OPERATIONAL_DATASET_AUTO_INIT OFF CACHE BOOL "Enable operational dataset auto init" FORCE) -endif() - -if(CONFIG_OPENTHREAD_OTNS) - set(OT_OTNS ON CACHE BOOL "Enable OTNS support" FORCE) -else() - set(OT_OTNS OFF CACHE BOOL "Enable OTNS support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PING_SENDER) - set(OT_PING_SENDER ON CACHE BOOL "Enable ping sender support" FORCE) -else() - set(OT_PING_SENDER OFF CACHE BOOL "Enable ping sender support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PLATFORM_NETIF) - set(OT_PLATFORM_NETIF ON CACHE BOOL "Enable platform netif support" FORCE) -else() - set(OT_PLATFORM_NETIF OFF CACHE BOOL "Enable platform netif support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PLATFORM_UDP) - set(OT_PLATFORM_UDP ON CACHE BOOL "Enable platform UDP support" FORCE) -else() - set(OT_PLATFORM_UDP OFF CACHE BOOL "Enable platform UDP support" FORCE) +if(CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE) + set(OT_NCP_VENDOR_HOOK_SOURCE ${CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE} CACHE STRING "NCP vendor hook source file name" FORCE) endif() if(CONFIG_OPENTHREAD_POWER_SUPPLY) set(OT_POWER_SUPPLY ${CONFIG_OPENTHREAD_POWER_SUPPLY} CACHE STRING "Power supply configuration" FORCE) endif() -if(CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE) - set(OT_15_4 ON CACHE BOOL "Enable 802.15.4 radio" FORCE) -else() - set(OT_15_4 OFF CACHE BOOL "Enable 802.15.4 radio" FORCE) -endif() - -if(CONFIG_OPENTHREAD_RAW) - set(OT_LINK_RAW ON CACHE BOOL "Enable Link Raw" FORCE) -else() - set(OT_LINK_RAW OFF CACHE BOOL "Enable Link Raw" FORCE) -endif() - -if(CONFIG_OPENTHREAD_REFERENCE_DEVICE) - set(OT_REFERENCE_DEVICE ON CACHE BOOL "Enable Thread Certification Reference Device" FORCE) -else() - set(OT_REFERENCE_DEVICE OFF CACHE BOOL "Enable Thread Certification Reference Device" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SETTINGS_RAM) - set(OT_SETTINGS_RAM ON CACHE BOOL "Enable volatile-only storage of settings" FORCE) -else() - set(OT_SETTINGS_RAM OFF CACHE BOOL "Enable volatile-only storage of settings" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SLAAC) - set(OT_SLAAC ON CACHE BOOL "Enable SLAAC" FORCE) -else() - set(OT_SLAAC OFF CACHE BOOL "Enable SLAAC" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SNTP_CLIENT) - set(OT_SNTP_CLIENT ON CACHE BOOL "Enable SNTP Client support" FORCE) -else() - set(OT_SNTP_CLIENT OFF CACHE BOOL "Enable SNTP Client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SRP_CLIENT) - set(OT_SRP_CLIENT ON CACHE BOOL "Enable SRP Client support" FORCE) -else() - set(OT_SRP_CLIENT OFF CACHE BOOL "Enable SRP Client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SRP_SERVER) - set(OT_SRP_SERVER ON CACHE BOOL "Enable SRP Server support" FORCE) -else() - set(OT_SRP_SERVER OFF CACHE BOOL "Enable SRP Server support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TCP_ENABLE) - set(OT_TCP ON CACHE BOOL "Enable TCP support" FORCE) -else() - set(OT_TCP OFF CACHE BOOL "Enable TCP support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TIME_SYNC) - set(OT_TIME_SYNC ON CACHE BOOL "Enable the time synchronization service feature" FORCE) -else() - set(OT_TIME_SYNC OFF CACHE BOOL "Enable the time synchronization service feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TREL) - set(OT_TREL ON CACHE BOOL "Enable TREL radio link for Thread over Infrastructure feature" FORCE) -else() - set(OT_TREL OFF CACHE BOOL "Enable TREL radio link for Thread over Infrastructure feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TX_BEACON_PAYLOAD) - set(OT_TX_BEACON_PAYLOAD ON CACHE BOOL "Enable tx beacon payload support" FORCE) -else() - set(OT_TX_BEACON_PAYLOAD OFF CACHE BOOL "Enable tx beacon payload support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TX_QUEUE_STATISTICS) - set(OT_TX_QUEUE_STATS ON CACHE BOOL "Enable tx queue statistics" FORCE) -else() - set(OT_TX_QUEUE_STATS OFF CACHE BOOL "Enable tx queue statistics" FORCE) -endif() - -if(CONFIG_OPENTHREAD_UDP_FORWARD) - set(OT_UDP_FORWARD ON CACHE BOOL "Enable UDP forward feature" FORCE) -else() - set(OT_UDP_FORWARD OFF CACHE BOOL "Enable UDP forward feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_UPTIME) - set(OT_UPTIME ON CACHE BOOL "Enable support for tracking OpenThread instance's uptime" FORCE) -else() - set(OT_UPTIME OFF CACHE BOOL "Enable support for tracking OpenThread instance's uptime" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE) - set(OT_NCP_VENDOR_HOOK_SOURCE ${CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE} CACHE STRING "NCP vendor hook source file name" FORCE) -endif() - set(BUILD_TESTING OFF CACHE BOOL "Disable openthread cmake testing targets" FORCE) # Zephyr logging options diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index a75c9e8fd488..ba3990a348d9 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -17,7 +17,7 @@ config OPENTHREAD_THREAD_VERSION_1_3 bool "Version 1.3" config OPENTHREAD_THREAD_VERSION_1_3_1 bool "Version 1.3.1" -endchoice +endchoice # OPENTHREAD_STACK_VERSION config OPENTHREAD_THREAD_VERSION string @@ -39,6 +39,10 @@ config OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING config OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING bool "BBR MR support" +config OPENTHREAD_BLE_TCAT + bool "BLE TCAT support" + select EXPERIMENTAL + config OPENTHREAD_BORDER_AGENT bool "Border Agent support" @@ -214,6 +218,9 @@ config OPENTHREAD_MLR help Enable Multicast Listener Registration support for Thread 1.2 +config OPENTHREAD_MULTIPAN_RCP + bool "OpenThread multipan rcp" + config OPENTHREAD_MULTIPLE_INSTANCE bool "OpenThread multiple instances" @@ -242,6 +249,31 @@ config OPENTHREAD_OTNS config OPENTHREAD_PING_SENDER bool "Ping sender support" +config OPENTHREAD_PLATFORM_KEY_REF + bool "Platform cryptographic key reference support" + help + Enable usage of cryptographic key references instead of literal keys. + This requires a crypto backend library that supports key references. + +choice OPENTHREAD_PLATFORM_BOOTLOADER_MODE_CHOICE + prompt "Platform bootloader mode configuration" + optional + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION + bool "Bootloader mode support with boot mode retention API" + depends on RETENTION_BOOT_MODE && REBOOT + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO + bool "Bootloader mode support with GPIO pin trigger" + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE +endchoice # OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE + bool + help + Platform bootloader mode support + config OPENTHREAD_PLATFORM_NETIF bool "Platform netif support" @@ -263,7 +295,7 @@ config OPENTHREAD_POWER_SUPPLY_EXTERNAL_STABLE config OPENTHREAD_POWER_SUPPLY_EXTERNAL_UNSTABLE bool "OT_POWER_SUPPLY_EXTERNAL_UNSTABLE" -endchoice +endchoice # OPENTHREAD_POWER_SUPPLY_CHOICE config OPENTHREAD_POWER_SUPPLY string diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index 891365b46723..542992e7fa18 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -181,3 +181,16 @@ config OPENTHREAD_DEFAULT_TX_POWER default 0 help Set the default TX output power [dBm] in radio driver for OpenThread purpose. + +config OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE + int "Openthread default TCAT stack size" + default 5120 if OPENTHREAD_CRYPTO_PSA + default 4200 + help + Openthread default TCAT stack size. + +config OPENTHREAD_BLE_TCAT_RING_BUF_SIZE + int "Openthread BLE ringbuffer size" + default 512 + help + Openthread BLE TCAT ringbuffer size. diff --git a/modules/openthread/platform/CMakeLists.txt b/modules/openthread/platform/CMakeLists.txt index d363bcda7dfb..542aa5186ea2 100644 --- a/modules/openthread/platform/CMakeLists.txt +++ b/modules/openthread/platform/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources( spi.c ) +zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_BLE_TCAT ble.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_DIAG diag.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_COPROCESSOR uart.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_CRYPTO_PSA crypto_psa.c) diff --git a/modules/openthread/platform/ble.c b/modules/openthread/platform/ble.c new file mode 100644 index 000000000000..7b41556b6173 --- /dev/null +++ b/modules/openthread/platform/ble.c @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Zephyr OpenThread integration Library */ +#include + +/* OpenThread BLE driver API */ +#include + +/* Zephyr Logging */ + +#define LOG_MODULE_NAME net_openthread_tcat +#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL + +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + +/* BLE connection constants as defined in thread specification. */ +#define TOBLE_SERVICE_UUID 0xfffb +#define RX_CHARACTERISTIC_UUID \ + BT_UUID_128_ENCODE(0x6bd10d8b, 0x85a7, 0x4e5a, 0xba2d, 0xc83558a5f220) +#define TX_CHARACTERISTIC_UUID \ + BT_UUID_128_ENCODE(0x7fddf61f, 0x280a, 0x4773, 0xb448, 0xba1b8fe0dd69) + +#define BT_UUID_TCAT_SERVICE BT_UUID_DECLARE_16(TOBLE_SERVICE_UUID) +#define BT_UUID_TCAT_SERVICE_RX BT_UUID_DECLARE_128(RX_CHARACTERISTIC_UUID) +#define BT_UUID_TCAT_SERVICE_TX BT_UUID_DECLARE_128(TX_CHARACTERISTIC_UUID) + +#define PLAT_BLE_THREAD_DEALY 500 +#define PLAT_BLE_MSG_DATA_MAX CONFIG_BT_L2CAP_TX_MTU /* must match the maximum MTU size used */ + +#define PLAT_BLE_MSG_CONNECT (PLAT_BLE_MSG_DATA_MAX + 1U) +#define PLAT_BLE_MSG_DISCONNECT (PLAT_BLE_MSG_CONNECT + 1U) + +/* Zephyr Kernel Objects */ + +static void ot_plat_ble_thread(void *, void *, void *); +static uint8_t ot_plat_ble_msg_buf[PLAT_BLE_MSG_DATA_MAX]; + +static K_SEM_DEFINE(ot_plat_ble_init_semaphore, 0, 1); +static K_SEM_DEFINE(ot_plat_ble_event_semaphore, 0, K_SEM_MAX_LIMIT); +RING_BUF_DECLARE(ot_plat_ble_ring_buf, CONFIG_OPENTHREAD_BLE_TCAT_RING_BUF_SIZE); +static K_THREAD_DEFINE(ot_plat_ble_tid, CONFIG_OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE, + ot_plat_ble_thread, NULL, NULL, NULL, 5, 0, PLAT_BLE_THREAD_DEALY); + +/* OpenThread Objects */ + +static otInstance *ble_openthread_instance; + +/* BLE service Objects */ + +/* forward declaration for callback functions */ +static ssize_t on_receive(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags); +static void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value); + +/* Service Declaration and Registration */ +BT_GATT_SERVICE_DEFINE(my_service, BT_GATT_PRIMARY_SERVICE(BT_UUID_TCAT_SERVICE), + BT_GATT_CHARACTERISTIC(BT_UUID_TCAT_SERVICE_RX, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, NULL, + on_receive, NULL), + BT_GATT_CHARACTERISTIC(BT_UUID_TCAT_SERVICE_TX, BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ, NULL, NULL, NULL), + BT_GATT_CCC(on_cccd_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),); + +/* Zephyr BLE Objects */ + +/* forward declaration for callback functions */ +static void connected(struct bt_conn *conn, uint8_t err); +static void disconnected(struct bt_conn *conn, uint8_t reason); +static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); +static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout); + +static struct bt_conn *ot_plat_ble_connection; + +static struct bt_conn_cb conn_callbacks = {.connected = connected, + .disconnected = disconnected, + .le_param_req = le_param_req, + .le_param_updated = le_param_updated}; + +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +}; + +static const struct bt_data sd[] = { + BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(TOBLE_SERVICE_UUID)), +}; + +/* Zephyr BLE Message Queue and Thread */ + +static bool ot_plat_ble_queue_msg(const uint8_t *aData, uint16_t aLen, int8_t aRssi) +{ + otError error = OT_ERROR_NONE; + uint16_t len = 0; + + if (aLen <= PLAT_BLE_MSG_DATA_MAX && aData == NULL) { + return OT_ERROR_INVALID_ARGS; + } + + k_sched_lock(); + + len = sizeof(aLen) + sizeof(aRssi) + ((aLen <= PLAT_BLE_MSG_DATA_MAX) ? aLen : 0); + + if (ring_buf_space_get(&ot_plat_ble_ring_buf) >= len) { + ring_buf_put(&ot_plat_ble_ring_buf, (uint8_t *)&aLen, sizeof(aLen)); + ring_buf_put(&ot_plat_ble_ring_buf, &aRssi, sizeof(aRssi)); + if (aLen <= PLAT_BLE_MSG_DATA_MAX) { + ring_buf_put(&ot_plat_ble_ring_buf, aData, aLen); + } + k_sem_give(&ot_plat_ble_event_semaphore); + } else { + error = OT_ERROR_NO_BUFS; + } + + k_sched_unlock(); + + return error; +} + +static void ot_plat_ble_thread(void *unused1, void *unused2, void *unused3) +{ + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + ARG_UNUSED(unused3); + + uint16_t len; + int8_t rssi; + otBleRadioPacket my_packet; + + LOG_INF("%s started", __func__); + + while (1) { + k_sem_take(&ot_plat_ble_event_semaphore, K_FOREVER); + ring_buf_get(&ot_plat_ble_ring_buf, (uint8_t *)&len, sizeof(len)); + ring_buf_get(&ot_plat_ble_ring_buf, &rssi, sizeof(rssi)); + if (len <= PLAT_BLE_MSG_DATA_MAX) { + ring_buf_get(&ot_plat_ble_ring_buf, ot_plat_ble_msg_buf, len); + } + + openthread_api_mutex_lock(openthread_get_default_context()); + + if (len <= PLAT_BLE_MSG_DATA_MAX) { + /* The packet parameter in otPlatBleGattServerOnWriteRequest is not const. + * Re-write all members. + */ + my_packet.mValue = ot_plat_ble_msg_buf; + my_packet.mPower = rssi; + my_packet.mLength = len; + otPlatBleGattServerOnWriteRequest(ble_openthread_instance, 0, &my_packet); + } else if (len == PLAT_BLE_MSG_CONNECT) { + otPlatBleGapOnConnected(ble_openthread_instance, 0); + } else if (len == PLAT_BLE_MSG_DISCONNECT) { + otPlatBleGapOnDisconnected(ble_openthread_instance, 0); + } + openthread_api_mutex_unlock(openthread_get_default_context()); + } +} + +/* Zephyr BLE service callbacks */ + +/* This function is called whenever the RX Characteristic has been written to by a Client */ +static ssize_t on_receive(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags) +{ + LOG_DBG("Received data, handle %" PRIu16 ", len %" PRIu16, attr->handle, len); + + otError error = ot_plat_ble_queue_msg(buf, len, 0); + + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + + return len; +} + +/* This function is called whenever a Notification has been sent by the TX Characteristic */ +static void on_sent(struct bt_conn *conn, void *user_data) +{ + ARG_UNUSED(conn); + ARG_UNUSED(user_data); + + LOG_DBG("Data sent"); +} + +/* This function is called whenever the CCCD register has been changed by the client */ +void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value) +{ + uint16_t mtu; + otError error = OT_ERROR_NONE; + + ARG_UNUSED(attr); + + switch (value) { + case BT_GATT_CCC_NOTIFY: + + error = ot_plat_ble_queue_msg(NULL, PLAT_BLE_MSG_CONNECT, 0); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("CCCD update (mtu=%" PRIu16 ")!", mtu); + + break; + + default: + break; + } +} + +otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, + const otBleRadioPacket *aPacket) +{ + ARG_UNUSED(aInstance); + + /* TO DO change to indications. */ + const struct bt_gatt_attr *attr = &my_service.attrs[3]; + + struct bt_gatt_notify_params params = {.uuid = BT_UUID_TCAT_SERVICE_TX, + .attr = attr, + .data = aPacket->mValue, + .len = aPacket->mLength, + .func = on_sent}; + + LOG_DBG("Send data, handle %d, len %d", attr->handle, aPacket->mLength); + + /* Only one connection supported */ + if (aHandle != 0) { + return OT_ERROR_INVALID_ARGS; + } + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_INVALID_STATE; + } + + /* Check whether notifications are enabled or not */ + if (bt_gatt_is_subscribed(ot_plat_ble_connection, attr, BT_GATT_CCC_NOTIFY)) { + if (bt_gatt_notify_cb(ot_plat_ble_connection, ¶ms)) { + LOG_WRN("Error, unable to send notification"); + return OT_ERROR_INVALID_ARGS; + } + } else { + LOG_WRN("Warning, notification not enabled on the selected attribute"); + return OT_ERROR_INVALID_STATE; + } + + return OT_ERROR_NONE; +} + +otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu) +{ + ARG_UNUSED(aInstance); + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_FAILED; + } + + if (aMtu != NULL) { + *aMtu = bt_gatt_get_mtu(ot_plat_ble_connection); + } + + return OT_ERROR_NONE; +} + +otError otPlatBleGapDisconnect(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_INVALID_STATE; + } + + if (bt_conn_disconnect(ot_plat_ble_connection, BT_HCI_ERR_REMOTE_USER_TERM_CONN)) { + return OT_ERROR_INVALID_STATE; + } + + return OT_ERROR_NONE; +} + +/* Zephyr BLE callbacks */ + +static void connected(struct bt_conn *conn, uint8_t err) +{ + struct bt_conn_info info; + char addr[BT_ADDR_LE_STR_LEN]; + uint16_t mtu; + otError error = OT_ERROR_NONE; + + ot_plat_ble_connection = bt_conn_ref(conn); + + if (err) { + LOG_WRN("Connection failed (err %u)", err); + return; + } else if (bt_conn_get_info(conn, &info)) { + LOG_WRN("Could not parse connection info"); + } else { + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("Connection established (mtu=%" PRIu16 ")!", mtu); + } +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + otError error = OT_ERROR_NONE; + + LOG_INF("Disconnected (reason %" PRIu8 ")", reason); + + if (ot_plat_ble_connection) { + bt_conn_unref(ot_plat_ble_connection); + ot_plat_ble_connection = NULL; + + error = ot_plat_ble_queue_msg(NULL, PLAT_BLE_MSG_DISCONNECT, 0); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + } +} + +static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param) +{ + return true; +} + +static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout) +{ + struct bt_conn_info info; + char addr[BT_ADDR_LE_STR_LEN]; + uint16_t mtu; + otError error = OT_ERROR_NONE; + + if (bt_conn_get_info(conn, &info)) { + LOG_INF("Could not parse connection info"); + } else { + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("Connection parameters updated (mtu=%" PRIu16 ")!", mtu); + } +} + +static void bt_ready(int err) +{ + if (err) { + LOG_WRN("BLE init failed with error code %d", err); + return; + } + + bt_conn_cb_register(&conn_callbacks); + k_sem_give(&ot_plat_ble_init_semaphore); /* BLE stack up an running */ +} + +otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval) +{ + ARG_UNUSED(aInstance); + ARG_UNUSED(aInterval); + + /* TO DO advertisement format change */ + int err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + + if (err != 0 && err != -EALREADY) { + LOG_WRN("Advertising failed to start (err %d)", err); + return OT_ERROR_INVALID_STATE; + } + + LOG_INF("Advertising successfully started"); + + return OT_ERROR_NONE; +} + +otError otPlatBleGapAdvStop(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + + int err = bt_le_adv_stop(); + + if (err != 0 && err != -EALREADY) { + LOG_WRN("Advertisement failed to stop (err %d)", err); + return OT_ERROR_FAILED; + } + return OT_ERROR_NONE; +} + +/* Zephyr BLE initialization */ + +otError otPlatBleEnable(otInstance *aInstance) +{ + int err; + + ble_openthread_instance = aInstance; + err = bt_enable(bt_ready); + + if (err != 0 && err != -EALREADY) { + 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)); + return OT_ERROR_NONE; + } + + err = k_sem_take(&ot_plat_ble_init_semaphore, K_MSEC(500)); + + if (!err) { + LOG_INF("Bluetooth initialized"); + } else { + LOG_INF("BLE initialization did not complete in time"); + return OT_ERROR_FAILED; + } + + return OT_ERROR_NONE; +} + +otError otPlatBleDisable(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + /* This function intentionally does nothing since disabling advertisement disables BLE + * stack. + */ + return OT_ERROR_NONE; +} diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index e5b234ce0307..c818c5695a34 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -16,6 +16,7 @@ #if defined(CONFIG_OPENTHREAD_ECDSA) #include +#include #endif static otError psaToOtError(psa_status_t aStatus) @@ -41,6 +42,8 @@ static psa_key_type_t toPsaKeyType(otCryptoKeyType aType) return PSA_KEY_TYPE_AES; case OT_CRYPTO_KEY_TYPE_HMAC: return PSA_KEY_TYPE_HMAC; + case OT_CRYPTO_KEY_TYPE_ECDSA: + return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); default: return PSA_KEY_TYPE_NONE; } @@ -53,12 +56,14 @@ static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm) return PSA_ALG_ECB_NO_PADDING; case OT_CRYPTO_KEY_ALG_HMAC_SHA_256: return PSA_ALG_HMAC(PSA_ALG_SHA_256); + case OT_CRYPTO_KEY_ALG_ECDSA: + return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256); default: /* * There is currently no constant like PSA_ALG_NONE, but 0 is used * to indicate an unknown algorithm. */ - return (psa_algorithm_t) 0; + return (psa_algorithm_t)0; } } @@ -82,16 +87,19 @@ static psa_key_usage_t toPsaKeyUsage(int aUsage) usage |= PSA_KEY_USAGE_SIGN_HASH; } + if (aUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH) { + usage |= PSA_KEY_USAGE_VERIFY_HASH; + } + return usage; } static bool checkKeyUsage(int aUsage) { /* Check if only supported flags have been passed */ - int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT | - OT_CRYPTO_KEY_USAGE_ENCRYPT | - OT_CRYPTO_KEY_USAGE_DECRYPT | - OT_CRYPTO_KEY_USAGE_SIGN_HASH; + int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT | OT_CRYPTO_KEY_USAGE_ENCRYPT | + OT_CRYPTO_KEY_USAGE_DECRYPT | OT_CRYPTO_KEY_USAGE_SIGN_HASH | + OT_CRYPTO_KEY_USAGE_VERIFY_HASH; return (aUsage & ~supported_flags) == 0; } @@ -102,31 +110,6 @@ static bool checkContext(otCryptoContext *aContext, size_t aMinSize) return aContext != NULL && aContext->mContext != NULL && aContext->mContextSize >= aMinSize; } -static void ensureKeyIsLoaded(otCryptoKeyRef aKeyRef) -{ - /* - * The workaround below will no longer be need after updating TF-M version used in Zephyr - * to 1.5.0 (see upstream commit 42e77b561fcfe19819ff1e63cb7c0b672ee8ba41). - * In the recent versions of TF-M the concept of key handles and psa_open_key()/ - * psa_close_key() APIs have been being deprecated, but the version currently used in Zephyr - * is in the middle of that transition. Consequently, psa_destroy_key() and lots of other - * functions will fail when a key ID that they take as a parameter is not loaded from the - * persistent storage. That may occur when a given persistent key is created via - * psa_generate_key() or psa_import_key(), and then the device reboots. - * - * Use psa_open_key() when the key has not been loaded yet to work around the issue. - */ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = psa_get_key_attributes(aKeyRef, &attributes); - psa_key_id_t key_handle; - - if (status == PSA_ERROR_INVALID_HANDLE) { - psa_open_key(aKeyRef, &key_handle); - } - - psa_reset_key_attributes(&attributes); -} - void otPlatCryptoInit(void) { psa_crypto_init(); @@ -137,26 +120,57 @@ void otPlatCryptoInit(void) * PSA with emulated TFM, Settings have to be initialized at the end of otPlatCryptoInit(), * to be available before storing Network Key. */ - __ASSERT_EVAL((void) settings_subsys_init(), int err = settings_subsys_init(), - !err, "Failed to initialize settings"); + __ASSERT_EVAL((void)settings_subsys_init(), int err = settings_subsys_init(), !err, + "Failed to initialize settings"); #endif } -otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, - otCryptoKeyType aKeyType, - otCryptoKeyAlgorithm aKeyAlgorithm, - int aKeyUsage, - otCryptoKeyStorage aKeyPersistence, - const uint8_t *aKey, +otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, otCryptoKeyType aKeyType, + otCryptoKeyAlgorithm aKeyAlgorithm, int aKeyUsage, + otCryptoKeyStorage aKeyPersistence, const uint8_t *aKey, size_t aKeyLen) { +#if defined(CONFIG_OPENTHREAD_ECDSA) + int version; + size_t len; + unsigned char *p = (unsigned char *)aKey; + unsigned char *end; +#endif + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; + psa_status_t status = 0; if (aKeyRef == NULL || aKey == NULL || !checkKeyUsage(aKeyUsage)) { return OT_ERROR_INVALID_ARGS; } +#if defined(CONFIG_OPENTHREAD_ECDSA) + /* Check if key is ECDSA pair and extract private key from it since PSA expects it. */ + if (aKeyType == OT_CRYPTO_KEY_TYPE_ECDSA) { + + end = p + aKeyLen; + status = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (status != 0) { + return OT_ERROR_FAILED; + } + + end = p + len; + status = mbedtls_asn1_get_int(&p, end, &version); + if (status != 0) { + return OT_ERROR_FAILED; + } + + status = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); + if (status != 0 || len != 32) { + return OT_ERROR_FAILED; + } + + aKey = p; + aKeyLen = len; + } +#endif + psa_set_key_type(&attributes, toPsaKeyType(aKeyType)); psa_set_key_algorithm(&attributes, toPsaAlgorithm(aKeyAlgorithm)); psa_set_key_usage_flags(&attributes, toPsaKeyUsage(aKeyUsage)); @@ -177,24 +191,18 @@ otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, return psaToOtError(status); } -otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, - uint8_t *aBuffer, - size_t aBufferLen, +otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen) { if (aBuffer == NULL) { return OT_ERROR_INVALID_ARGS; } - ensureKeyIsLoaded(aKeyRef); - return psaToOtError(psa_export_key(aKeyRef, aBuffer, aBufferLen, aKeyLen)); } otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef) { - ensureKeyIsLoaded(aKeyRef); - return psaToOtError(psa_destroy_key(aKeyRef)); } @@ -203,7 +211,6 @@ bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef) psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; - ensureKeyIsLoaded(aKeyRef); status = psa_get_key_attributes(aKeyRef, &attributes); psa_reset_key_attributes(&attributes); @@ -246,15 +253,13 @@ otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey return OT_ERROR_INVALID_ARGS; } - ensureKeyIsLoaded(aKey->mKeyRef); operation = aContext->mContext; status = psa_mac_sign_setup(operation, aKey->mKeyRef, PSA_ALG_HMAC(PSA_ALG_SHA_256)); return psaToOtError(status); } -otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, - const void *aBuf, +otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength) { psa_mac_operation_t *operation; @@ -265,7 +270,7 @@ otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, operation = aContext->mContext; - return psaToOtError(psa_mac_update(operation, (const uint8_t *) aBuf, aBufLength)); + return psaToOtError(psa_mac_update(operation, (const uint8_t *)aBuf, aBufLength)); } otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength) @@ -291,7 +296,7 @@ otError otPlatCryptoAesInit(otCryptoContext *aContext) } key_ref = aContext->mContext; - *key_ref = (psa_key_id_t) 0; /* In TF-M 1.5.0 this can be replaced with PSA_KEY_ID_NULL */ + *key_ref = (psa_key_id_t)0; /* In TF-M 1.5.0 this can be replaced with PSA_KEY_ID_NULL */ return OT_ERROR_NONE; } @@ -314,7 +319,6 @@ otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, { const size_t block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); psa_status_t status = PSA_SUCCESS; - psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_id_t *key_ref; size_t cipher_length; @@ -322,37 +326,10 @@ otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, return OT_ERROR_INVALID_ARGS; } - /* - * The code below can be simplified after updating TF-M version used in Zephyr to 1.5.0 - * (see upstream commit: 045ec4abfc73152a0116684ba9127d0a97cc8d34), using - * psa_cipher_encrypt() function which will replace the setup-update-finish sequence below. - */ key_ref = aContext->mContext; - ensureKeyIsLoaded(*key_ref); - status = psa_cipher_encrypt_setup(&operation, *key_ref, PSA_ALG_ECB_NO_PADDING); - - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_cipher_update(&operation, - aInput, - block_size, - aOutput, - block_size, - &cipher_length); - - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_cipher_finish(&operation, - aOutput + cipher_length, - block_size - cipher_length, - &cipher_length); + status = psa_cipher_encrypt(*key_ref, PSA_ALG_ECB_NO_PADDING, aInput, block_size, aOutput, + block_size, &cipher_length); -out: - psa_cipher_abort(&operation); return psaToOtError(status); } @@ -411,7 +388,7 @@ otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, ui operation = aContext->mContext; - return psaToOtError(psa_hash_update(operation, (const uint8_t *) aBuf, aBufLength)); + return psaToOtError(psa_hash_update(operation, (const uint8_t *)aBuf, aBufLength)); } otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize) @@ -475,38 +452,6 @@ otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair) return psaToOtError(status); } -otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair, - otPlatCryptoEcdsaPublicKey *aPublicKey) -{ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_status_t status; - size_t exported_length; - uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE]; - - psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&attributes, 256); - - status = psa_import_key(&attributes, aKeyPair->mDerBytes, aKeyPair->mDerLength, &key_id); - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_export_public_key(key_id, buffer, sizeof(buffer), &exported_length); - if (status != PSA_SUCCESS) { - goto out; - } - __ASSERT_NO_MSG(exported_length == sizeof(buffer)); - memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE); - -out: - psa_reset_key_attributes(&attributes); - psa_destroy_key(key_id); - - return psaToOtError(status); -} - otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair, const otPlatCryptoSha256Hash *aHash, otPlatCryptoEcdsaSignature *aSignature) diff --git a/modules/openthread/platform/misc.c b/modules/openthread/platform/misc.c index 7f57dddb9e3e..5f9043dfa27b 100644 --- a/modules/openthread/platform/misc.c +++ b/modules/openthread/platform/misc.c @@ -9,6 +9,24 @@ #include #include +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + +#include + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + +BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(openthread_config), + "`openthread,config` compatible node not found"); +BUILD_ASSERT(DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), bootloader_gpios), + "`bootloader-gpios` property missing from `openthread,config` compatible node"); + +#include + +static const struct gpio_dt_spec bootloader_gpio = + GPIO_DT_SPEC_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), + bootloader_gpios); +#endif + #include "platform-zephyr.h" void otPlatReset(otInstance *aInstance) @@ -19,6 +37,54 @@ void otPlatReset(otInstance *aInstance) sys_reboot(SYS_REBOOT_WARM); } +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) +otError otPlatResetToBootloader(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + if (bootmode_set(BOOT_MODE_TYPE_BOOTLOADER)) { + return OT_ERROR_NOT_CAPABLE; + } + sys_reboot(SYS_REBOOT_WARM); + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + /* + * To enable resetting to bootloader by triggering gpio pin, + * select `CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO=y`, + * and in Devicetree create `openthread` node in `/options/` path with + * `compatible = "openthread,config"` property and `bootloader-gpios` property, + * which should represent GPIO pin's configuration, + * containing controller phandle, pin number and pin flags. e.g: + * + * options { + * openthread { + * compatible = "openthread,config"; + * bootloader-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + * }; + * }; + * + * Note: in below implementation, chosen GPIO pin is configured as output + * and initialized to active state (logical value ‘1’). + * Configuring pin flags in `bootloader-gpios` allows to choose + * if pin should be active in high or in low state. + */ + + if (!gpio_is_ready_dt(&bootloader_gpio)) { + return OT_ERROR_NOT_CAPABLE; + } + gpio_pin_configure_dt(&bootloader_gpio, GPIO_OUTPUT_ACTIVE); + +#endif + + /* + * Return OT_ERROR_NOT_CAPABLE if resetting has been unsuccessful (invalid configuration or + * triggering reset had no effect) + */ + return OT_ERROR_NOT_CAPABLE; +} +#endif /* defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) */ + otPlatResetReason otPlatGetResetReason(otInstance *aInstance) { ARG_UNUSED(aInstance); @@ -33,5 +99,10 @@ void otPlatWakeHost(void) void otPlatAssertFail(const char *aFilename, int aLineNumber) { - __ASSERT(false, "OpenThread ASSERT @ %s:%d", aFilename, aLineNumber); + /* + * The code below is used instead of __ASSERT(false) to print the actual assert + * location instead of __FILE__:__LINE__, which would point to this function. + */ + __ASSERT_PRINT("OpenThread ASSERT @ %s:%d\n", aFilename, aLineNumber); + __ASSERT_POST_ACTION(); } diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 881585e55789..71a087ca0b50 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -396,16 +396,6 @@ #define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA #endif -/** - * @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - * - * Set to 1 if you want to enable key reference usage support. - * - */ -#ifdef CONFIG_OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE -#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1 -#endif - /** * @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE * @@ -448,17 +438,6 @@ #define OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE 0 #endif -/** - * @def OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE - * - * In Zephyr, power calibration is handled by Radio Driver, so it can't be handled on OT level. - * - */ -#ifndef OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE -#define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE 0 -#endif - - /** * @def OPENTHREAD_CONFIG_RADIO_STATS * diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 98eab182aade..d405539bcc01 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -380,13 +380,8 @@ void transmit_message(struct k_work *tx_job) channel = sTransmitFrame.mChannel; - radio_api->set_channel(radio_dev, sTransmitFrame.mChannel); - -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - net_pkt_set_ieee802154_txpwr(tx_pkt, get_transmit_power_for_channel(channel)); -#else + radio_api->set_channel(radio_dev, channel); radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel)); -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ net_pkt_set_ieee802154_frame_secured(tx_pkt, sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed); @@ -1188,20 +1183,14 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe struct ieee802154_key keys[] = { { .key_id_mode = key_id_mode, - .key_index = aKeyId == 1 ? 0x80 : aKeyId - 1, - .key_value = (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { .key_id_mode = key_id_mode, - .key_index = aKeyId, - .key_value = (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { .key_id_mode = key_id_mode, - .key_index = aKeyId == 0x80 ? 1 : aKeyId + 1, - .key_value = (uint8_t *)aNextKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { @@ -1215,9 +1204,24 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe }, }; - /* aKeyId in range: (1, 0x80) means valid keys - * aKeyId == 0 is used only to clear keys for stack reset in RCP - */ + if (key_id_mode == 1) { + /* aKeyId in range: (1, 0x80) means valid keys */ + uint8_t prev_key_id = aKeyId == 1 ? 0x80 : aKeyId - 1; + uint8_t next_key_id = aKeyId == 0x80 ? 1 : aKeyId + 1; + + keys[0].key_id = &prev_key_id; + keys[0].key_value = (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8; + + keys[1].key_id = &aKeyId; + keys[1].key_value = (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8; + + keys[2].key_id = &next_key_id; + keys[2].key_value = (uint8_t *)aNextKey->mKeyMaterial.mKey.m8; + } else { + /* aKeyId == 0 is used only to clear keys for stack reset in RCP */ + __ASSERT_NO_MSG((key_id_mode == 0) && (aKeyId == 0)); + } + struct ieee802154_config config = { .mac_keys = aKeyId == 0 ? clear_keys : keys, }; @@ -1251,10 +1255,7 @@ void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacF otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr) { - struct ieee802154_config config = { - .ack_ie.short_addr = aShortAddr, - .ack_ie.ext_addr = aExtAddr->m8, - }; + struct ieee802154_config config = { 0 }; int result; ARG_UNUSED(aInstance); @@ -1267,6 +1268,8 @@ otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShort if (result) { return OT_ERROR_FAILED; } + config.ack_ie.short_addr = aShortAddr; + config.ack_ie.ext_addr = aExtAddr != NULL ? aExtAddr->m8 : NULL; /* Configure the CSL IE. */ if (aCslPeriod > 0) { @@ -1291,6 +1294,22 @@ otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShort return result ? OT_ERROR_FAILED : OT_ERROR_NONE; } +otError otPlatRadioResetCsl(otInstance *aInstance) +{ + struct ieee802154_config config = { 0 }; + int result; + + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config); + if (result) { + return OT_ERROR_FAILED; + } + + config.ack_ie.purge_ie = true; + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); + + return result ? OT_ERROR_FAILED : OT_ERROR_NONE; +} + void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime) { ARG_UNUSED(aInstance); @@ -1344,7 +1363,7 @@ uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance) * | IE_VENDOR_THREAD_ACK_PROBING_ID | LINK_METRIC_TOKEN | LINK_METRIC_TOKEN| * |---------------------------------|-------------------|------------------| */ -static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header) +static void set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header) { /* Vendor-specific IE identifier */ const uint8_t ie_vendor_id = 0x00; @@ -1358,7 +1377,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui const uint8_t ie_vendor_thread_margin_token = 0x02; /* Thread Vendor-specific ACK Probing IE LQI value placeholder */ const uint8_t ie_vendor_thread_lqi_token = 0x03; - const uint8_t ie_header_size = 2; const uint8_t oui_size = 3; const uint8_t sub_type = 1; const uint8_t id_offset = 7; @@ -1376,7 +1394,8 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui __ASSERT(ie_header, "Invalid argument"); if (link_metrics_data_len == 0) { - return 0; + ie_header[0] = 0; + return; } /* Set Element ID */ @@ -1411,8 +1430,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui if (rssi) { ie_header[link_metrics_idx++] = ie_vendor_thread_rssi_token; } - - return ie_header_size + content_len; } otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics aLinkMetrics, @@ -1424,13 +1441,12 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a .ack_ie.ext_addr = aExtAddress->m8, }; uint8_t header_ie_buf[OT_ACK_IE_MAX_SIZE]; - uint16_t header_ie_len; int result; ARG_UNUSED(aInstance); - header_ie_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, - aLinkMetrics.mRssi, header_ie_buf); + set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, + aLinkMetrics.mRssi, header_ie_buf); config.ack_ie.header_ie = (struct ieee802154_header_ie *)header_ie_buf; result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 177a47e28d67..2bba4a45c6db 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -40,9 +40,11 @@ if (CONFIG_BUILD_WITH_TFM) endif() if (CONFIG_TFM_REGRESSION_S) list(APPEND TFM_CMAKE_ARGS -DTEST_S=ON) + list(APPEND TFM_CMAKE_ARGS -DTFM_S_REG_TEST:BOOL=ON) endif() if (CONFIG_TFM_REGRESSION_NS) list(APPEND TFM_CMAKE_ARGS -DTEST_NS=ON) + list(APPEND TFM_CMAKE_ARGS -DTFM_NS_REG_TEST:BOOL=ON) endif() if (CONFIG_TFM_BL2) list(APPEND TFM_CMAKE_ARGS -DBL2=TRUE) @@ -51,11 +53,6 @@ if (CONFIG_BUILD_WITH_TFM) else() list(APPEND TFM_CMAKE_ARGS -DBL2=FALSE) endif() - if (CONFIG_TFM_BUILD_NS) - list(APPEND TFM_CMAKE_ARGS -DNS=TRUE) - else() - list(APPEND TFM_CMAKE_ARGS -DNS=FALSE) - endif() if (CONFIG_TFM_ISOLATION_LEVEL) list(APPEND TFM_CMAKE_ARGS -DTFM_ISOLATION_LEVEL=${CONFIG_TFM_ISOLATION_LEVEL}) endif() @@ -68,20 +65,6 @@ if (CONFIG_BUILD_WITH_TFM) if (CONFIG_TFM_PROFILE) list(APPEND TFM_CMAKE_ARGS -DTFM_PROFILE=${CONFIG_TFM_PROFILE}) endif() - if (CONFIG_TFM_PSA_TEST_CRYPTO) - set(TFM_PSA_TEST_SUITE CRYPTO) - elseif (CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE) - set(TFM_PSA_TEST_SUITE PROTECTED_STORAGE) - elseif (CONFIG_TFM_PSA_TEST_INTERNAL_TRUSTED_STORAGE) - set(TFM_PSA_TEST_SUITE INTERNAL_TRUSTED_STORAGE) - elseif (CONFIG_TFM_PSA_TEST_STORAGE) - set(TFM_PSA_TEST_SUITE STORAGE) - elseif (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION) - set(TFM_PSA_TEST_SUITE INITIAL_ATTESTATION) - endif() - if (DEFINED TFM_PSA_TEST_SUITE) - list(APPEND TFM_CMAKE_ARGS -DTEST_PSA_API=${TFM_PSA_TEST_SUITE}) - endif() if (CONFIG_TFM_CMAKE_BUILD_TYPE_RELEASE) set(TFM_CMAKE_BUILD_TYPE "Release") elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL) @@ -95,6 +78,12 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_NUMBER=${CONFIG_TFM_MCUBOOT_IMAGE_NUMBER}) endif() + if (CONFIG_TFM_DUMMY_PROVISIONING) + list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=ON) + else() + list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=OFF) + endif() + if (CONFIG_TFM_EXCEPTION_INFO_DUMP) list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=ON) else() @@ -163,34 +152,17 @@ if (CONFIG_BUILD_WITH_TFM) foreach(module ${TFM_CRYPTO_MODULES}) if (CONFIG_TFM_${module}_ENABLED) # list(APPEND TFM_ENABLED_CRYPTO_MODULES_ARG ${module}) - set(val "FALSE") - else() - set(val "TRUE") + list(APPEND TFM_CMAKE_ARGS -D${module}_ENABLED=True) endif() - list(APPEND TFM_CMAKE_ARGS -D${module}_DISABLED=${val}) endforeach() set(TFM_BINARY_DIR ${CMAKE_BINARY_DIR}/tfm) - set(TFM_TEST_REPO_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/../tf-m-tests) set(PSA_ARCH_TESTS_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/../psa-arch-tests) - set(VENEERS_FILE ${TFM_BINARY_DIR}/secure_fw/s_veneers.o) - set(TFM_API_NS_PATH ${TFM_BINARY_DIR}/tf-m-tests/app/libtfm_api_ns.a) - set(PLATFORM_NS_FILE ${TFM_BINARY_DIR}/platform/ns/libplatform_ns.a) - set(TFM_GENERATED_INCLUDES ${TFM_BINARY_DIR}/generated/interface/include) - set(TFM_INTERFACE_SOURCE_DIR ${TFM_BINARY_DIR}/install/interface/src) - - if (TFM_PSA_TEST_SUITE) - set(PSA_TEST_VAL_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/val/val_nspe.a) - set(PSA_TEST_PAL_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/platform/pal_nspe.a) - set(COMBINE_DIR_STORAGE storage) - set(COMBINE_DIR_PROTECTED_STORAGE storage) - set(COMBINE_DIR_INTERNAL_TRUSTED_STORAGE storage) - set(COMBINE_DIR_CRYPTO crypto) - set(COMBINE_DIR_INITIAL_ATTESTATION initial_attestation) - set(PSA_TEST_COMBINE_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/dev_apis/${COMBINE_DIR_${TFM_PSA_TEST_SUITE}}/test_combine.a) - endif() + set(TFM_INTERFACE_SOURCE_DIR ${TFM_BINARY_DIR}/api_ns/interface/src) + set(TFM_INTERFACE_INCLUDE_DIR ${TFM_BINARY_DIR}/api_ns/interface/include) + set(TFM_INTERFACE_LIB_DIR ${TFM_BINARY_DIR}/api_ns/interface/lib) if(CONFIG_TFM_BL2) set(BL2_ELF_FILE ${TFM_BINARY_DIR}/bin/bl2.elf) @@ -201,38 +173,33 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_S_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s.bin) set(TFM_S_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_s.hex) set(TFM_NS_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.bin) - set(TFM_NS_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.hex) + set(TFM_NS_HEX_FILE ${CMAKE_BINARY_DIR}/tfm_ns/bin/tfm_ns.hex) set(TFM_S_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_signed.bin) set(TFM_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns_signed.bin) set(TFM_S_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_ns_signed.bin) set(BUILD_BYPRODUCTS - ${VENEERS_FILE} - ${TFM_API_NS_PATH} - ${TFM_GENERATED_INCLUDES}/psa_manifest/sid.h ${PSA_TEST_VAL_FILE} ${PSA_TEST_PAL_FILE} ${PSA_TEST_COMBINE_FILE} - ${PLATFORM_NS_FILE} ${BL2_ELF_FILE} ${BL2_BIN_FILE} ${BL2_HEX_FILE} ${TFM_S_ELF_FILE} ${TFM_S_BIN_FILE} ${TFM_S_HEX_FILE} - ${TFM_NS_BIN_FILE} - ${TFM_NS_HEX_FILE} ${TFM_S_SIGNED_BIN_FILE} - ${TFM_NS_SIGNED_BIN_FILE} ${TFM_S_NS_SIGNED_BIN_FILE} + ${TFM_INTERFACE_LIB_DIR}/s_veneers.o + ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c - ${TFM_INTERFACE_SOURCE_DIR}/tfm_psa_ns_api.c + ${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c # Specific to nordic_nrf platform ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c @@ -257,33 +224,7 @@ if (CONFIG_BUILD_WITH_TFM) message(FATAL_ERROR "Unsupported ZEPHYR_TOOLCHAIN_VARIANT: ${ZEPHYR_TOOLCHAIN_VARIANT}") endif() - if (CONFIG_TFM_PARTITION_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") - # TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, - # or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has - # been manually downloaded by the user before starting the build. - message(FATAL_ERROR "CONFIG_TFM_PARTITION_INITIAL_ATTESTATION is not available " - "with TF-M 1.7.0 due to licensing issues with a dependent library. This " - "restriction will be removed once licensing issues have been resolved." - ) - endif() - - if (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") - # TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, - # or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has - # been manually downloaded by the user before starting the build. - message(FATAL_ERROR "CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION is not available " - "with TF-M 1.7.0 due to licensing issues with a dependent library. This " - "restriction will be removed once licensing issues have been resolved." - ) - endif() - - if (CONFIG_TFM_QCBOR_PATH STREQUAL "DOWNLOAD") - # Change CMake cache type to string to avoid QCBOR_PATH=/absolute/path/DOWNLOAD being set. - set(QCBOR_PATH_TYPE ":STRING") - endif() - # Always set QCBOR_PATH, this will make sure that we don't automatically download this - # dependency in the TF-M build system and it will fail when set to an invalid value. - list(APPEND TFM_CMAKE_ARGS -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH}) + string(REPLACE "toolchain" "toolchain_ns" TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_FILE}) if(CONFIG_BOARD_LPCXPRESSO55S69_CPU0) # Supply path to NXP HAL sources used for TF-M build @@ -300,13 +241,6 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_DATA_SHARING=ON) endif() - if(TFM_PSA_TEST_SUITE) - list(APPEND TFM_CMAKE_ARGS - -DPSA_TOOLCHAIN_FILE=${CMAKE_CURRENT_LIST_DIR}/psa/GNUARM.cmake - -DTOOLCHAIN=INHERIT - ) - endif() - if(CONFIG_FPU AND CONFIG_FP_HARDABI) list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_ENABLE_FP=ON) # Note: This is not a cmake option in TF-M. @@ -334,7 +268,6 @@ if (CONFIG_BUILD_WITH_TFM) ${TFM_CMAKE_ARGS} $> -DMBEDCRYPTO_PATH=$>,$,${ZEPHYR_MBEDTLS_MODULE_DIR}> - -DTFM_TEST_REPO_PATH=${TFM_TEST_REPO_PATH} -DPSA_ARCH_TESTS_PATH=${PSA_ARCH_TESTS_PATH} ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR} WORKING_DIRECTORY ${TFM_BINARY_DIR} @@ -373,6 +306,11 @@ if (CONFIG_BUILD_WITH_TFM) # This is the root of all TFM build artifacts. set_target_properties(tfm PROPERTIES TFM_BINARY_DIR ${TFM_BINARY_DIR}) + # Set TFM toolchain properties on 'tfm' + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_NS_FILE}) + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PREFIX ${TFM_TOOLCHAIN_PREFIX}) + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PATH ${TFM_TOOLCHAIN_PATH}) + # Set BL2 (MCUboot) executable file paths as target properties on 'tfm' # These files are produced by the TFM build system. if(CONFIG_TFM_BL2) @@ -409,48 +347,27 @@ if (CONFIG_BUILD_WITH_TFM) if (CONFIG_TFM_PARTITION_PLATFORM AND NOT CONFIG_TFM_PARTITION_PLATFORM_CUSTOM_REBOOT) zephyr_library_sources(src/reboot.c) endif() - zephyr_library_sources_ifndef(CONFIG_TFM_PSA_TEST_NONE src/zephyr_tfm_psa_test.c) - if (TFM_PSA_TEST_SUITE) - zephyr_library_link_libraries( - ${PSA_TEST_VAL_FILE} - ${PSA_TEST_PAL_FILE} - ${PSA_TEST_COMBINE_FILE} - ) - endif() - - if(NOT CONFIG_TFM_BUILD_NS) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PROTECTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_CRYPTO ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INITIAL_ATTESTATION ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_FIRMWARE_UPDATE ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PROTECTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_CRYPTO ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INITIAL_ATTESTATION ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_FIRMWARE_UPDATE ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c) - zephyr_library_sources(${TFM_INTERFACE_SOURCE_DIR}/tfm_psa_ns_api.c) - - if(CONFIG_SOC_FAMILY_NRF) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c) - endif() + zephyr_library_sources(${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c) - else() - zephyr_library_link_libraries( - ${PLATFORM_NS_FILE} - ${TFM_API_NS_PATH} - ) + if(CONFIG_SOC_FAMILY_NRF) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c) endif() - zephyr_include_directories( - ${TFM_GENERATED_INCLUDES} - ) - target_include_directories(tfm_api PRIVATE - ${TFM_BINARY_DIR}/install/interface/include - ${TFM_BINARY_DIR}/install/interface/include/crypto_keys + ${TFM_INTERFACE_INCLUDE_DIR} + ${TFM_INTERFACE_INCLUDE_DIR}/crypto_keys ) zephyr_library_link_libraries( - ${VENEERS_FILE} + ${TFM_INTERFACE_LIB_DIR}/s_veneers.o ) # To ensure that generated include files are created before they are used. @@ -579,4 +496,13 @@ if (CONFIG_BUILD_WITH_TFM) ${MERGED_FILE} ) endif() -endif() + + if(CONFIG_TFM_DUMMY_PROVISIONING) + message(WARNING + "TFM_DUMMY_PROVISIONING is enabled: + The device will be provisioned using dummy keys and is NOT secure! + This is not suitable for production" + ) + endif() + +endif() # CONFIG_BUILD_WITH_TFM diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index b635347b6e1a..f8285da53d60 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -177,6 +177,25 @@ config TFM_PARTITION_PLATFORM_CUSTOM_REBOOT Instead the application will have to override the weak ARM implementation of sys_arch_reset(). +config TFM_DUMMY_PROVISIONING + bool "Provision with dummy values. NOT to be used in production" + select TFM_INITIAL_ATTESTATION_KEY + default y + help + If this option is enabled (as it is by default), a set of dummy + keys / data will be provisioned. The dummy IAK matches the IAK tested + by the TF-M tests, and the dummy bl2 ROTPKs match the dummy bl2 keys + used by default. + This option MUST not be used in production hardware, as the keys are + insecure. + +config TFM_INITIAL_ATTESTATION_KEY + bool + help + Hidden option to mark that the TF-M platform has an initial + attestation key, which is a requirement for the Initial Attestation + partition. + config TFM_BL2_NOT_SUPPORTED bool help @@ -207,19 +226,8 @@ config TFM_BL2 TFM is designed to run with MCUboot in a certain configuration. This config adds MCUboot to the build - built via TFM's build system. -config TFM_BUILD_NS - bool "Build the TF-M Non-Secure application and libraries" - help - Instruct the TF-M build system to build the TF-M Non-Secure - application and libraries. - - This option is intended for testing purposes only, since this is the - easiest way to build the TF-M regression tests application and test - support libraries in the zephyr build system. - config TFM_USE_NS_APP bool "Use the TF-M Non-Secure application" - depends on TFM_BUILD_NS help The TF-M build system can produce multiple executable files. The main one is the TF-M secure firmware. Optionally the TF-M diff --git a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules index 1d70a2c44d29..02d3580c22f3 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules +++ b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules @@ -10,6 +10,7 @@ if TFM_PARTITION_CRYPTO config TFM_CRYPTO_RNG_MODULE_ENABLED bool "Random number generator crypto module" default y + depends on PSA_WANT_GENERATE_RANDOM && NRF_SECURITY help Enables the random number generator module within the crypto partition. Unset this option if 'psa_generate_random' is not used. @@ -17,6 +18,7 @@ config TFM_CRYPTO_RNG_MODULE_ENABLED config TFM_CRYPTO_KEY_MODULE_ENABLED bool "KEY crypto module" default y + depends on PSA_HAS_KEY_SUPPORT && NRF_SECURITY help Enables the KEY crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key_management.c' @@ -25,6 +27,7 @@ config TFM_CRYPTO_KEY_MODULE_ENABLED config TFM_CRYPTO_AEAD_MODULE_ENABLED bool "AEAD crypto module" default y + depends on PSA_HAS_AEAD_SUPPORT && NRF_SECURITY help Enables the AEAD crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_aead.c' @@ -33,6 +36,7 @@ config TFM_CRYPTO_AEAD_MODULE_ENABLED config TFM_CRYPTO_MAC_MODULE_ENABLED bool "MAC crypto module" default y + depends on PSA_HAS_MAC_SUPPORT && NRF_SECURITY help Enables the MAC crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_mac.c' @@ -41,6 +45,7 @@ config TFM_CRYPTO_MAC_MODULE_ENABLED config TFM_CRYPTO_HASH_MODULE_ENABLED bool "HASH crypto module" default y + depends on PSA_HAS_HASH_SUPPORT && NRF_SECURITY help Enables the HASH crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_hash.c' @@ -49,6 +54,7 @@ config TFM_CRYPTO_HASH_MODULE_ENABLED config TFM_CRYPTO_CIPHER_MODULE_ENABLED bool "CIPHER crypto module" default y + depends on PSA_HAS_CIPHER_SUPPORT && NRF_SECURITY help Enables the CIPHER crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_cipher.c' @@ -57,6 +63,7 @@ config TFM_CRYPTO_CIPHER_MODULE_ENABLED config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED bool "ASYM ENCRYPT crypto module" default y + depends on PSA_HAS_ASYM_ENCRYPT_SUPPORT && NRF_SECURITY help Enables the ASYM ENCRYPT crypto module within the crypto partition. Unset this option if the encrypt functionality provided by 'crypto_asymmetric.c' @@ -65,6 +72,7 @@ config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED bool "ASYM SIGN crypto module" default y + depends on PSA_HAS_ASYM_SIGN_SUPPORT && NRF_SECURITY help Enables the ASYM SIGN crypto module within the crypto partition. Unset this option if the sign functionality provided by 'crypto_asymmetric.c' @@ -73,10 +81,12 @@ config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED config TFM_CRYPTO_KEY_DERIVATION_MODULE_ENABLED bool "KEY DERIVATION crypto module" default y + depends on (PSA_HAS_KEY_DERIVATION || PSA_HAS_KEY_AGREEMENT) && NRF_SECURITY help Enables the KEY_DERIVATION crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key_derivation.c' is not used. + Note that key agreement is under key derivation in the current implementation. endif # TFM_PARTITION_CRYPTO diff --git a/modules/trusted-firmware-m/Kconfig.tfm.partitions b/modules/trusted-firmware-m/Kconfig.tfm.partitions index cd9aaadb1ec4..67b46f5328ba 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.partitions +++ b/modules/trusted-firmware-m/Kconfig.tfm.partitions @@ -44,6 +44,7 @@ config TFM_PARTITION_CRYPTO config TFM_PARTITION_INITIAL_ATTESTATION bool "Secure partition 'Initial Attestation'" depends on TFM_PARTITION_CRYPTO + depends on TFM_INITIAL_ATTESTATION_KEY default n help Setting this option will cause '-DTFM_PARTITION_INITIAL_ATTESTATION' diff --git a/modules/trusted-firmware-m/interface/interface.c b/modules/trusted-firmware-m/interface/interface.c index ad0ed1abdfe6..d949a9dc027a 100644 --- a/modules/trusted-firmware-m/interface/interface.c +++ b/modules/trusted-firmware-m/interface/interface.c @@ -35,7 +35,7 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, if (!is_pre_kernel) { /* TF-M request protected by NS lock */ if (k_mutex_lock(&tfm_mutex, K_FOREVER) != 0) { - return (int32_t)TFM_ERROR_GENERIC; + return (int32_t)PSA_ERROR_GENERIC_ERROR; } #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS) @@ -79,7 +79,7 @@ uint32_t tfm_ns_interface_init(void) * The static K_MUTEX_DEFINE handles mutex initialization, * so this function may be implemented as no-op. */ - return TFM_SUCCESS; + return PSA_SUCCESS; } @@ -90,7 +90,7 @@ uint32_t tfm_ns_interface_init(void) static int ns_interface_init(void) { - __ASSERT(tfm_ns_interface_init() == TFM_SUCCESS, + __ASSERT(tfm_ns_interface_init() == PSA_SUCCESS, "TF-M NS interface init failed"); return 0; diff --git a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt index 41dca2f15a95..d75b34a81098 100644 --- a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt @@ -36,14 +36,6 @@ target_include_directories(platform_s ${board_includes} ) -target_include_directories(platform_ns - PUBLIC - include - include/util - ${partition_includes} - ${board_includes} -) - if(BL2) target_include_directories(platform_bl2 PUBLIC @@ -54,14 +46,18 @@ if(BL2) ) endif() -if (TFM_PARTITION_PLATFORM) -install(FILES include/tfm_ioctl_api.h - DESTINATION ${TFM_INSTALL_PATH}/interface/include) -endif() - -#========================= tfm_spm ============================================# - target_sources(tfm_spm PRIVATE src/tfm_hal_platform.c ) + +if (TFM_PARTITION_PLATFORM) +install(FILES include/tfm_ioctl_api.h + include/device_cfg.h + include/RTE_Device.h + include/tfm_ioctl_api.h + DESTINATION ${INSTALL_INTERFACE_INC_DIR}) +endif() + +install(FILES ns/CMakeLists.txt + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) diff --git a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h index c6c36ee927fd..3fade10525af 100644 --- a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h +++ b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h @@ -9,7 +9,6 @@ #include #include -#include #include /* Include core IOCTL services */ diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt index 279ea3859961..b74620fe2d51 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt @@ -5,8 +5,19 @@ # set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf5340) add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf5340 nrf5340) add_subdirectory(.. common) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR} +) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake index b3e5d74181c8..ae50a4846dd5 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf5340 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf5340/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake new file mode 100644 index 000000000000..f19d7f43c673 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf) + +include(${PLATFORM_PATH}/common/nrf5340/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake new file mode 100644 index 000000000000..077e88bd37b4 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf5340/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake deleted file mode 100644 index d9bd226eb65a..000000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf5340/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt index a84c6fd9fd57..64fff7cdb860 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt @@ -5,8 +5,21 @@ # set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf91) add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) add_subdirectory(.. common) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf9120/cpuarch.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf9120) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf9161dk_nrf9161/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake index 3f58e7b89eb9..e858eda3a270 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf91 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.cmake new file mode 100644 index 000000000000..9f0886c7a51e --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.cmake @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# +set(PLATFORM_PATH platform/ext/target/nordic_nrf) + +include(${PLATFORM_PATH}/common/nrf9120/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake new file mode 100644 index 000000000000..c53d684d7e88 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf9120/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake deleted file mode 100644 index 4b3c6ee79abd..000000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf9120/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt index a84c6fd9fd57..aa2ef8310315 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt @@ -5,8 +5,21 @@ # set(NRF_BOARD_SELECTED True) -set(NRF_SOC_VARIANT nrf91) add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf91 nrf91) add_subdirectory(.. common) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf9160/cpuarch.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf9160) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake index 3f58e7b89eb9..e858eda3a270 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf91 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake new file mode 100644 index 000000000000..f728014d3f72 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf) + +include(${PLATFORM_PATH}/common/nrf9160/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake new file mode 100644 index 000000000000..902e7fe7ef49 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf9160/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake deleted file mode 100644 index 364480a6f7fc..000000000000 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/preload.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023, Nordic Semiconductor ASA. -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(platform/ext/target/nordic_nrf/common/nrf9160/preload.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/ns/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/ns/CMakeLists.txt new file mode 100644 index 000000000000..5bb8cb5bd94a --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/ns/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(NRF_BOARD_SELECTED True) + +add_library(platform_ns STATIC) + +set(partition_includes + ${CMAKE_CURRENT_LIST_DIR}/common/${NRF_SOC_VARIANT}/partition + ${CMAKE_BINARY_DIR}/../zephyr/include/generated +) + +set(board_includes + ${CMAKE_BINARY_DIR}/../zephyr/misc/generated/syscalls_links/include + ${ZEPHYR_BASE}/include +) + +target_include_directories(platform_region_defs + INTERFACE + ${partition_includes} +) + +target_include_directories(platform_ns + PUBLIC + ${partition_includes} + ${board_includes} +) + +# Get the value of HAL_NORDIC_PATH +include(${CMAKE_CURRENT_LIST_DIR}/common/core/config_nordic_nrf_spe.cmake) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common/${NRF_SOC_VARIANT} ${NRF_SOC_VARIANT}) + +target_include_directories(platform_ns + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +target_link_libraries(platform_ns + PUBLIC + platform_region_defs +) diff --git a/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c b/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c deleted file mode 100644 index d7d68f9db673..000000000000 --- a/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/** - * \brief This symbol is the entry point provided by the PSA API compliance - * test libraries - */ -extern void val_entry(void); - - -void psa_test(void) -{ - val_entry(); -} diff --git a/modules/uoscore-uedhoc/CMakeLists.txt b/modules/uoscore-uedhoc/CMakeLists.txt index e23ad7da2e67..aaf842e392ca 100644 --- a/modules/uoscore-uedhoc/CMakeLists.txt +++ b/modules/uoscore-uedhoc/CMakeLists.txt @@ -29,7 +29,7 @@ if (CONFIG_UOSCORE OR CONFIG_UEDHOC) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild index 37a6b66c7f4d..f434010f81d2 100644 --- a/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild +++ b/samples/bluetooth/broadcast_audio_sink/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "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/broadcast_audio_sink/sysbuild.cmake b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake index c150913cc551..2523aac8ea76 100644 --- a/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild index 37a6b66c7f4d..f434010f81d2 100644 --- a/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild +++ b/samples/bluetooth/broadcast_audio_source/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "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/broadcast_audio_source/sysbuild.cmake b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake index c150913cc551..2523aac8ea76 100644 --- a/samples/bluetooth/broadcast_audio_source/sysbuild.cmake +++ b/samples/bluetooth/broadcast_audio_source/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf new file mode 100644 index 000000000000..e6749ae63990 --- /dev/null +++ b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf b/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf new file mode 100644 index 000000000000..e6749ae63990 --- /dev/null +++ b/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/mesh/CMakeLists.txt b/samples/bluetooth/mesh/CMakeLists.txt index 6ee28b12d488..74734eb84b45 100644 --- a/samples/bluetooth/mesh/CMakeLists.txt +++ b/samples/bluetooth/mesh/CMakeLists.txt @@ -16,6 +16,6 @@ endif() if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh/README.rst b/samples/bluetooth/mesh/README.rst index e6ee78ba3a75..58532a0600bb 100644 --- a/samples/bluetooth/mesh/README.rst +++ b/samples/bluetooth/mesh/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Overview ******** -This sample demonstrates Bluetooth mesh functionality. It has several +This sample demonstrates Bluetooth Mesh functionality. It has several standard mesh models, and supports provisioning over both the Advertising and the GATT Provisioning Bearers (i.e. PB-ADV and PB-GATT). The application also needs a functioning serial console, since that's diff --git a/samples/bluetooth/mesh/boards/bbc_microbit.conf b/samples/bluetooth/mesh/boards/bbc_microbit.conf index 26fb05301c1c..1655768864b1 100644 --- a/samples/bluetooth/mesh/boards/bbc_microbit.conf +++ b/samples/bluetooth/mesh/boards/bbc_microbit.conf @@ -32,3 +32,4 @@ CONFIG_BT_MESH_SUBNET_COUNT=1 CONFIG_BT_MESH_APP_KEY_COUNT=1 CONFIG_BT_MESH_MODEL_GROUP_COUNT=1 CONFIG_BT_MESH_LABEL_COUNT=0 +CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n diff --git a/samples/bluetooth/mesh_demo/CMakeLists.txt b/samples/bluetooth/mesh_demo/CMakeLists.txt index 07736d6c12e1..f5d347ab373b 100644 --- a/samples/bluetooth/mesh_demo/CMakeLists.txt +++ b/samples/bluetooth/mesh_demo/CMakeLists.txt @@ -15,6 +15,6 @@ endif() if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh_demo/README.rst b/samples/bluetooth/mesh_demo/README.rst index 7fe7f0908cee..2edb690ab196 100644 --- a/samples/bluetooth/mesh_demo/README.rst +++ b/samples/bluetooth/mesh_demo/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Demo Overview ******** -This sample is a Bluetooth mesh application intended for demonstration +This sample is a Bluetooth Mesh application intended for demonstration purposes only. The application provisions and configures itself (i.e. no external provisioner needed) with hard-coded network and application key values. The local unicast address can be set using a NODE_ADDR build diff --git a/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf b/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf index 5eb087c4cedd..64adc4657945 100644 --- a/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf +++ b/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf @@ -22,3 +22,4 @@ CONFIG_BT_MESH_BEACON_ENABLED=n CONFIG_BT_MESH_LABEL_COUNT=1 CONFIG_BT_MESH_SETTINGS_WORKQ=n +CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n diff --git a/samples/bluetooth/mesh_provisioner/CMakeLists.txt b/samples/bluetooth/mesh_provisioner/CMakeLists.txt index 7b22bd0fe14c..aefe3628ba87 100644 --- a/samples/bluetooth/mesh_provisioner/CMakeLists.txt +++ b/samples/bluetooth/mesh_provisioner/CMakeLists.txt @@ -10,6 +10,6 @@ target_sources(app PRIVATE src/main.c) if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh_provisioner/README.rst b/samples/bluetooth/mesh_provisioner/README.rst index 6da113afc1bc..1b37a04a4a83 100644 --- a/samples/bluetooth/mesh_provisioner/README.rst +++ b/samples/bluetooth/mesh_provisioner/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Provisioner Overview ******** -This sample demonstrates how to use the Bluetooth mesh APIs related to +This sample demonstrates how to use the Bluetooth Mesh APIs related to provisioning and using the Configuration Database (CDB). It is intended to be tested together with a device capable of being provisioned. For example, one could use the sample in diff --git a/samples/bluetooth/mesh_provisioner/prj.conf b/samples/bluetooth/mesh_provisioner/prj.conf index bfc6d5a12417..341dd49ed2e5 100644 --- a/samples/bluetooth/mesh_provisioner/prj.conf +++ b/samples/bluetooth/mesh_provisioner/prj.conf @@ -33,7 +33,7 @@ CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT=3 CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=n +CONFIG_BT_MESH_PROVISIONEE=n CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_CDB_NODE_COUNT=16 CONFIG_BT_MESH_CDB_SUBNET_COUNT=3 diff --git a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild index 37a6b66c7f4d..f434010f81d2 100644 --- a/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "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/unicast_audio_client/sysbuild.cmake b/samples/bluetooth/unicast_audio_client/sysbuild.cmake index c150913cc551..2523aac8ea76 100644 --- a/samples/bluetooth/unicast_audio_client/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_client/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild index 37a6b66c7f4d..f434010f81d2 100644 --- a/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild +++ b/samples/bluetooth/unicast_audio_server/Kconfig.sysbuild @@ -8,3 +8,8 @@ config NET_CORE_BOARD default "nrf5340dk_nrf5340_cpunet" if $(BOARD) = "nrf5340dk_nrf5340_cpuapp" default "nrf5340_audio_dk_nrf5340_cpunet" if $(BOARD) = "nrf5340_audio_dk_nrf5340_cpuapp" default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "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/unicast_audio_server/sysbuild.cmake b/samples/bluetooth/unicast_audio_server/sysbuild.cmake index c150913cc551..2523aac8ea76 100644 --- a/samples/bluetooth/unicast_audio_server/sysbuild.cmake +++ b/samples/bluetooth/unicast_audio_server/sysbuild.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) +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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - endif() + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) - # Let's meet the expectation of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/boards/nrf/mesh/onoff-app/README.rst b/samples/boards/nrf/mesh/onoff-app/README.rst index e8cadccd53cb..35e37d6a599b 100644 --- a/samples/boards/nrf/mesh/onoff-app/README.rst +++ b/samples/boards/nrf/mesh/onoff-app/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh OnOff Model Overview ******** -This is a simple application demonstrating a Bluetooth mesh multi-element node. +This is a simple application demonstrating a Bluetooth Mesh multi-element node. Each element has a mesh onoff client and server model which controls one of the 4 sets of buttons and LEDs . diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst index 05b8d896e771..f33bf1e77611 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst @@ -4,7 +4,7 @@ Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models ###################################################################### Overview ******** -This is a application demonstrating a Bluetooth mesh node in +This is a application demonstrating a Bluetooth Mesh node in which Root element has following models - Generic OnOff Server diff --git a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake index a5d1eb9874f8..0c97244fd7b3 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake +++ b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_NET_CORE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${REMOTE_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/boards/nrf/nrf53_sync_rtc/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/boards/nrf/nrfx/Kconfig b/samples/boards/nrf/nrfx/Kconfig index 0d54067202a2..09076c9da49e 100644 --- a/samples/boards/nrf/nrfx/Kconfig +++ b/samples/boards/nrf/nrfx/Kconfig @@ -7,4 +7,14 @@ config NRFX_DPPI config NRFX_PPI default HAS_HW_NRF_PPI +config NRFX_GPIOTE0 + default y if SOC_SERIES_NRF51X || \ + SOC_SERIES_NRF52X || \ + (SOC_SERIES_NRF53X && !TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91X && !TRUSTED_EXECUTION_NONSECURE) + +config NRFX_GPIOTE1 + default y if (SOC_SERIES_NRF53X && TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91X && TRUSTED_EXECUTION_NONSECURE) + source "Kconfig.zephyr" diff --git a/samples/boards/nrf/nrfx/prj.conf b/samples/boards/nrf/nrfx/prj.conf index 32cbfc3279cc..d4f0c29699f8 100644 --- a/samples/boards/nrf/nrfx/prj.conf +++ b/samples/boards/nrf/nrfx/prj.conf @@ -1,4 +1,3 @@ CONFIG_GPIO=n -CONFIG_NRFX_GPIOTE=y CONFIG_LOG=y CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 diff --git a/samples/boards/nrf/nrfx/src/main.c b/samples/boards/nrf/nrfx/src/main.c index 615b800545e4..0643b1c09117 100644 --- a/samples/boards/nrf/nrfx/src/main.c +++ b/samples/boards/nrf/nrfx/src/main.c @@ -21,6 +21,15 @@ LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF); #define INPUT_PIN DT_GPIO_PIN(DT_ALIAS(sw0), gpios) #define OUTPUT_PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios) +#define GPIOTE_INST NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios) +#define GPIOTE_NODE DT_NODELABEL(_CONCAT(gpiote, GPIOTE_INST)) + +BUILD_ASSERT(NRF_DT_GPIOTE_INST(DT_ALIAS(led0), gpios) == GPIOTE_INST, + "Both sw0 and led0 GPIOs must use the same GPIOTE instance"); +BUILD_ASSERT(IS_ENABLED(_CONCAT(CONFIG_, _CONCAT(NRFX_GPIOTE, GPIOTE_INST))), + "NRFX_GPIOTE" STRINGIFY(GPIOTE_INST) " must be enabled in Kconfig"); + + static void button_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t trigger, void *context) @@ -35,28 +44,28 @@ int main(void) nrfx_err_t err; uint8_t in_channel, out_channel; uint8_t ppi_channel; + const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(GPIOTE_INST); - /* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */ - IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)), - DT_IRQ(DT_NODELABEL(gpiote), priority), - nrfx_isr, nrfx_gpiote_irq_handler, 0); + /* Connect GPIOTE instance IRQ to irq handler */ + IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), nrfx_isr, + NRFX_CONCAT(nrfx_gpiote_, GPIOTE_INST, _irq_handler), 0); /* Initialize GPIOTE (the interrupt priority passed as the parameter * here is ignored, see nrfx_glue.h). */ - err = nrfx_gpiote_init(0); + err = nrfx_gpiote_init(&gpiote, 0); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_gpiote_init error: 0x%08X", err); return 0; } - err = nrfx_gpiote_channel_alloc(&in_channel); + err = nrfx_gpiote_channel_alloc(&gpiote, &in_channel); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate in_channel, error: 0x%08X", err); return 0; } - err = nrfx_gpiote_channel_alloc(&out_channel); + err = nrfx_gpiote_channel_alloc(&gpiote, &out_channel); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate out_channel, error: 0x%08X", err); return 0; @@ -65,20 +74,22 @@ int main(void) /* Initialize input pin to generate event on high to low transition * (falling edge) and call button_handler() */ - static const nrfx_gpiote_input_config_t input_config = { - .pull = NRF_GPIO_PIN_PULLUP, - }; - const nrfx_gpiote_trigger_config_t trigger_config = { + static const nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLUP; + nrfx_gpiote_trigger_config_t trigger_config = { .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, .p_in_channel = &in_channel, }; static const nrfx_gpiote_handler_config_t handler_config = { .handler = button_handler, }; - err = nrfx_gpiote_input_configure(INPUT_PIN, - &input_config, - &trigger_config, - &handler_config); + nrfx_gpiote_input_pin_config_t input_config = { + .p_pull_config = &pull_config, + .p_trigger_config = &trigger_config, + .p_handler_config = &handler_config + }; + + err = nrfx_gpiote_input_configure(&gpiote, INPUT_PIN, &input_config); + if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_gpiote_input_configure error: 0x%08X", err); return 0; @@ -97,7 +108,7 @@ int main(void) .polarity = NRF_GPIOTE_POLARITY_TOGGLE, .init_val = 1, }; - err = nrfx_gpiote_output_configure(OUTPUT_PIN, + err = nrfx_gpiote_output_configure(&gpiote, OUTPUT_PIN, &output_config, &task_config); if (err != NRFX_SUCCESS) { @@ -105,8 +116,8 @@ int main(void) return 0; } - nrfx_gpiote_trigger_enable(INPUT_PIN, true); - nrfx_gpiote_out_task_enable(OUTPUT_PIN); + nrfx_gpiote_trigger_enable(&gpiote, INPUT_PIN, true); + nrfx_gpiote_out_task_enable(&gpiote, OUTPUT_PIN); LOG_INF("nrfx_gpiote initialized"); @@ -122,8 +133,8 @@ int main(void) * the button is pressed, the LED pin will be toggled. */ nrfx_gppi_channel_endpoints_setup(ppi_channel, - nrfx_gpiote_in_event_address_get(INPUT_PIN), - nrfx_gpiote_out_task_address_get(OUTPUT_PIN)); + nrfx_gpiote_in_event_address_get(&gpiote, INPUT_PIN), + nrfx_gpiote_out_task_address_get(&gpiote, OUTPUT_PIN)); /* Enable the channel. */ nrfx_gppi_channels_enable(BIT(ppi_channel)); diff --git a/samples/boards/reel_board/mesh_badge/README.rst b/samples/boards/reel_board/mesh_badge/README.rst index d5973ab8e9c4..ccfc7e771aea 100644 --- a/samples/boards/reel_board/mesh_badge/README.rst +++ b/samples/boards/reel_board/mesh_badge/README.rst @@ -6,7 +6,7 @@ Mesh Badge Overview ******** -This sample app for the reel board showcases Bluetooth mesh +This sample app for the reel board showcases Bluetooth Mesh The app starts off as a regular Bluetooth GATT peripheral application. Install the "nRF Connect" app on your phone (available both for @@ -34,7 +34,7 @@ Steps to set up you're not happy with it you can try writing something else. #. When you're happy with the text, disconnect from the board (exit the app or go back to the device scan page) -#. Once disconnected the board switches over to Bluetooth mesh mode, and you +#. Once disconnected the board switches over to Bluetooth Mesh mode, and you can't connect to it anymore over GATT. If you configure multiple boards like this they can communicate with diff --git a/samples/drivers/counter/alarm/CMakeLists.txt b/samples/drivers/counter/alarm/CMakeLists.txt index eadc9e99e67d..747c2b27ebd6 100644 --- a/samples/drivers/counter/alarm/CMakeLists.txt +++ b/samples/drivers/counter/alarm/CMakeLists.txt @@ -9,6 +9,6 @@ target_sources(app PRIVATE ${app_sources}) if(CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake index 1bd6a00ae9e1..a8dfb8ebdf40 100644 --- a/samples/drivers/mbox/sysbuild.cmake +++ b/samples/drivers/mbox/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_REMOTE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${REMOTE_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${REMOTE_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/drivers/mbox/sysbuild.conf b/samples/drivers/mbox/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/drivers/mbox/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/drivers/soc_flash_nrf/README.rst b/samples/drivers/soc_flash_nrf/README.rst index 496688e8b65f..2ee87739aad0 100644 --- a/samples/drivers/soc_flash_nrf/README.rst +++ b/samples/drivers/soc_flash_nrf/README.rst @@ -62,7 +62,7 @@ Sample Output Data read: 1234 Data read matches data written. Good! - Test 3: Flash erase (4 pages at 0x80000) + Test 3: Flash erase (2 pages at 0x80000) Flash erase succeeded! Test 4: Flash write (word array 2) @@ -131,3 +131,5 @@ Sample Output Test 8: Write block size API write-block-size = 1 + + Finished! diff --git a/samples/drivers/soc_flash_nrf/prj.conf b/samples/drivers/soc_flash_nrf/prj.conf index 9909ef3b29f8..48e64121b6a1 100644 --- a/samples/drivers/soc_flash_nrf/prj.conf +++ b/samples/drivers/soc_flash_nrf/prj.conf @@ -3,3 +3,7 @@ CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_MPU_ALLOW_FLASH_WRITE=y CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/samples/drivers/soc_flash_nrf/sample.yaml b/samples/drivers/soc_flash_nrf/sample.yaml index b8a59328be40..d1f635ca93fa 100644 --- a/samples/drivers/soc_flash_nrf/sample.yaml +++ b/samples/drivers/soc_flash_nrf/sample.yaml @@ -29,3 +29,4 @@ tests: - "Data read matches data written. Good!" - "SoC flash consists of \\d+ pages." - "write-block-size = 1" + - "Finished!" diff --git a/samples/drivers/soc_flash_nrf/src/main.c b/samples/drivers/soc_flash_nrf/src/main.c index a438a67cf2fc..29606a9ca5df 100644 --- a/samples/drivers/soc_flash_nrf/src/main.c +++ b/samples/drivers/soc_flash_nrf/src/main.c @@ -13,11 +13,7 @@ #include -#ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE -#define TEST_PARTITION slot1_ns_partition -#else -#define TEST_PARTITION slot1_partition -#endif +#define TEST_PARTITION storage_partition #define TEST_PARTITION_OFFSET FIXED_PARTITION_OFFSET(TEST_PARTITION) #define TEST_PARTITION_DEVICE FIXED_PARTITION_DEVICE(TEST_PARTITION) @@ -84,9 +80,9 @@ int main(void) } } - offset = TEST_PARTITION_OFFSET - FLASH_PAGE_SIZE * 2; - printf("\nTest 3: Flash erase (4 pages at 0x%x)\n", offset); - if (flash_erase(flash_dev, offset, FLASH_PAGE_SIZE * 4) != 0) { + offset = TEST_PARTITION_OFFSET; + printf("\nTest 3: Flash erase (2 pages at 0x%x)\n", offset); + if (flash_erase(flash_dev, offset, FLASH_PAGE_SIZE * 2) != 0) { printf(" Flash erase failed!\n"); } else { printf(" Flash erase succeeded!\n"); @@ -191,5 +187,7 @@ int main(void) printf("\nTest 8: Write block size API\n"); printf(" write-block-size = %u\n", flash_get_write_block_size(flash_dev)); + + printf("\nFinished!\n"); return 0; } diff --git a/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..66157d79fb36 --- /dev/null +++ b/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt30 { + status = "okay"; +}; diff --git a/samples/net/dhcpv4_client/overlay-nrf700x.conf b/samples/net/dhcpv4_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..2d552e9c6231 --- /dev/null +++ b/samples/net/dhcpv4_client/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/dns_resolve/overlay-nrf700x.conf b/samples/net/dns_resolve/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/dns_resolve/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/ipv4_autoconf/overlay-nrf700x.conf b/samples/net/ipv4_autoconf/overlay-nrf700x.conf new file mode 100644 index 000000000000..2d552e9c6231 --- /dev/null +++ b/samples/net/ipv4_autoconf/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/lwm2m_client/overlay-queue.conf b/samples/net/lwm2m_client/overlay-queue.conf index 1adc9eda5ec3..946c0fbab671 100644 --- a/samples/net/lwm2m_client/overlay-queue.conf +++ b/samples/net/lwm2m_client/overlay-queue.conf @@ -1,5 +1,7 @@ CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 +CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE=y + # Default lifetime is 1 day CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=86400 # Send update once an hour diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index 748f654d9eed..2e9792e51eae 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -16,6 +16,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include +#include #include "modules.h" #define APP_BANNER "Run LWM2M client" @@ -29,6 +31,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_FIRMWARE_VER "1.0" #define CLIENT_HW_VER "1.0.1" +/* Macros used to subscribe to specific Zephyr NET management events. */ +#define L4_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED) +#define CONN_LAYER_EVENT_MASK (NET_EVENT_CONN_IF_FATAL_ERROR) + static uint8_t bat_idx = LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT; static int bat_mv = 3800; static int bat_ma = 125; @@ -52,6 +58,12 @@ BUILD_ASSERT(sizeof(endpoint) <= CONFIG_LWM2M_SECURITY_KEY_SIZE, static struct k_sem quit_lock; +/* Zephyr NET management event callback structures. */ +static struct net_mgmt_event_callback l4_cb; +static struct net_mgmt_event_callback conn_cb; + +static K_SEM_DEFINE(network_connected_sem, 0, 1); + static int device_reboot_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { @@ -179,6 +191,10 @@ static void rd_client_event(struct lwm2m_ctx *client, /* do nothing */ break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_DBG("LwM2M server disabled"); + break; + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: LOG_DBG("Bootstrap registration failure!"); break; @@ -237,6 +253,25 @@ static void rd_client_event(struct lwm2m_ctx *client, } } +static void socket_state(int fd, enum lwm2m_socket_states state) +{ + (void) fd; + switch (state) { + case LWM2M_SOCKET_STATE_ONGOING: + LOG_DBG("LWM2M_SOCKET_STATE_ONGOING"); + break; + case LWM2M_SOCKET_STATE_ONE_RESPONSE: + LOG_DBG("LWM2M_SOCKET_STATE_ONE_RESPONSE"); + break; + case LWM2M_SOCKET_STATE_LAST: + LOG_DBG("LWM2M_SOCKET_STATE_LAST"); + break; + case LWM2M_SOCKET_STATE_NO_DATA: + LOG_DBG("LWM2M_SOCKET_STATE_NO_DATA"); + break; + } +} + static void observe_cb(enum lwm2m_observe_event event, struct lwm2m_obj_path *path, void *user_data) { @@ -265,6 +300,47 @@ static void observe_cb(enum lwm2m_observe_event event, } } +static void on_net_event_l4_disconnected(void) +{ + LOG_INF("Disconnected from network"); + lwm2m_engine_pause(); +} + +static void on_net_event_l4_connected(void) +{ + LOG_INF("Connected to network"); + k_sem_give(&network_connected_sem); + lwm2m_engine_resume(); +} + +static void l4_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, + struct net_if *iface) +{ + switch (event) { + case NET_EVENT_L4_CONNECTED: + LOG_INF("IP Up"); + on_net_event_l4_connected(); + break; + case NET_EVENT_L4_DISCONNECTED: + LOG_INF("IP down"); + on_net_event_l4_disconnected(); + break; + default: + break; + } +} + +static void connectivity_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, + struct net_if *iface) +{ + if (event == NET_EVENT_CONN_IF_FATAL_ERROR) { + LOG_ERR("Fatal error received from the connectivity layer"); + return; + } +} + int main(void) { uint32_t flags = IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) ? @@ -275,6 +351,31 @@ int main(void) k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT); + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { + /* Setup handler for Zephyr NET Connection Manager events. */ + net_mgmt_init_event_callback(&l4_cb, l4_event_handler, L4_EVENT_MASK); + net_mgmt_add_event_callback(&l4_cb); + + /* Setup handler for Zephyr NET Connection Manager Connectivity layer. */ + net_mgmt_init_event_callback(&conn_cb, connectivity_event_handler, + CONN_LAYER_EVENT_MASK); + net_mgmt_add_event_callback(&conn_cb); + + ret = net_if_up(net_if_get_default()); + + if (ret < 0 && ret != -EALREADY) { + LOG_ERR("net_if_up, error: %d", ret); + return ret; + } + + ret = conn_mgr_if_connect(net_if_get_default()); + /* Ignore errors from interfaces not requiring connectivity */ + if (ret == 0) { + LOG_INF("Connecting to network"); + k_sem_take(&network_connected_sem, K_FOREVER); + } + } + ret = lwm2m_setup(); if (ret < 0) { LOG_ERR("Cannot setup LWM2M fields (%d)", ret); @@ -285,6 +386,7 @@ int main(void) #if defined(CONFIG_LWM2M_DTLS_SUPPORT) client_ctx.tls_tag = CONFIG_LWM2M_APP_TLS_TAG; #endif + client_ctx.set_socket_state = socket_state; /* client_ctx.sec_obj_inst is 0 as a starting point */ lwm2m_rd_client_start(&client_ctx, endpoint, flags, rd_client_event, observe_cb); diff --git a/samples/net/mdns_responder/overlay-nrf700x.conf b/samples/net/mdns_responder/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/mdns_responder/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_publisher/overlay-nrf700x.conf b/samples/net/mqtt_publisher/overlay-nrf700x.conf new file mode 100644 index 000000000000..a812c7896f62 --- /dev/null +++ b/samples/net/mqtt_publisher/overlay-nrf700x.conf @@ -0,0 +1,19 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_client/overlay-nrf700x.conf b/samples/net/sockets/coap_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..a0e436e3537d --- /dev/null +++ b/samples/net/sockets/coap_client/overlay-nrf700x.conf @@ -0,0 +1,16 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_server/overlay-nrf700x.conf b/samples/net/sockets/coap_server/overlay-nrf700x.conf new file mode 100644 index 000000000000..4817a4f73ba6 --- /dev/null +++ b/samples/net/sockets/coap_server/overlay-nrf700x.conf @@ -0,0 +1,26 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# The sample can run either IPv4 or IPv6, not both +CONFIG_NET_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_CONFIG_NEED_IPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_server/prj.conf b/samples/net/sockets/coap_server/prj.conf index 1a26e6147862..59d444db4566 100644 --- a/samples/net/sockets/coap_server/prj.conf +++ b/samples/net/sockets/coap_server/prj.conf @@ -13,7 +13,6 @@ CONFIG_COAP=y CONFIG_COAP_SERVER=y CONFIG_COAP_SERVER_WELL_KNOWN_CORE=y CONFIG_COAP_WELL_KNOWN_BLOCK_WISE=n -CONFIG_COAP_OBSERVER_EVENTS=y # Kernel options CONFIG_ENTROPY_GENERATOR=y @@ -30,6 +29,11 @@ CONFIG_COAP_SERVER_SHELL=y # Configuration CONFIG_NET_CONFIG_SETTINGS=y +# Events +CONFIG_NET_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y + # Enable only one protocol, if you enable both sources # won't compile. # IPv6 Support diff --git a/samples/net/sockets/coap_server/src/core.c b/samples/net/sockets/coap_server/src/core.c index 276ab0d5de18..00f4adb4d349 100644 --- a/samples/net/sockets/coap_server/src/core.c +++ b/samples/net/sockets/coap_server/src/core.c @@ -45,7 +45,7 @@ static int core_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/events.c b/samples/net/sockets/coap_server/src/events.c new file mode 100644 index 000000000000..3f843fba0171 --- /dev/null +++ b/samples/net/sockets/coap_server/src/events.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +#define COAP_EVENTS_SET (NET_EVENT_COAP_OBSERVER_ADDED | NET_EVENT_COAP_OBSERVER_REMOVED | \ + NET_EVENT_COAP_SERVICE_STARTED | NET_EVENT_COAP_SERVICE_STOPPED) + +void coap_event_handler(uint32_t mgmt_event, struct net_if *iface, + void *info, size_t info_length, void *user_data) +{ + ARG_UNUSED(iface); + ARG_UNUSED(user_data); + + switch (mgmt_event) { + case NET_EVENT_COAP_OBSERVER_ADDED: + LOG_INF("CoAP observer added"); + break; + case NET_EVENT_COAP_OBSERVER_REMOVED: + LOG_INF("CoAP observer removed"); + break; + case NET_EVENT_COAP_SERVICE_STARTED: + if (info != NULL && info_length == sizeof(struct net_event_coap_service)) { + struct net_event_coap_service *net_event = info; + + LOG_INF("CoAP service %s started", net_event->service->name); + } else { + LOG_INF("CoAP service started"); + } + break; + case NET_EVENT_COAP_SERVICE_STOPPED: + if (info != NULL && info_length == sizeof(struct net_event_coap_service)) { + struct net_event_coap_service *net_event = info; + + LOG_INF("CoAP service %s stopped", net_event->service->name); + } else { + LOG_INF("CoAP service stopped"); + } + break; + } +} + +NET_MGMT_REGISTER_EVENT_HANDLER(coap_events, COAP_EVENTS_SET, coap_event_handler, NULL); diff --git a/samples/net/sockets/coap_server/src/large.c b/samples/net/sockets/coap_server/src/large.c index 28a3eebe099f..8656a5b53b14 100644 --- a/samples/net/sockets/coap_server/src/large.c +++ b/samples/net/sockets/coap_server/src/large.c @@ -87,7 +87,7 @@ static int large_get(struct coap_resource *resource, memset(&ctx, 0, sizeof(ctx)); } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -167,7 +167,7 @@ static int large_update_put(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -239,7 +239,7 @@ static int large_create_post(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/location_query.c b/samples/net/sockets/coap_server/src/location_query.c index b13079bc4567..bce4eb67b862 100644 --- a/samples/net/sockets/coap_server/src/location_query.c +++ b/samples/net/sockets/coap_server/src/location_query.c @@ -59,7 +59,7 @@ static int location_query_post(struct coap_resource *resource, } } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/observer.c b/samples/net/sockets/coap_server/src/observer.c index 29b7b4ed4727..8a14d316c61b 100644 --- a/samples/net/sockets/coap_server/src/observer.c +++ b/samples/net/sockets/coap_server/src/observer.c @@ -17,16 +17,6 @@ static int obs_counter; static void update_counter(struct k_work *work); K_WORK_DELAYABLE_DEFINE(obs_work, update_counter); -#ifdef CONFIG_COAP_OBSERVER_EVENTS - -static void observer_event(struct coap_resource *resource, struct coap_observer *observer, - enum coap_observer_event event) -{ - LOG_INF("Observer %s", event == COAP_OBSERVER_ADDED ? "added" : "removed"); -} - -#endif - static int send_notification_packet(struct coap_resource *resource, const struct sockaddr *addr, socklen_t addr_len, @@ -90,7 +80,7 @@ static int send_notification_packet(struct coap_resource *resource, k_work_reschedule(&obs_work, K_SECONDS(5)); - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -138,9 +128,6 @@ COAP_RESOURCE_DEFINE(obs, coap_server, .get = obs_get, .path = obs_path, .notify = obs_notify, -#ifdef CONFIG_COAP_OBSERVER_EVENTS - .observer_event_handler = observer_event, -#endif }); static void update_counter(struct k_work *work) diff --git a/samples/net/sockets/coap_server/src/query.c b/samples/net/sockets/coap_server/src/query.c index 10479b1e6f19..95272189d9ca 100644 --- a/samples/net/sockets/coap_server/src/query.c +++ b/samples/net/sockets/coap_server/src/query.c @@ -89,7 +89,7 @@ static int query_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/separate.c b/samples/net/sockets/coap_server/src/separate.c index c3f6f6c256ee..68bba0bb473c 100644 --- a/samples/net/sockets/coap_server/src/separate.c +++ b/samples/net/sockets/coap_server/src/separate.c @@ -43,7 +43,7 @@ static int separate_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); if (r < 0) { return r; } @@ -86,7 +86,7 @@ static int separate_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/test.c b/samples/net/sockets/coap_server/src/test.c index aa496a125b10..52885b31a5dd 100644 --- a/samples/net/sockets/coap_server/src/test.c +++ b/samples/net/sockets/coap_server/src/test.c @@ -73,7 +73,7 @@ static int piggyback_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -113,7 +113,7 @@ static int test_del(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -160,7 +160,7 @@ static int test_put(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -221,7 +221,7 @@ static int test_post(struct coap_resource *resource, } } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/echo/overlay-nrf700x.conf b/samples/net/sockets/echo/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/echo/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_async/overlay-nrf700x.conf b/samples/net/sockets/echo_async/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/echo_async/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_client/overlay-nrf700x.conf b/samples/net/sockets/echo_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/sockets/echo_client/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_server/overlay-nrf700x.conf b/samples/net/sockets/echo_server/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/sockets/echo_server/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/http_get/overlay-nrf700x.conf b/samples/net/sockets/http_get/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/http_get/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/sntp_client/overlay-nrf700x.conf b/samples/net/sockets/sntp_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/sntp_client/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/syslog_net/overlay-nrf700x.conf b/samples/net/syslog_net/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/syslog_net/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/telnet/overlay-nrf700x.conf b/samples/net/telnet/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/telnet/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..3d872a2071bf --- /dev/null +++ b/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + qdec0 = &qdec20; + qenca = &phase_a; + qencb = &phase_b; + }; + + encoder-emulate { + compatible = "gpio-leds"; + phase_a: phase_a { + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + }; + phase_b: phase_b { + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&pinctrl { + qdec_pinctrl: qdec_pinctrl { + group1 { + psels = , + ; + }; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&qdec20 { + status = "okay"; + pinctrl-0 = <&qdec_pinctrl>; + pinctrl-names = "default"; + steps = <120>; + led-pre = <500>; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c index 9b288f8a6a18..f285f4b6d23c 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/remote/src/main.c @@ -193,7 +193,7 @@ static void ipc1_ept_recv(const void *data, size_t len, void *priv) { ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc0B_data_sem); + k_sem_give(&ipc1_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c b/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c index 78d7af052882..4ad5659df382 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/src/main.c @@ -190,7 +190,7 @@ static void ipc1_ept_recv(const void *data, size_t len, void *priv) { ipc1_received_data = *((uint8_t *) data); - k_sem_give(&ipc0B_data_sem); + k_sem_give(&ipc1_data_sem); } static struct ipc_ept_cfg ipc1_ept_cfg = { diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf b/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/logging/multidomain/sysbuild.cmake b/samples/subsys/logging/multidomain/sysbuild.cmake index e50f47b6db1a..496a7a03f9de 100644 --- a/samples/subsys/logging/multidomain/sysbuild.cmake +++ b/samples/subsys/logging/multidomain/sysbuild.cmake @@ -15,24 +15,6 @@ ExternalZephyrProject_Add( BOARD ${SB_CONFIG_NET_CORE_BOARD} ) -if("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) +native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) - - # Let's meet users expectations of finding the final executable in zephyr/zephyr.exe - add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} - ) -endif() +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/subsys/logging/multidomain/sysbuild.conf b/samples/subsys/logging/multidomain/sysbuild.conf new file mode 100644 index 000000000000..6408669a8474 --- /dev/null +++ b/samples/subsys/logging/multidomain/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_PARTITION_MANAGER=n diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf new file mode 100644 index 000000000000..98260877332f --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf new file mode 100644 index 000000000000..98260877332f --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/samples/subsys/usb/mass/CMakeLists.txt b/samples/subsys/usb/mass/CMakeLists.txt index ef71596104d7..2ac19d9b0169 100644 --- a/samples/subsys/usb/mass/CMakeLists.txt +++ b/samples/subsys/usb/mass/CMakeLists.txt @@ -15,6 +15,6 @@ target_sources(app PRIVATE ${app_sources}) if(CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/tfm_integration/psa_crypto/CMakeLists.txt b/samples/tfm_integration/psa_crypto/CMakeLists.txt index 17339b470b81..f8ef1eca23fb 100644 --- a/samples/tfm_integration/psa_crypto/CMakeLists.txt +++ b/samples/tfm_integration/psa_crypto/CMakeLists.txt @@ -16,7 +16,7 @@ target_sources(app PRIVATE src/util_app_log.c) target_sources(app PRIVATE src/util_sformat.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) # In TF-M, default value of CRYPTO_ENGINE_BUF_SIZE is 0x2080. It causes diff --git a/samples/tfm_integration/psa_protected_storage/CMakeLists.txt b/samples/tfm_integration/psa_protected_storage/CMakeLists.txt index bbb8a2041fd7..dfb0169eda6c 100644 --- a/samples/tfm_integration/psa_protected_storage/CMakeLists.txt +++ b/samples/tfm_integration/psa_protected_storage/CMakeLists.txt @@ -13,5 +13,5 @@ project(protected_storage) target_sources(app PRIVATE src/main.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) diff --git a/samples/tfm_integration/tfm_ipc/CMakeLists.txt b/samples/tfm_integration/tfm_ipc/CMakeLists.txt index f11b67af843d..896af7bfbdaa 100644 --- a/samples/tfm_integration/tfm_ipc/CMakeLists.txt +++ b/samples/tfm_integration/tfm_ipc/CMakeLists.txt @@ -9,5 +9,5 @@ project(tfm_ipc) target_sources(app PRIVATE src/main.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) diff --git a/samples/tfm_integration/tfm_ipc/src/main.c b/samples/tfm_integration/tfm_ipc/src/main.c index 7179705cbe3c..133c7203b0ef 100644 --- a/samples/tfm_integration/tfm_ipc/src/main.c +++ b/samples/tfm_integration/tfm_ipc/src/main.c @@ -7,7 +7,6 @@ #include #include -#include "tfm_api.h" #include "tfm_ns_interface.h" #ifdef TFM_PSA_API #include "psa_manifest/sid.h" diff --git a/samples/tfm_integration/tfm_psa_test/CMakeLists.txt b/samples/tfm_integration/tfm_psa_test/CMakeLists.txt index 9dcbf12ae642..0d11c021627f 100644 --- a/samples/tfm_integration/tfm_psa_test/CMakeLists.txt +++ b/samples/tfm_integration/tfm_psa_test/CMakeLists.txt @@ -8,10 +8,103 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(tfm_psa_storage_test) +project(tfm_psa_arch_test) target_sources(app PRIVATE src/main.c) -target_include_directories(app PRIVATE - $/install/interface/include +get_target_property(TFM_BINARY_DIR tfm TFM_BINARY_DIR) +get_target_property(TFM_NS_BIN_FILE tfm TFM_NS_BIN_FILE) +get_target_property(TFM_NS_HEX_FILE tfm TFM_NS_HEX_FILE) +get_target_property(TFM_NS_SIGNED_BIN_FILE tfm TFM_NS_SIGNED_BIN_FILE) + +get_target_property(TFM_TOOLCHAIN_PATH tfm TFM_TOOLCHAIN_PATH) +get_target_property(TFM_TOOLCHAIN_PREFIX tfm TFM_TOOLCHAIN_PREFIX) +get_target_property(TFM_TOOLCHAIN_NS_FILE tfm TFM_TOOLCHAIN_NS_FILE) + +set(TFM_TEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../tf-m-tests) +set(TFM_PSA_ARCHTEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../psa-arch-tests) + +if (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") +# TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, +# or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has +# been manually downloaded by the user before starting the build. +message(FATAL_ERROR "CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION is not available " + "with TF-M 2.0.0 due to licensing issues with a dependent library. This " + "restriction will be removed once licensing issues have been resolved." + ) +endif() + + +set(TFM_TEST_DIR "${TFM_TEST_REPO_PATH}/tests_psa_arch/spe/partitions") +set(PSA_ARCH_TESTS_CONFIG_FILE "${TFM_TEST_REPO_PATH}/tests_psa_arch/spe/config/config_test_psa_api.cmake") +if (CONFIG_TFM_PSA_TEST_CRYPTO) +set(TFM_PSA_TEST_SUITE CRYPTO) +elseif (CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE) +set(TFM_PSA_TEST_SUITE PROTECTED_STORAGE) +elseif (CONFIG_TFM_PSA_TEST_INTERNAL_TRUSTED_STORAGE) +set(TFM_PSA_TEST_SUITE INTERNAL_TRUSTED_STORAGE) +elseif (CONFIG_TFM_PSA_TEST_STORAGE) +set(TFM_PSA_TEST_SUITE STORAGE) +elseif (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION) +set(TFM_PSA_TEST_SUITE INITIAL_ATTESTATION) +endif() + +if (NOT DEFINED TFM_PSA_TEST_SUITE) + message(FATAL_ERROR "Please define witch test suite to run: + CONFIG_TFM_PSA_TEST_CRYPTO + CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE + CONFIG_TFM_PSA_TEST_STORAGE + CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION") +endif() +set(TEST_PSA_API "${TFM_PSA_TEST_SUITE}") + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DPSA_ARCH_TESTS_PATH=${TFM_PSA_ARCHTEST_REPO_PATH} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_DIR=${TFM_TEST_DIR} ) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_PSA_ARCH_TESTS_CONFIG_FILE=${PSA_ARCH_TESTS_CONFIG_FILE} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DTEST_PSA_API=${TEST_PSA_API} +) + +include(ExternalProject) + +ExternalProject_Add(tfm_psa_arch_test_app + SOURCE_DIR ${TFM_TEST_REPO_PATH}/tests_psa_arch + BINARY_DIR ${PROJECT_BINARY_DIR}/tfm_ns + CONFIGURE_COMMAND + ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} + -S ${TFM_TEST_REPO_PATH}/tests_psa_arch + -B ${PROJECT_BINARY_DIR}/tfm_ns + -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX} + -DPSA_TOOLCHAIN_FILE=${TFM_BINARY_DIR}/api_ns/cmake/${TFM_TOOLCHAIN_NS_FILE} + -DCONFIG_SPE_PATH=${TFM_BINARY_DIR}/api_ns + -DTFM_TOOLCHAIN_FILE=cmake/${TFM_TOOLCHAIN_NS_FILE} + -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH} + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DTEST_PSA_API=${TEST_PSA_API} + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tfm_ns + DEPENDS tfm + BUILD_BYPRODUCTS + ${TFM_NS_HEX_FILE} + ${TFM_NS_BIN_FILE} + ${TFM_NS_SIGNED_BIN_FILE} +) + +add_dependencies(app tfm_psa_arch_test_app) diff --git a/samples/tfm_integration/tfm_psa_test/prj.conf b/samples/tfm_integration/tfm_psa_test/prj.conf index 3ceca5745287..bab1254229da 100644 --- a/samples/tfm_integration/tfm_psa_test/prj.conf +++ b/samples/tfm_integration/tfm_psa_test/prj.conf @@ -5,9 +5,10 @@ # CONFIG_BUILD_WITH_TFM=y -CONFIG_TFM_BUILD_NS=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y +CONFIG_TFM_USE_NS_APP=y CONFIG_QEMU_ICOUNT_SHIFT=1 + # Needed for CRYPTO and INITIAL_ATTESTATION CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/tfm_integration/tfm_psa_test/src/main.c b/samples/tfm_integration/tfm_psa_test/src/main.c index 232fc505cfdf..9d2809fe2696 100644 --- a/samples/tfm_integration/tfm_psa_test/src/main.c +++ b/samples/tfm_integration/tfm_psa_test/src/main.c @@ -1,21 +1,15 @@ /* - * Copyright (c) 2021 Nordic Semiconductor ASA. + * Copyright (c) 2023 Nordic Semiconductor ASA. * * SPDX-License-Identifier: Apache-2.0 */ #include -/* Run the PSA test suite */ -void psa_test(void); - int main(void) { -#ifdef CONFIG_TFM_PSA_TEST_NONE - #error "No PSA test suite set. Use Kconfig to enable a test suite.\n" -#else - psa_test(); -#endif + printk("Should not be printed, expected TF-M's NS application to be run instead.\n"); + k_panic(); for (;;) { } diff --git a/samples/tfm_integration/tfm_regression_test/CMakeLists.txt b/samples/tfm_integration/tfm_regression_test/CMakeLists.txt index 5f34b1c0b26e..b86eebc4a81e 100644 --- a/samples/tfm_integration/tfm_regression_test/CMakeLists.txt +++ b/samples/tfm_integration/tfm_regression_test/CMakeLists.txt @@ -11,3 +11,56 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(tfm_regression_test) target_sources(app PRIVATE src/main.c) + +get_target_property(TFM_BINARY_DIR tfm TFM_BINARY_DIR) +get_target_property(TFM_NS_BIN_FILE tfm TFM_NS_BIN_FILE) +get_target_property(TFM_NS_HEX_FILE tfm TFM_NS_HEX_FILE) +get_target_property(TFM_NS_SIGNED_BIN_FILE tfm TFM_NS_SIGNED_BIN_FILE) + +get_target_property(TFM_TOOLCHAIN_PATH tfm TFM_TOOLCHAIN_PATH) +get_target_property(TFM_TOOLCHAIN_PREFIX tfm TFM_TOOLCHAIN_PREFIX) +get_target_property(TFM_TOOLCHAIN_NS_FILE tfm TFM_TOOLCHAIN_NS_FILE) + +set(TFM_TEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../tf-m-tests) + +set(TFM_TEST_DIR "${TFM_TEST_REPO_PATH}/tests_reg/test/secure_regression") +set(TFM_TEST_CONFIG_FILE "${TFM_TEST_REPO_PATH}/tests_reg/test/config/config.cmake") + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_DIR=${TFM_TEST_DIR} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_CONFIG_FILE=${TFM_TEST_CONFIG_FILE} +) + +include(ExternalProject) + +ExternalProject_Add(tfm_regression_test_app + SOURCE_DIR ${TFM_TEST_REPO_PATH}/tests_reg + BINARY_DIR ${PROJECT_BINARY_DIR}/tfm_ns + CONFIGURE_COMMAND + ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} + -S ${TFM_TEST_REPO_PATH}/tests_reg + -B ${PROJECT_BINARY_DIR}/tfm_ns + -DCONFIG_SPE_PATH=${TFM_BINARY_DIR}/api_ns + -DTFM_TOOLCHAIN_FILE=cmake/${TFM_TOOLCHAIN_NS_FILE} + -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX} + -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH} + -DCMAKE_BUILD_TYPE=RelWithDebInfo + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tfm_ns + DEPENDS tfm + BUILD_BYPRODUCTS + ${TFM_NS_HEX_FILE} + ${TFM_NS_BIN_FILE} + ${TFM_NS_SIGNED_BIN_FILE} +) + +add_dependencies(app tfm_regression_test_app) diff --git a/samples/tfm_integration/tfm_regression_test/prj.conf b/samples/tfm_integration/tfm_regression_test/prj.conf index 6817a7f717b2..0a6573f811c7 100644 --- a/samples/tfm_integration/tfm_regression_test/prj.conf +++ b/samples/tfm_integration/tfm_regression_test/prj.conf @@ -6,7 +6,6 @@ CONFIG_BUILD_WITH_TFM=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y -CONFIG_TFM_BUILD_NS=y CONFIG_TFM_USE_NS_APP=y CONFIG_TFM_REGRESSION_S=y CONFIG_TFM_REGRESSION_NS=y diff --git a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt index 69901f73928f..beadae9230ab 100644 --- a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt +++ b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt @@ -28,7 +28,7 @@ target_sources(app PRIVATE ) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) target_compile_definitions(app diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt b/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt index 0e335a73028e..013332ccb1a0 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt @@ -50,7 +50,7 @@ target_link_libraries(tfm_partitions tfm_app_rot_partition_dp ) -target_compile_definitions(tfm_partition_defs +target_compile_definitions(tfm_config INTERFACE TFM_PARTITION_DUMMY_PARTITION ) diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c index 6519723058c4..d618868ddbfd 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c @@ -7,7 +7,6 @@ #include #include #include -#include "tfm_api.h" #include "psa/service.h" #include "psa_manifest/tfm_dummy_partition.h" diff --git a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h index b31ce897d275..7ca52b3c5c4c 100644 --- a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h +++ b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "tfm_api.h" - psa_status_t dp_secret_digest(uint32_t secret_index, void *p_digest, size_t digest_size); diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 0a2da6bc9cab..d8b147f8ab00 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -314,6 +314,13 @@ def get_modules(self, modules_file): modules = [name for name in os.listdir(modules_dir) if os.path.exists(os.path.join(modules_dir, name, 'Kconfig'))] + nrf_modules_dir = ZEPHYR_BASE + '/../nrf/modules' + nrf_modules = [] + if os.path.exists(nrf_modules_dir): + nrf_modules = [name for name in os.listdir(nrf_modules_dir) if + os.path.exists(os.path.join(nrf_modules_dir, name, + 'Kconfig'))] + with open(modules_file, 'r') as fp_module_file: content = fp_module_file.read() @@ -323,6 +330,15 @@ def get_modules(self, modules_file): re.sub('[^a-zA-Z0-9]', '_', module).upper(), modules_dir + '/' + module + '/Kconfig' )) + for module in nrf_modules: + fp_module_file.write("ZEPHYR_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + nrf_modules_dir + '/' + module + '/Kconfig' + )) + fp_module_file.write("NCS_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + modules_dir + '/' + module + '/Kconfig' + )) fp_module_file.write(content) def get_kconfig_dts(self, kconfig_dts_file): diff --git a/scripts/gitlint/zephyr_commit_rules.py b/scripts/gitlint/zephyr_commit_rules.py index ea31c6737f39..d39c7997e26b 100644 --- a/scripts/gitlint/zephyr_commit_rules.py +++ b/scripts/gitlint/zephyr_commit_rules.py @@ -78,7 +78,7 @@ class TitleMaxLengthRevert(LineRule): name = "title-max-length-no-revert" id = "UC5" target = CommitMessageTitle - options_spec = [IntOption('line-length', 75, "Max line length")] + options_spec = [IntOption('line-length', 120, "Max line length")] violation_message = "Commit title exceeds max length ({0}>{1})" def validate(self, line, _commit): @@ -103,7 +103,7 @@ class MaxLineLengthExceptions(LineRule): name = "max-line-length-with-exceptions" id = "UC4" target = CommitMessageBody - options_spec = [IntOption('line-length', 75, "Max line length")] + options_spec = [IntOption('line-length', 120, "Max line length")] violation_message = "Commit message body line exceeds max length ({0}>{1})" def validate(self, line, _commit): diff --git a/scripts/kconfig/hardened.csv b/scripts/kconfig/hardened.csv index ee95b54b3a74..6cc978f7e563 100644 --- a/scripts/kconfig/hardened.csv +++ b/scripts/kconfig/hardened.csv @@ -39,6 +39,7 @@ TEST_RANDOM_GENERATOR,n TEST_SHELL,n TEST_USERSPACE,n TFM_CMAKE_BUILD_TYPE_DEBUG,n +TFM_DUMMY_PROVISIONING,n THREAD_MONITOR,n THREAD_NAME,n TIMER_RANDOM_GENERATOR,n diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 621ec3cb3a8b..754a312ebb7f 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -309,6 +309,48 @@ def dt_chosen_reg(kconf, name, chosen, index=0, unit=None): return hex(_dt_chosen_reg_addr(kconf, chosen, index, unit)) +def _dt_chosen_partition_addr(kconf, chosen, index=0, unit=None): + """ + This function takes a 'chosen' property and treats that property as a path + to an EDT node. If it finds an EDT node, it will look to see if that + node has a register, and if that node has a grandparent that has a register + at the given 'index'. The addition of both addresses will be returned, if + not, we return 0. + + The function will divide the value based on 'unit': + None No division + 'k' or 'K' divide by 1024 (1 << 10) + 'm' or 'M' divide by 1,048,576 (1 << 20) + 'g' or 'G' divide by 1,073,741,824 (1 << 30) + 'kb' or 'Kb' divide by 8192 (1 << 13) + 'mb' or 'Mb' divide by 8,388,608 (1 << 23) + 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33) + """ + if doc_mode or edt is None: + return 0 + + node = edt.chosen_node(chosen) + if not node: + return 0 + + p_node = node.parent + if not p_node: + return 0 + + return _node_reg_addr(p_node.parent, index, unit) + _node_reg_addr(node, 0, unit) + + +def dt_chosen_partition_addr(kconf, name, chosen, index=0, unit=None): + """ + This function just routes to the proper function and converts + the result to either a string int or string hex value. + """ + if name == "dt_chosen_partition_addr_int": + return str(_dt_chosen_partition_addr(kconf, chosen, index, unit)) + if name == "dt_chosen_partition_addr_hex": + return hex(_dt_chosen_partition_addr(kconf, chosen, index, unit)) + + def _dt_node_reg_addr(kconf, path, index=0, unit=None): """ This function takes a 'path' and looks for an EDT node at that path. If it @@ -806,5 +848,7 @@ def shields_list_contains(kconf, _, shield): "dt_node_parent": (dt_node_parent, 1, 1), "dt_nodelabel_array_prop_has_val": (dt_nodelabel_array_prop_has_val, 3, 3), "dt_gpio_hogs_enabled": (dt_gpio_hogs_enabled, 0, 0), + "dt_chosen_partition_addr_int": (dt_chosen_partition_addr, 1, 3), + "dt_chosen_partition_addr_hex": (dt_chosen_partition_addr, 1, 3), "shields_list_contains": (shields_list_contains, 1, 1), } diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 86965f1f9cfb..16e19c85fec3 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -216,6 +216,12 @@ def add_parse_arguments(parser = None): and 'fifo_loop' is a name of a function found in main.c without test prefix. """) + parser.add_argument( + "--pytest-args", action="append", + help="""Pass additional arguments to the pytest subprocess. This parameter + will override the pytest_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 diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 5e90b7c84c6f..a0ea7c59a8eb 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -13,7 +13,6 @@ import scl import logging from pathlib import Path -from natsort import natsorted from twisterlib.environment import ZEPHYR_BASE @@ -322,7 +321,7 @@ def readlink(link): def save(self, hwm_file): # use existing map - self.detected = natsorted(self.detected, key=lambda x: x.serial or '') + self.detected.sort(key=lambda x: x.serial or '') if os.path.exists(hwm_file): with open(hwm_file, 'r') as yaml_file: hwm = yaml.load(yaml_file, Loader=SafeLoader) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 052def7162a8..8b8ad92fc51f 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -309,8 +309,9 @@ def pytest_run(self, timeout): def generate_command(self): config = self.instance.testsuite.harness_config + handler: Handler = self.instance.handler pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest'] - pytest_args = config.get('pytest_args', []) if config else [] + pytest_args_yaml = config.get('pytest_args', []) if config else [] pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None command = [ 'pytest', @@ -324,12 +325,10 @@ def generate_command(self): ] command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) - command.extend(pytest_args) + if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') - handler: Handler = self.instance.handler - if handler.options.verbose > 1: command.extend([ '--log-cli-level=DEBUG', @@ -346,6 +345,16 @@ def generate_command(self): command.append('--device-type=custom') else: raise PytestHarnessException(f'Handling of handler {handler.type_str} not implemented yet') + + if handler.options.pytest_args: + command.extend(handler.options.pytest_args) + if pytest_args_yaml: + logger.warning(f'The pytest_args ({handler.options.pytest_args}) specified ' + 'in the command line will override the pytest_args defined ' + f'in the YAML file {pytest_args_yaml}') + else: + command.extend(pytest_args_yaml) + return command def _generate_parameters_for_hardware(self, handler: Handler): @@ -489,6 +498,9 @@ def _parse_report_file(self, report): tc.status = 'error' tc.reason = elem.get('message') tc.output = elem.text + else: + self.state = 'skipped' + self.instance.reason = 'No tests collected' class Gtest(Harness): diff --git a/scripts/quarantine.yaml b/scripts/quarantine.yaml new file mode 100644 index 000000000000..20c4f9248ea9 --- /dev/null +++ b/scripts/quarantine.yaml @@ -0,0 +1,88 @@ +# The configurations resulting as a product of scenarios and platforms +# will be skipped if quarantine is used. More details here: +# https://docs.zephyrproject.org/latest/guides/test/twister.html#quarantine + +- scenarios: + - testing.ztest.busy_sim + - testing.ztest.busy_sim_nrf52840dk_pin + platforms: + - nrf52840dk_nrf52840 + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.unary_f64 + platforms: + - nrf5340dk_nrf5340_cpunet + - qemu_cortex_m3 + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_f16 + - libraries.cmsis_dsp.matrix.binary_f16.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_q15 + - libraries.cmsis_dsp.matrix.binary_q15.fpu + - libraries.cmsis_dsp.matrix.unary_f32 + - libraries.cmsis_dsp.matrix.unary_f32.fpu + - libraries.cmsis_dsp.matrix.unary_f64 + - libraries.cmsis_dsp.matrix.unary_f64.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Flash overflows" + +# libsdl2-dev package should be added into docker image +- scenarios: + - sample.boards.nrf.nrf_led_matrix + - sample.display.lvgl.gui + platforms: + - native_posix + comment: "libsdl2-dev package not available" + +- scenarios: + - sample.net.sockets.echo_server.usbnet + - sample.net.sockets.echo_server.usbnet_composite + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - sample.net.zperf.netusb_ecm + - sample.net.zperf.netusb_eem + - sample.net.zperf.netusb_rndis + platforms: + - nrf52833dk_nrf52833 + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - net.mqtt.tls + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - kernel.common.picolibc + - libraries.picolibc + - libraries.libc.picolibc.mem_alloc + - libraries.picolibc.sprintf_new + platforms: + - nrf52dk_nrf52832 + comment: "Ram overflows, also in the upstream" + +- scenarios: + - sample.psa_crypto + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Due to using sdk-zephyr manifest instead of nrf. Should be fixed after the change" diff --git a/scripts/requirements-run-test.txt b/scripts/requirements-run-test.txt index 836921281102..3bb0b21c44e8 100644 --- a/scripts/requirements-run-test.txt +++ b/scripts/requirements-run-test.txt @@ -7,7 +7,6 @@ pyocd>=0.35.0 # used by twister for board/hardware map tabulate -natsort # used by mcuboot cbor>=1.0.0 diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index 150980059b3d..befd384be37b 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -25,6 +25,7 @@ def testinstance() -> TestInstance: testinstance.handler = mock.Mock() testinstance.handler.options = mock.Mock() testinstance.handler.options.verbose = 1 + testinstance.handler.options.pytest_args = None testinstance.handler.type_str = 'native' return testinstance @@ -67,6 +68,19 @@ def test_pytest_command_extra_args(testinstance: TestInstance): assert c in command +def test_pytest_command_extra_args_in_options(testinstance: TestInstance): + pytest_harness = Pytest() + pytest_args_from_yaml = '-k test_from_yaml' + pytest_args_from_cmd = ['-k', 'test_from_cmd'] + testinstance.testsuite.harness_config['pytest_args'] = [pytest_args_from_yaml] + testinstance.handler.options.pytest_args = pytest_args_from_cmd + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + assert pytest_args_from_cmd[0] in command + assert pytest_args_from_cmd[1] in command + assert pytest_args_from_yaml not in command + + @pytest.mark.parametrize( ('pytest_root', 'expected'), [ @@ -222,3 +236,56 @@ def test_skip_2(): assert len(testinstance.testcases) == 2 for tc in testinstance.testcases: assert tc.status == "skipped" + + +def test_if_report_with_filter(pytester, testinstance: TestInstance): + test_file_content = textwrap.dedent(""" + import pytest + def test_A(): + pass + def test_B(): + pass + """) + test_file = pytester.path / 'test_filter.py' + test_file.write_text(test_file_content) + report_file = pytester.path / 'report.xml' + result = pytester.runpytest( + str(test_file), + '-k', 'test_B', + f'--junit-xml={str(report_file)}' + ) + result.assert_outcomes(passed=1) + assert report_file.is_file() + + pytest_harness = Pytest() + pytest_harness.configure(testinstance) + pytest_harness.report_file = report_file + pytest_harness._update_test_status() + assert pytest_harness.state == "passed" + assert testinstance.status == "passed" + assert len(testinstance.testcases) == 1 + + +def test_if_report_with_no_collected(pytester, testinstance: TestInstance): + test_file_content = textwrap.dedent(""" + import pytest + def test_A(): + pass + """) + test_file = pytester.path / 'test_filter.py' + test_file.write_text(test_file_content) + report_file = pytester.path / 'report.xml' + result = pytester.runpytest( + str(test_file), + '-k', 'test_B', + f'--junit-xml={str(report_file)}' + ) + result.assert_outcomes(passed=0) + assert report_file.is_file() + + pytest_harness = Pytest() + pytest_harness.configure(testinstance) + pytest_harness.report_file = report_file + pytest_harness._update_test_status() + assert pytest_harness.state == "skipped" + assert testinstance.status == "skipped" diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 2ff51d7e85d1..76662c72ea91 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -24,11 +24,26 @@ ErrNotAvailableBecauseProtection = 24 ErrVerify = 25 +UICR_RANGES = { + 'NRF53_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), + 'NRFDL_DEVICE_CORE_NETWORK': (0x01FF8000, 0x01FF8800), + }, + 'NRF54H_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x0FFF8000, 0x0FFF8800), + 'NRFDL_DEVICE_CORE_NETWORK': (0x0FFFA000, 0x0FFFA800), + }, + 'NRF91_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), + } +} + class NrfBinaryRunner(ZephyrBinaryRunner): '''Runner front-end base class for nrf tools.''' def __init__(self, cfg, family, softreset, dev_id, erase=False, - reset=True, tool_opt=[], force=False, recover=False): + reset=True, tool_opt=[], force=False, recover=False, + erase_all_uicrs=False): super().__init__(cfg) self.hex_ = cfg.hex_file if family and not family.endswith('_FAMILY'): @@ -40,6 +55,7 @@ def __init__(self, cfg, family, softreset, dev_id, erase=False, self.reset = bool(reset) self.force = force self.recover = bool(recover) + self.erase_all_uicrs = bool(erase_all_uicrs) self.tool_opt = [] for opts in [shlex.split(opt) for opt in tool_opt]: @@ -59,7 +75,8 @@ def dev_id_help(cls) -> str: @classmethod def do_add_parser(cls, parser): parser.add_argument('--nrf-family', - choices=['NRF51', 'NRF52', 'NRF53', 'NRF91'], + choices=['NRF51', 'NRF52', 'NRF53', 'NRF54L', + 'NRF54H', 'NRF91'], help='''MCU family; still accepted for compatibility only''') parser.add_argument('--softreset', required=False, @@ -75,6 +92,11 @@ def do_add_parser(cls, parser): help='''erase all user available non-volatile memory and disable read back protection before flashing (erases flash for both cores on nRF53)''') + parser.add_argument('--erase-all-uicrs', required=False, + action='store_true', + help='''Erase all UICR registers before flashing + (nRF54H only). When not set, only UICR registers + present in the hex file will be erased.''') parser.set_defaults(reset=True) @@ -161,6 +183,10 @@ def ensure_family(self): self.family = 'NRF52_FAMILY' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'): self.family = 'NRF53_FAMILY' + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54LX'): + self.family = 'NRF54L_FAMILY' + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54HX'): + self.family = 'NRF54H_FAMILY' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'): self.family = 'NRF91_FAMILY' else: @@ -172,21 +198,15 @@ def hex_refers_region(self, region_start, region_end): return True return False - def hex_has_uicr_content(self): - # A map from SoCs which need this check to their UICR address - # ranges. If self.family isn't in here, do nothing. - uicr_ranges = { - 'NRF53': ((0x00FF8000, 0x00FF8800), - (0x01FF8000, 0x01FF8800)), - 'NRF91': ((0x00FF8000, 0x00FF8800),), - } + def hex_get_uicrs(self): + hex_uicrs = {} - if self.family not in uicr_ranges: - return + if self.family in UICR_RANGES: + for uicr_core, uicr_range in UICR_RANGES[self.family].items(): + if self.hex_refers_region(*uicr_range): + hex_uicrs[uicr_core] = uicr_range - for region_start, region_end in uicr_ranges[self.family]: - if self.hex_refers_region(region_start, region_end): - return True + return hex_uicrs def flush(self, force=False): try: @@ -211,7 +231,7 @@ def flush(self, force=False): # If there are data in the UICR region it is likely that the # verify failed du to the UICR not been erased before, so giving # a warning here will hopefully enhance UX. - if self.hex_has_uicr_content(): + if self.hex_get_uicrs(): self.logger.warning( 'The hex file contains data placed in the UICR, which ' 'may require a full erase before reprogramming. Run ' @@ -264,11 +284,24 @@ def program_hex(self): if self.family == 'NRF53_FAMILY': # nRF53 requires special treatment due to the extra coprocessor. self.program_hex_nrf53(erase_arg, qspi_erase_opt) + elif self.family == 'NRF54H_FAMILY': + self.program_hex_nrf54h() else: self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True) self.flush(force=False) + def program_hex_nrf54h(self): + if self.erase_all_uicrs: + uicrs = UICR_RANGES['NRF54H_FAMILY'] + else: + uicrs = self.hex_get_uicrs() + + for uicr_core, range in uicrs.items(): + self.exec_op('erasepage', defer=True, core=uicr_core, page=range[0]) + + self.op_program(self.hex_, 'NO_ERASE', None, defer=True) + def program_hex_nrf53(self, erase_arg, qspi_erase_opt): # program_hex() helper for nRF53. diff --git a/scripts/west_commands/runners/nrfjprog.py b/scripts/west_commands/runners/nrfjprog.py index 8762ce0e7405..723080d56c3e 100644 --- a/scripts/west_commands/runners/nrfjprog.py +++ b/scripts/west_commands/runners/nrfjprog.py @@ -32,7 +32,8 @@ def do_create(cls, cfg, args): args.dev_id, erase=args.erase, reset=args.reset, tool_opt=args.tool_opt, force=args.force, - recover=args.recover) + recover=args.recover, + erase_all_uicrs=args.erase_all_uicrs) def do_get_boards(self): snrs = self.check_output(['nrfjprog', '--ids']) @@ -46,7 +47,8 @@ def do_exec_op(self, op, force=False): # Translate the op families = {'NRF51_FAMILY': 'NRF51', 'NRF52_FAMILY': 'NRF52', - 'NRF53_FAMILY': 'NRF53', 'NRF91_FAMILY': 'NRF91'} + 'NRF53_FAMILY': 'NRF53', 'NRF54L_FAMILY': 'NRF54L', + 'NRF54H_FAMILY': 'NRF54H', 'NRF91_FAMILY': 'NRF91'} cores = {'NRFDL_DEVICE_CORE_APPLICATION': 'CP_APPLICATION', 'NRFDL_DEVICE_CORE_NETWORK': 'CP_NETWORK'} @@ -69,6 +71,8 @@ def do_exec_op(self, op, force=False): cmd.append('--sectorerase') elif erase == 'ERASE_PAGES_INCLUDING_UICR': cmd.append('--sectoranduicrerase') + elif erase == 'NO_ERASE': + pass else: raise RuntimeError(f'Invalid erase mode: {erase}') @@ -85,6 +89,9 @@ def do_exec_op(self, op, force=False): cmd.append('--reset') if _op['option'] == 'RESET_PIN': cmd.append('--pinreset') + elif op_type == 'erasepage': + cmd.append('--erasepage') + cmd.append(f"0x{_op['page']:08x}") else: raise RuntimeError(f'Invalid operation: {op_type}') diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index 7bbfe1387601..8a15da9cef58 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023 Nordic Semiconductor +# Copyright (c) 2023 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 @@ -18,7 +18,10 @@ set(APP_DIR ${APP_DIR} CACHE PATH "Main Application Source Directory") list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) # List of Zephyr and sysbuild CMake modules we need for sysbuild. # Note: sysbuild_kconfig will internally load kconfig CMake module. -set(zephyr_modules extensions sysbuild_extensions python west root zephyr_module boards shields sysbuild_kconfig) +set(zephyr_modules extensions + sysbuild_extensions python west root zephyr_module boards shields + sysbuild_kconfig native_simulator_sb_extensions + ) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS ${zephyr_modules}) diff --git a/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake b/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake new file mode 100644 index 000000000000..3d888d1775ef --- /dev/null +++ b/share/sysbuild/cmake/modules/native_simulator_sb_extensions.cmake @@ -0,0 +1,62 @@ +# Copyright (c) 2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Usage: +# native_simulator_set_final_executable() +# +# When building for a native_simulator based target (including bsim targets), +# this function adds an extra build target which will copy the executable produced by +# `` to the top level, as zephyr/zephyr.exe +# +# This final image is expected to have been set to assemble other dependent images into +# itself if necessary, by calling native_simulator_set_child_images() +# This will allow other tools, like twister, or the bsim test scripts, as well as users to find +# this final executable in the same place as for non-sysbuild builds. +# +function(native_simulator_set_final_executable final_image) + if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + add_custom_target(final_executable + ALL + COMMAND + ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/${final_image}/zephyr/zephyr.exe + ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe + DEPENDS ${final_image} + ) + endif() +endfunction() + +# Usage: +# native_simulator_set_child_images( ) +# +# When building for a native_simulator based target (including bsim targets), +# this function sets a `` as dependencies of `` +# and configures the final image to assemble the child images into its final executable. +# +function(native_simulator_set_child_images final_image child_image) + if(("${BOARD}" MATCHES "native") OR ("${BOARD}" MATCHES "bsim")) + add_dependencies(${final_image} ${child_image}) + + set(CHILD_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${child_image}/zephyr/zephyr.elf) + set_property(TARGET ${final_image} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${CHILD_LIBRARY_PATH}\"\n" + ) + endif() +endfunction() + +# Usage: +# native_simulator_set_primary_mcu_index( [ ...]) +# +# Propagate the SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX setting, +# if it is set, to each given image CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX +# +function(native_simulator_set_primary_mcu_index) + if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) + foreach(arg IN LISTS ARGV) + set_property(TARGET ${arg} APPEND_STRING PROPERTY CONFIG + "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" + ) + endforeach() + endif() +endfunction() diff --git a/snippets/nordic-ppr/README.rst b/snippets/nordic-ppr/README.rst new file mode 100644 index 000000000000..36eb74d193f2 --- /dev/null +++ b/snippets/nordic-ppr/README.rst @@ -0,0 +1,10 @@ +.. _nordic-ppr: + +Nordic PPR snippet (nordic-ppr) +############################### + +Overview +******** + +This snippet allows users to build Zephyr with the capability to boot Nordic PPR +(Peripheral Processor) from another core. diff --git a/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay b/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..75128f42a13f --- /dev/null +++ b/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuppr_ram3x_region { + status = "okay"; +}; + +&uart135 { + status = "reserved"; +}; diff --git a/snippets/nordic-ppr/nordic-ppr.overlay b/snippets/nordic-ppr/nordic-ppr.overlay new file mode 100644 index 000000000000..e33885fc10dd --- /dev/null +++ b/snippets/nordic-ppr/nordic-ppr.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuppr_vpr { + status = "okay"; +}; diff --git a/snippets/nordic-ppr/snippet.yml b/snippets/nordic-ppr/snippet.yml new file mode 100644 index 000000000000..9e1f20bb7570 --- /dev/null +++ b/snippets/nordic-ppr/snippet.yml @@ -0,0 +1,8 @@ +name: nordic-ppr +append: + EXTRA_DTC_OVERLAY_FILE: nordic-ppr.overlay + +boards: + nrf54h20pdk_nrf54h20_cpuapp: + append: + EXTRA_DTC_OVERLAY_FILE: boards/nrf54h20pdk_nrf54h20_cpuapp.overlay diff --git a/soc/CMakeLists.txt b/soc/CMakeLists.txt index 6706168281eb..d55bd63f496d 100644 --- a/soc/CMakeLists.txt +++ b/soc/CMakeLists.txt @@ -9,6 +9,8 @@ if(_SOC_IS_IN_TREE) endif() unset(_SOC_IS_IN_TREE) +add_subdirectory(common) + if(EXISTS ${SOC_DIR}/${ARCH}/CMakeLists.txt) add_subdirectory(${SOC_DIR}/${ARCH} soc/${ARCH}) else() diff --git a/soc/arm/ambiq/apollo4x/Kconfig.series b/soc/arm/ambiq/apollo4x/Kconfig.series index b7982d3609e0..a9e725672064 100644 --- a/soc/arm/ambiq/apollo4x/Kconfig.series +++ b/soc/arm/ambiq/apollo4x/Kconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES_APOLLO4X select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_FPU + select CPU_HAS_ARM_MPU select SOC_FAMILY_AMBIQ select HAS_SWO select AMBIQ_HAL diff --git a/soc/arm/arm/designstart/soc.h b/soc/arm/arm/designstart/soc.h index ec58467f923c..a9bcdb4e9cd1 100644 --- a/soc/arm/arm/designstart/soc.h +++ b/soc/arm/arm/designstart/soc.h @@ -7,7 +7,6 @@ #ifndef _SOC_H_ #define _SOC_H_ - -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include #endif /* _SOC_H_ */ diff --git a/soc/arm/arm/mps2/soc.h b/soc/arm/arm/mps2/soc.h index 594d3d084c1f..822c7ee01bd2 100644 --- a/soc/arm/arm/mps2/soc.h +++ b/soc/arm/arm/mps2/soc.h @@ -7,15 +7,7 @@ #ifndef _SOC_H_ #define _SOC_H_ -#define __MPU_PRESENT 1 - -#if defined(CONFIG_SOC_MPS2_AN521) -#define __SAUREGION_PRESENT CONFIG_CPU_HAS_ARM_SAU -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __DSP_PRESENT CONFIG_ARMV8_M_DSP - -#endif - +#include #include extern void wakeup_cpu1(void); diff --git a/soc/arm/arm/mps3/Kconfig.soc b/soc/arm/arm/mps3/Kconfig.soc index 86970e288cc8..ae577fa549b1 100644 --- a/soc/arm/arm/mps3/Kconfig.soc +++ b/soc/arm/arm/mps3/Kconfig.soc @@ -14,5 +14,10 @@ config SOC_MPS3_AN547 select ARMV8_M_DSP select ARMV8_1_M_MVEI select ARMV8_1_M_MVEF + select ARMV8_1_M_PMU endchoice + +config ARMV8_1_M_PMU_EVENTCNT + int + default 8 if SOC_MPS3_AN547 diff --git a/soc/arm/arm/mps3/soc.h b/soc/arm/arm/mps3/soc.h index 6a325074cf2d..c3a59da1c0dc 100644 --- a/soc/arm/arm/mps3/soc.h +++ b/soc/arm/arm/mps3/soc.h @@ -7,19 +7,6 @@ #ifndef _SOC_H_ #define _SOC_H_ -#define __MPU_PRESENT 1 - -#if defined(CONFIG_SOC_MPS3_AN547) -#define __SAUREGION_PRESENT 1U /* SAU regions present */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __DSP_PRESENT 1U /* DSP extension present */ -#define __MVE_PRESENT 1U /* MVE extensions present */ -#define __MVE_FP 1U /* MVE floating point present */ -#define __ICACHE_PRESENT 1U /* ICACHE present */ -#define __DCACHE_PRESENT 1U /* DCACHE present */ -#define __PMU_PRESENT 1U /* PMU present */ -#define __PMU_NUM_EVENTCNT 8U /* PMU Event Counters */ -#endif - +#include #endif /* _SOC_H_ */ diff --git a/soc/arm/arm/musca_s1/Kconfig.soc b/soc/arm/arm/musca_s1/Kconfig.soc index 9bf02614308b..0c0763fae2a0 100644 --- a/soc/arm/arm/musca_s1/Kconfig.soc +++ b/soc/arm/arm/musca_s1/Kconfig.soc @@ -11,5 +11,7 @@ config SOC_V2M_MUSCA_S1 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_FPU + select ARMV8_M_DSP endchoice diff --git a/soc/arm/aspeed/ast10x0/soc.h b/soc/arm/aspeed/ast10x0/soc.h index f45df84c1283..be1cced5da28 100644 --- a/soc/arm/aspeed/ast10x0/soc.h +++ b/soc/arm/aspeed/ast10x0/soc.h @@ -25,4 +25,6 @@ void aspeed_print_sysrst_info(void); +#include + #endif /* ZEPHYR_SOC_ARM_ASPEED_AST10X0_SOC_H_*/ diff --git a/soc/arm/atmel_sam0/samc21/Kconfig.series b/soc/arm/atmel_sam0/samc21/Kconfig.series index 044a7aea229d..acb83679e18e 100644 --- a/soc/arm/atmel_sam0/samc21/Kconfig.series +++ b/soc/arm/atmel_sam0/samc21/Kconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES_SAMC21 select CPU_CORTEX_M0PLUS select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU select SOC_FAMILY_SAM0 select PLATFORM_SPECIFIC_INIT select ASF diff --git a/soc/arm/bcm_vk/valkyrie/soc.h b/soc/arm/bcm_vk/valkyrie/soc.h index 26863fbfea0f..c3e21a895815 100644 --- a/soc/arm/bcm_vk/valkyrie/soc.h +++ b/soc/arm/bcm_vk/valkyrie/soc.h @@ -292,4 +292,6 @@ typedef enum IRQn { #define PCIE0_PERST_FE_INTR BIT(1) #define PCIE0_PERST_INB_FE_INTR BIT(3) +#include + #endif diff --git a/soc/arm/bcm_vk/viper/soc.h b/soc/arm/bcm_vk/viper/soc.h index 6695e92ef5cc..06bf59fb24dd 100644 --- a/soc/arm/bcm_vk/viper/soc.h +++ b/soc/arm/bcm_vk/viper/soc.h @@ -9,10 +9,10 @@ #include #include +#include #ifndef _ASMLANGUAGE - /* Interrupt Number Definition */ typedef enum IRQn { /* CORTEX-M7 Processor Exceptions Numbers */ @@ -301,4 +301,6 @@ typedef enum IRQn { #define LS_ICFG_PMON_LITE_SW_RESETN 0x482f0120 #define PCIE_PMON_LITE_SW_RESETN BIT(0) +#include + #endif diff --git a/soc/arm/cypress/Kconfig b/soc/arm/cypress/Kconfig index 352c66b4e761..cb76ccb10902 100644 --- a/soc/arm/cypress/Kconfig +++ b/soc/arm/cypress/Kconfig @@ -12,12 +12,15 @@ config SOC_PSOC6_M0 select CPU_CORTEX_M0PLUS select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU config SOC_PSOC6_M4 bool "SOC_PSOC6_M4" select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_CORTEX_M_HAS_SYSTICK + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU endchoice diff --git a/soc/arm/gigadevice/gd32a50x/Kconfig.series b/soc/arm/gigadevice/gd32a50x/Kconfig.series index 96fc8c1d0af7..2488c643727d 100644 --- a/soc/arm/gigadevice/gd32a50x/Kconfig.series +++ b/soc/arm/gigadevice/gd32a50x/Kconfig.series @@ -6,6 +6,7 @@ config SOC_SERIES_GD32A50X select ARM select CPU_HAS_ARM_MPU select CPU_HAS_FPU + select ARMV8_M_DSP select CPU_CORTEX_M33 select SOC_FAMILY_GD32_ARM select GD32_HAS_AF_PINMUX diff --git a/soc/arm/gigadevice/gd32e50x/Kconfig.series b/soc/arm/gigadevice/gd32e50x/Kconfig.series index 8bc3f71118ec..546ca4567934 100644 --- a/soc/arm/gigadevice/gd32e50x/Kconfig.series +++ b/soc/arm/gigadevice/gd32e50x/Kconfig.series @@ -7,6 +7,7 @@ config SOC_SERIES_GD32E50X select CPU_HAS_ARM_MPU select CPU_HAS_FPU select CPU_CORTEX_M33 + select ARMV8_M_DSP select SOC_FAMILY_GD32_ARM select GD32_HAS_AFIO_PINMUX select GD32_HAS_IRC_40K diff --git a/soc/arm/gigadevice/gd32l23x/Kconfig.series b/soc/arm/gigadevice/gd32l23x/Kconfig.series index 5bdb0dba7d3a..d6125ca4152f 100644 --- a/soc/arm/gigadevice/gd32l23x/Kconfig.series +++ b/soc/arm/gigadevice/gd32l23x/Kconfig.series @@ -6,6 +6,7 @@ config SOC_SERIES_GD32L23X select ARM select CPU_CORTEX_M23 select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select SOC_FAMILY_GD32_ARM select GD32_HAS_AF_PINMUX select GD32_HAS_IRC_32K diff --git a/soc/arm/microchip_mec/mec1501/Kconfig.series b/soc/arm/microchip_mec/mec1501/Kconfig.series index d3b679bb557d..92dc6f3f8f9f 100644 --- a/soc/arm/microchip_mec/mec1501/Kconfig.series +++ b/soc/arm/microchip_mec/mec1501/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_MEC1501X select ARM select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU select SOC_FAMILY_MEC select HAS_PM help diff --git a/soc/arm/microchip_mec/mec172x/soc.h b/soc/arm/microchip_mec/mec172x/soc.h index 3bf4f533fdb7..19afc4e920a9 100644 --- a/soc/arm/microchip_mec/mec172x/soc.h +++ b/soc/arm/microchip_mec/mec172x/soc.h @@ -242,6 +242,8 @@ typedef enum { MAX_IRQn } IRQn_Type; +#include + #include /* chip specific register defines */ diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 47364b35ffb2..bd7725404b8c 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -1,9 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_library() + add_subdirectory(${SOC_SERIES}) add_subdirectory(common) -zephyr_sources( +zephyr_library_sources( validate_base_addresses.c validate_enabled_instances.c ) @@ -25,4 +27,8 @@ if(CONFIG_BUILD_WITH_TFM) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} ) + + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DNRF_NS_STORAGE=${CONFIG_TFM_NRF_NS_STORAGE} + ) endif() diff --git a/soc/arm/nordic_nrf/Kconfig b/soc/arm/nordic_nrf/Kconfig index 19e49c054540..ba0c9d4b1644 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -13,11 +13,12 @@ config SOC_FAMILY string default "nordic_nrf" -source "soc/arm/nordic_nrf/Kconfig.peripherals" +source "soc/common/nordic_nrf/Kconfig.peripherals" source "soc/arm/nordic_nrf/*/Kconfig.soc" config NRF_SOC_SECURE_SUPPORTED def_bool !TRUSTED_EXECUTION_NONSECURE || (BUILD_WITH_TFM && TFM_PARTITION_PLATFORM) + depends on !SOC_SERIES_NRF54HX help Hidden function to indicate that that the soc_secure functions are available. @@ -45,6 +46,10 @@ config TFM_LOG_LEVEL_SILENCE Disable TF-M secure output if the uart1 node has not assigned GPIO pins using pinctrl. +config TFM_NRF_NS_STORAGE + bool "TF-M non-secure storage partition" + default y + endif # BUILD_WITH_TFM diff --git a/soc/arm/nordic_nrf/Kconfig.defconfig b/soc/arm/nordic_nrf/Kconfig.defconfig index 3eedcf350c6c..ad3c97443ffa 100644 --- a/soc/arm/nordic_nrf/Kconfig.defconfig +++ b/soc/arm/nordic_nrf/Kconfig.defconfig @@ -7,22 +7,21 @@ if SOC_FAMILY_NRF source "soc/arm/nordic_nrf/*/Kconfig.defconfig.series" -# If the kernel has timer support, enable both clock control and timer +# If the kernel has timer support, enable clock control if SYS_CLOCK_EXISTS config CLOCK_CONTROL - default y - -config NRF_RTC_TIMER - default y + default y if !SOC_SERIES_NRF54HX endif # SYS_CLOCK_EXISTS config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 if NRF_GRTC_TIMER default 32768 config SYS_CLOCK_TICKS_PER_SEC default 128 if !TICKLESS_KERNEL + default 10000 if NRF_GRTC_TIMER default 32768 config ARCH_HAS_CUSTOM_BUSY_WAIT @@ -40,4 +39,7 @@ config GPIO default y depends on SPI +config UART_USE_RUNTIME_CONFIGURE + default n + endif # SOC_FAMILY_NRF diff --git a/soc/arm/nordic_nrf/common/CMakeLists.txt b/soc/arm/nordic_nrf/common/CMakeLists.txt index eb074dd05481..ea05f3d369e5 100644 --- a/soc/arm/nordic_nrf/common/CMakeLists.txt +++ b/soc/arm/nordic_nrf/common/CMakeLists.txt @@ -3,11 +3,14 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_NRF soc_nrf_common.S) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) + zephyr_include_directories(.) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + if (CONFIG_TFM_PARTITION_PLATFORM) - zephyr_sources(soc_secure.c) + zephyr_library_sources(soc_secure.c) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/soc/arm/nordic_nrf/common/soc_nrf_common.h b/soc/arm/nordic_nrf/common/soc_nrf_common.h index 4c00d7c0237c..1e5e603967b5 100644 --- a/soc/arm/nordic_nrf/common/soc_nrf_common.h +++ b/soc/arm/nordic_nrf/common/soc_nrf_common.h @@ -149,6 +149,52 @@ (NRF_DT_GPIOS_TO_PSEL(node_id, prop)), \ (default_value)) +/** + * @brief Convert a devicetree GPIO phandle+specifier to GPIOTE instance number. + * + * Some of nRF SoCs may have more instances of GPIOTE. + * To handle this, we use the "gpiote-instance" property of the GPIO node. + * + * This macro converts a devicetree GPIO phandle array value + * "<&gpioX pin ...>" to a GPIOTE instance number. + * + * Examples: + * + * &gpiote0 { + * instance = <0>; + * }; + * + * &gpiote20 { + * instance = <20>; + * }; + * + * &gpio0 { + * gpiote-instance = <&gpiote0>; + * } + * + * &gpio1 { + * gpiote-instance = <&gpiote20>; + * } + * + * foo: my-node { + * tx-gpios = <&gpio0 4 ...>; + * rx-gpios = <&gpio0 5 ...>, <&gpio1 5 ...>; + * }; + * + * NRF_DT_GPIOTE_INST_BY_IDX(DT_NODELABEL(foo), tx_gpios, 0) // = 0 + * NRF_DT_GPIOTE_INST_BY_IDX(DT_NODELABEL(foo), rx_gpios, 1) // = 20 + */ +#define NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) \ + DT_PROP(DT_PHANDLE(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx), \ + gpiote_instance), \ + instance) + +/** + * @brief Equivalent to NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0) + */ +#define NRF_DT_GPIOTE_INST(node_id, prop) \ + NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0) + /** * Error out the build if 'prop' is set on node 'node_id' and * DT_GPIO_CTLR(node_id, prop) is not an SoC GPIO controller, diff --git a/soc/arm/nordic_nrf/common/soc_secure.h b/soc/arm/nordic_nrf/common/soc_secure.h index 948f38547aa8..d38d66ab4889 100644 --- a/soc/arm/nordic_nrf/common/soc_secure.h +++ b/soc/arm/nordic_nrf/common/soc_secure.h @@ -59,7 +59,7 @@ static inline void soc_secure_gpio_pin_mcu_select(uint32_t pin_number, #if defined(CONFIG_SOC_HFXO_CAP_INTERNAL) static inline uint32_t soc_secure_read_xosc32mtrim(void) { - return NRF_FICR_S->XOSC32MTRIM; + return NRF_FICR->XOSC32MTRIM; } #endif /* defined(CONFIG_SOC_HFXO_CAP_INTERNAL) */ diff --git a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt index 44d139e422a6..35d47fb252bc 100644 --- a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt @@ -1,14 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library() - -zephyr_library_sources( - soc.c - ) - -zephyr_library_include_directories( - ${ZEPHYR_BASE}/kernel/include - ${ZEPHYR_BASE}/arch/arm/include - ) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +zephyr_library_sources(soc.c) diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series index 8c0bc74c02f5..a4053bf7fed0 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series @@ -14,4 +14,8 @@ config SOC_SERIES config NUM_IRQS default 26 +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF51X diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index 04e255a3eb12..1b7d4d5257a1 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -1,15 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library() - -zephyr_library_sources( - soc.c - ) - -zephyr_library_include_directories( - ${ZEPHYR_BASE}/kernel/include - ${ZEPHYR_BASE}/arch/arm/include - ) +zephyr_library_sources(soc.c) if(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 AND CONFIG_SPI_NRFX_SPIM) message(WARNING "Both SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 and an NRF SPIM driver are enabled, therefore PAN 58 will apply if RXD.MAXCNT == 1 and TXD.MAXCNT <= 1") @@ -22,5 +13,3 @@ if(CONFIG_SOC_NRF52832) endif() endif() endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series index 4a7edf2aa95f..2e89a5130a68 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52*" config SOC_SERIES default "nrf52" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF52X diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index 517b4ce2baa3..de6a16129d37 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -147,4 +147,12 @@ config NRF52_ANOMALY_109_WORKAROUND 64MHz clock at the same time as the peripheral that is using DMA is started. This anomaly applies to IC revisions up to "3", the most recent one. +config NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE + int "Anomaly 109 workaround EGU instance" + depends on NRF52_ANOMALY_109_WORKAROUND + range 0 5 + default 5 + help + EGU instance used by the nRF52 Anomaly 109 workaround for PWM. + endif # SOC_SERIES_NRF52X diff --git a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt index b4e82f52c288..be275df68f55 100644 --- a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt @@ -1,12 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( - soc.c - ) +zephyr_library_sources(soc.c) -zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC - sync_rtc.c - ) +zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC sync_rtc.c) if (CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED AND NOT CONFIG_SYS_CLOCK_EXISTS) @@ -19,5 +15,3 @@ if (CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED AND At your own risk, you can suppress this warning by setting CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED=n.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series index 2857d5dd25dd..7e5660cf514b 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.nrf53*" config SOC_SERIES default "nrf53" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF53X diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 3afcd96f70d0..f72ae5ab004b 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -104,12 +104,26 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral +config NRF_SPU_FLASH_REGION_ALIGNMENT + hex + default 0x4000 + help + FLASH regions must be aligned to this value due to SPU HW + limitations. + config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral +config NRF_SPU_RAM_REGION_ALIGNMENT + hex + default 0x2000 + help + RAM regions must be aligned to this value due to SPU HW + limitations. + config SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 bool depends on NRF_SOC_SECURE_SUPPORTED diff --git a/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt b/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt new file mode 100644 index 000000000000..8b4df42fa553 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources(soc.c) + +# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes +# for the image correctly +zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp new file mode 100644 index 000000000000..d90f87c0b896 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -0,0 +1,17 @@ +# Nordic Semiconductor nRF54H20 Application MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPUAPP + +config SOC + default "nrf54h20_enga_cpuapp" + +config NUM_IRQS + default 471 + +config NRF_REGTOOL_GENERATE_UICR + default y + +endif # SOC_NRF54H20_ENGA_CPUAPP diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad new file mode 100644 index 000000000000..6aae8c3a1052 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -0,0 +1,17 @@ +# Nordic Semiconductor nRF54H20 Radio MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPURAD + +config SOC + default "nrf54h20_enga_cpurad" + +config NUM_IRQS + default 471 + +config NRF_REGTOOL_GENERATE_UICR + default y + +endif # SOC_NRF54H20_ENGA_CPURAD diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series new file mode 100644 index 000000000000..ddc902d213eb --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series @@ -0,0 +1,16 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54HX + +rsource "Kconfig.defconfig.nrf54h*" + +config SOC_SERIES + default "nrf54h" + +config CACHE_NRF_CACHE + default y if EXTERNAL_CACHE + +endif # SOC_SERIES_NRF54HX diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.series b/soc/arm/nordic_nrf/nrf54h/Kconfig.series new file mode 100644 index 000000000000..0b896f477acc --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.series @@ -0,0 +1,16 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54HX + bool "Nordic Semiconductor nRF54H series MCU" + select ARM + select ARMV8_M_DSP + select CPU_CORTEX_M33 + select SOC_FAMILY_NRF + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + help + Enable support for nRF54H MCU series diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.soc b/soc/arm/nordic_nrf/nrf54h/Kconfig.soc new file mode 100644 index 000000000000..9c065e79eaf7 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.soc @@ -0,0 +1,37 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF54H20 + bool "nRF54H20" + depends on SOC_SERIES_NRF54HX + +if SOC_NRF54H20 + +choice + prompt "nRF54H20 MCU Selection" + +config SOC_NRF54H20_ENGA_CPUAPP + bool "nRF54H20 ENGA CPUAPP" + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_FPU + +config SOC_NRF54H20_ENGA_CPURAD + bool "nRF54H20 ENGA CPURAD" + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_FPU + +endchoice + +config NRF_ENABLE_ICACHE + bool "Instruction cache (I-Cache)" + default y + +endif # SOC_NRF54H20 diff --git a/soc/arm/nordic_nrf/nrf54h/align.ld b/soc/arm/nordic_nrf/nrf54h/align.ld new file mode 100644 index 000000000000..0905aa7f7bcc --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/align.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.align16,,) +{ + . = (ALIGN(16) > 0 ? ALIGN(16) : 16) - 1; + BYTE(0); +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/arm/nordic_nrf/nrf54h/soc.c b/soc/arm/nordic_nrf/nrf54h/soc.c new file mode 100644 index 000000000000..9fefd4141525 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/soc.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#if defined(NRF_APPLICATION) +#define HSFLL_NODE DT_NODELABEL(cpuapp_hsfll) +#elif defined(NRF_RADIOCORE) +#define HSFLL_NODE DT_NODELABEL(cpurad_hsfll) +#endif + +#define FICR_ADDR_GET(node_id, name) \ + DT_REG_ADDR(DT_PHANDLE_BY_NAME(node_id, nordic_ficrs, name)) + \ + DT_PHA_BY_NAME(node_id, nordic_ficrs, name, offset) + +static void power_domain_init(void) +{ + /* + * Set: + * - LRCCONF010.POWERON.MAIN: 1 + * - LRCCONF010.POWERON.ACT: 1 + * - LRCCONF010.RETAIN.MAIN: 1 + * - LRCCONF010.RETAIN.ACT: 1 + * + * This is done here at boot so that when the idle routine will hit + * WFI the power domain will be correctly retained. + */ + + nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true); + nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true); + + nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true); + nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true); + +#if defined(CONFIG_SOC_NRF54H20_ENGA_CPUAPP) + nrf_lrcconf_poweron_force_set(NRF_LRCCONF000, NRF_LRCCONF_POWER_DOMAIN_0, true); +#endif +} + +static int trim_hsfll(void) +{ + NRF_HSFLL_Type *hsfll = (NRF_HSFLL_Type *)DT_REG_ADDR(HSFLL_NODE); + nrf_hsfll_trim_t trim = { + .vsup = sys_read32(FICR_ADDR_GET(HSFLL_NODE, vsup)), + .coarse = sys_read32(FICR_ADDR_GET(HSFLL_NODE, coarse)), + .fine = sys_read32(FICR_ADDR_GET(HSFLL_NODE, fine)) + }; + + LOG_DBG("Trim: HSFLL VSUP: 0x%.8x", trim.vsup); + LOG_DBG("Trim: HSFLL COARSE: 0x%.8x", trim.coarse); + LOG_DBG("Trim: HSFLL FINE: 0x%.8x", trim.fine); + + nrf_hsfll_clkctrl_mult_set(hsfll, + DT_PROP(HSFLL_NODE, clock_frequency) / + DT_PROP(DT_CLOCKS_CTLR(HSFLL_NODE), clock_frequency)); + nrf_hsfll_trim_set(hsfll, &trim); + + nrf_hsfll_task_trigger(hsfll, NRF_HSFLL_TASK_FREQ_CHANGE); +#if defined(CONFIG_SOC_NRF54H20_ENGA_CPUAPP) || defined(CONFIG_SOC_NRF54H20_ENGA_CPURAD) + /* In this HW revision, HSFLL task frequency change needs to be + * triggered additional time to take effect. + */ + nrf_hsfll_task_trigger(hsfll, NRF_HSFLL_TASK_FREQ_CHANGE); +#endif + + LOG_DBG("NRF_HSFLL->TRIM.VSUP = %d", hsfll->TRIM.VSUP); + LOG_DBG("NRF_HSFLL->TRIM.COARSE = %d", hsfll->TRIM.COARSE); + LOG_DBG("NRF_HSFLL->TRIM.FINE = %d", hsfll->TRIM.FINE); + + return 0; +} + +static int nordicsemi_nrf54h_init(void) +{ +#if defined(CONFIG_NRF_ENABLE_ICACHE) + sys_cache_instr_enable(); +#endif + + power_domain_init(); + + trim_hsfll(); + + return 0; +} + +void arch_busy_wait(uint32_t time_us) +{ + nrfx_coredep_delay_us(time_us); +} + +SYS_INIT(nordicsemi_nrf54h_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/nordic_nrf/nrf54h/soc.h b/soc/arm/nordic_nrf/nrf54h/soc.h new file mode 100644 index 000000000000..9a44ab24982e --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/soc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ +#define SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ + +#include + +#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */ diff --git a/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt b/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt new file mode 100644 index 000000000000..33036acce8fe --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources( + soc.c + ../validate_rram_partitions.c) + +if (CONFIG_ELV_GRTC_LFXO_ALLOWED) + message(WARNING "WARNING! ELV mode feature is EXPERIMENTAL and may brick your device!") +endif() diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp new file mode 100644 index 000000000000..d19df604c027 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp @@ -0,0 +1,18 @@ +# Nordic Semiconductor nRF54L15 MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54L15_ENGA_CPUAPP + +config SOC + string + default "nrf54l15_cpuapp" + +config NUM_IRQS + default 271 + +config IEEE802154_NRF5 + default IEEE802154 + +endif # SOC_NRF54L15_ENGA_CPUAPP diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series new file mode 100644 index 000000000000..6c0a5bc606d5 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series @@ -0,0 +1,19 @@ +# Nordic Semiconductor nRF54L MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54LX + +rsource "Kconfig.defconfig.nrf54l*" + +config SOC_SERIES + default "nrf54l" + +config CORTEX_M_SYSTICK + default !NRF_GRTC_TIMER + +config CACHE_NRF_CACHE + default y if EXTERNAL_CACHE + +endif # SOC_SERIES_NRF54LX diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.series b/soc/arm/nordic_nrf/nrf54l/Kconfig.series new file mode 100644 index 000000000000..a9367a0bf363 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.series @@ -0,0 +1,13 @@ +# Nordic Semiconductor nRF54L MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54LX + bool "Nordic Semiconductor nRF54L series MCU" + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select SOC_FAMILY_NRF + help + Enable support for nRF54L MCU series diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.soc b/soc/arm/nordic_nrf/nrf54l/Kconfig.soc new file mode 100644 index 000000000000..c42c8cfc9b37 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.soc @@ -0,0 +1,70 @@ +# Nordic Semiconductor nRF54 MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54LX + +config SOC_NRF54L15 + bool "NRF54L15" + +config SOC_NRF54L15_ENGA + bool "NRF54L15 ENGA" + select SOC_NRF54L15 + +config SOC_NRF54L15_ENGA_CPUAPP + bool "NRF54L15 ENGA CPUAPP" + select ARM + select ARMV8_M_DSP + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select HAS_HW_NRF_RADIO_IEEE802154 + select HAS_POWEROFF + select SOC_NRF54L15_ENGA + +config SOC_NRF54LX_SKIP_CLOCK_CONFIG + bool "Skip clock frequency configuration in system initialization" + help + With this option, the CPU clock frequency is not set during system initialization. + The CPU runs with the default, hardware-selected frequency. + +config SOC_NRF_FORCE_CONSTLAT + bool "Force constant-latency mode" + help + In constant latency mode the CPU wakeup latency and the PPI task response + will be constant and kept at a minimum. This is secured by forcing a set + 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. + +config SOC_NRF54L_VREG_MAIN_DCDC + bool "NRF54L DC/DC converter." + help + To enable, an inductor must be connected to the DC/DC converter pin. + +config SOC_NRF54L_NORMAL_VOLTAGE_MODE + bool "NRF54L Normal Voltage Mode." + +config SOC_NRF54L_GLITCHDET_WORKAROUND + bool "Workaround that disables glitch detector" + default y + help + Temporary workaround - disabling glitch detector to limit power consumption. + +if NRF_GRTC_TIMER + +config ELV_GRTC_LFXO_ALLOWED + bool + depends on NRF_GRTC_SLEEP_ALLOWED + 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/arm/nordic_nrf/nrf54l/soc.c b/soc/arm/nordic_nrf/nrf54l/soc.c new file mode 100644 index 000000000000..a7b286fa048d --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/soc.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Nordic Semiconductor nRF54L family processor + * + * This module provides routines to initialize and support board-level hardware + * for the Nordic Semiconductor nRF54L family processor. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#define LFXO_NODE DT_NODELABEL(lfxo) +#define HFXO_NODE DT_NODELABEL(hfxo) + +static int nordicsemi_nrf54l_init(void) +{ + /* Update the SystemCoreClock global variable with current core clock + * retrieved from hardware state. + */ + SystemCoreClockUpdate(); + + /* Enable ICACHE */ + sys_cache_instr_enable(); + + if (IS_ENABLED(CONFIG_SOC_NRF54L_GLITCHDET_WORKAROUND)) { + nrf_glitchdet_enable_set(NRF_GLITCHDET, false); + } + +#if DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, internal) + uint32_t xosc32ktrim = NRF_FICR->XOSC32KTRIM; + + uint32_t offset_k = + (xosc32ktrim & FICR_XOSC32KTRIM_OFFSET_Msk) >> FICR_XOSC32KTRIM_OFFSET_Pos; + + uint32_t slope_field_k = + (xosc32ktrim & FICR_XOSC32KTRIM_SLOPE_Msk) >> FICR_XOSC32KTRIM_SLOPE_Pos; + uint32_t slope_mask_k = FICR_XOSC32KTRIM_SLOPE_Msk >> FICR_XOSC32KTRIM_SLOPE_Pos; + uint32_t slope_sign_k = (slope_mask_k - (slope_mask_k >> 1)); + int32_t slope_k = (int32_t)(slope_field_k ^ slope_sign_k) - (int32_t)slope_sign_k; + + /* As specified in the nRF54L15 PS: + * CAPVALUE = round( (CAPACITANCE - 4) * (FICR->XOSC32KTRIM.SLOPE + 0.765625 * 2^9)/(2^9) + * + FICR->XOSC32KTRIM.OFFSET/(2^6) ); + * where CAPACITANCE is the desired capacitor value in pF, holding any + * value between 4 pF and 18 pF in 0.5 pF steps. + */ + uint32_t mid_val = + (((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) * 2UL) / 1000UL - 8UL) * + (uint32_t)(slope_k + 392)) + (offset_k << 4UL); + uint32_t capvalue_k = mid_val >> 10UL; + + /* Round. */ + if ((mid_val % 1024UL) >= 512UL) { + capvalue_k++; + } + nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)capvalue_k); +#elif DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, external) + nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)0); +#endif + +#if DT_ENUM_HAS_VALUE(HFXO_NODE, load_capacitors, internal) + uint32_t xosc32mtrim = NRF_FICR->XOSC32MTRIM; + /* The SLOPE field is in the two's complement form, hence this special + * handling. Ideally, it would result in just one SBFX instruction for + * extracting the slope value, at least gcc is capable of producing such + * output, but since the compiler apparently tries first to optimize + * additions and subtractions, it generates slightly less than optimal + * code. + */ + uint32_t slope_field = + (xosc32mtrim & FICR_XOSC32MTRIM_SLOPE_Msk) >> FICR_XOSC32MTRIM_SLOPE_Pos; + uint32_t slope_mask = FICR_XOSC32MTRIM_SLOPE_Msk >> FICR_XOSC32MTRIM_SLOPE_Pos; + uint32_t slope_sign = (slope_mask - (slope_mask >> 1)); + int32_t slope_m = (int32_t)(slope_field ^ slope_sign) - (int32_t)slope_sign; + uint32_t offset_m = + (xosc32mtrim & FICR_XOSC32MTRIM_OFFSET_Msk) >> FICR_XOSC32MTRIM_OFFSET_Pos; + /* As specified in the nRF54L15 PS: + * CAPVALUE = (((CAPACITANCE-5.5)*(FICR->XOSC32MTRIM.SLOPE+791)) + + * FICR->XOSC32MTRIM.OFFSET<<2)>>8; + * where CAPACITANCE is the desired total load capacitance value in pF, + * holding any value between 4.0 pF and 17.0 pF in 0.25 pF steps. + */ + uint32_t capvalue = + (((((DT_PROP(HFXO_NODE, load_capacitance_femtofarad) * 4UL) / 1000UL) - 22UL) * + (uint32_t)(slope_m + 791) / 4UL) + (offset_m << 2UL)) >> 8UL; + + nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, true, capvalue); +#elif DT_ENUM_HAS_VALUE(HFXO_NODE, load_capacitors, external) + nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, false, 0); +#endif + + if (IS_ENABLED(CONFIG_SOC_NRF_FORCE_CONSTLAT)) { + nrf_power_task_trigger(NRF_POWER, NRF_POWER_TASK_CONSTLAT); + } + + if (IS_ENABLED(CONFIG_SOC_NRF54L_VREG_MAIN_DCDC)) { + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MAIN, true); + } + + if (IS_ENABLED(CONFIG_SOC_NRF54L_NORMAL_VOLTAGE_MODE)) { + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MEDIUM, false); + } + +#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 */ + + return 0; +} + +void arch_busy_wait(uint32_t time_us) +{ + nrfx_coredep_delay_us(time_us); +} + +SYS_INIT(nordicsemi_nrf54l_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/nordic_nrf/nrf54l/soc.h b/soc/arm/nordic_nrf/nrf54l/soc.h new file mode 100644 index 000000000000..b775fa9d0f39 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/soc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Nordic Semiconductor NRF54L family processors. + */ + +#ifndef _NORDICSEMI_NRF54L_SOC_H_ +#define _NORDICSEMI_NRF54L_SOC_H_ + +#include + +#define FLASH_PAGE_ERASE_MAX_TIME_US 8000UL +#define FLASH_PAGE_MAX_CNT 381UL + +#endif /* _NORDICSEMI_NRF54L_SOC_H_ */ diff --git a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt index 7424bb9f7b9b..35d47fb252bc 100644 --- a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt @@ -1,7 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( - soc.c - ) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +zephyr_library_sources(soc.c) diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA new file mode 100644 index 000000000000..1b3ea88e359b --- /dev/null +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA @@ -0,0 +1,14 @@ +# Nordic Semiconductor nRF9151 MCU + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9151_LACA + +config SOC + default "nRF9151_LACA" + +config NUM_IRQS + default 65 + +endif # SOC_NRF9151_LACA diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series index 9612555a4c82..6d6cccab9999 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf91*" config SOC_SERIES default "nrf91" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF91X diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 1be69c377e5e..08d36e5b48c3 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -27,9 +27,23 @@ config NRF_SPU_FLASH_REGION_SIZE help FLASH region size for the NRF_SPU peripheral +config NRF_SPU_FLASH_REGION_ALIGNMENT + hex + default 0x8000 + help + FLASH regions must be aligned to this value due to SPU HW + limitations. + config NRF_SPU_RAM_REGION_SIZE hex default 0x2000 help RAM region size for the NRF_SPU peripheral + +config NRF_SPU_RAM_REGION_ALIGNMENT + hex + default 0x2000 + help + RAM regions must be aligned to this value due to SPU HW + limitations. endif diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.soc b/soc/arm/nordic_nrf/nrf91/Kconfig.soc index c9b8c54438bf..0267ada4850e 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.soc @@ -34,6 +34,10 @@ config SOC_NRF9131_LACA bool "NRF9131_LACA" select SOC_NRF9120 +config SOC_NRF9151_LACA + bool "NRF9151_LACA" + select SOC_NRF9120 + endchoice config NRF_ENABLE_ICACHE diff --git a/soc/arm/nordic_nrf/validate_base_addresses.c b/soc/arm/nordic_nrf/validate_base_addresses.c index 58aaa5a75134..28ec231b132b 100644 --- a/soc/arm/nordic_nrf/validate_base_addresses.c +++ b/soc/arm/nordic_nrf/validate_base_addresses.c @@ -16,6 +16,10 @@ #define NRF_CTRLAP NRF_CTRL_AP_PERI #endif +#if !defined(NRF_GPIOTE0) && defined(NRF_GPIOTE) +#define NRF_GPIOTE0 NRF_GPIOTE +#endif + #if !defined(NRF_I2S0) && defined(NRF_I2S) #define NRF_I2S0 NRF_I2S #endif @@ -141,6 +145,12 @@ CHECK_DT_REG(flash_controller, NRF_NVMC); CHECK_DT_REG(gpio0, NRF_P0); CHECK_DT_REG(gpio1, NRF_P1); CHECK_DT_REG(gpiote, NRF_GPIOTE); +CHECK_DT_REG(gpiote0, NRF_GPIOTE0); +CHECK_DT_REG(gpiote1, NRF_GPIOTE1); +CHECK_DT_REG(gpiote20, NRF_GPIOTE20); +CHECK_DT_REG(gpiote30, NRF_GPIOTE30); +CHECK_DT_REG(gpiote130, NRF_GPIOTE130); +CHECK_DT_REG(gpiote131, NRF_GPIOTE131); CHECK_I2C_REG(i2c0, 0); CHECK_I2C_REG(i2c1, 1); CHECK_DT_REG(i2c2, NRF_TWIM2); @@ -188,10 +198,31 @@ CHECK_DT_REG(timer1, NRF_TIMER1); CHECK_DT_REG(timer2, NRF_TIMER2); CHECK_DT_REG(timer3, NRF_TIMER3); CHECK_DT_REG(timer4, NRF_TIMER4); +CHECK_DT_REG(timer00, NRF_TIMER00); +CHECK_DT_REG(timer10, NRF_TIMER10); +CHECK_DT_REG(timer20, NRF_TIMER20); +CHECK_DT_REG(timer21, NRF_TIMER21); +CHECK_DT_REG(timer22, NRF_TIMER22); +CHECK_DT_REG(timer23, NRF_TIMER23); +CHECK_DT_REG(timer24, NRF_TIMER24); CHECK_UART_REG(uart0, 0); CHECK_DT_REG(uart1, NRF_UARTE1); CHECK_DT_REG(uart2, NRF_UARTE2); CHECK_DT_REG(uart3, NRF_UARTE3); +CHECK_DT_REG(uart00, NRF_UARTE00); +CHECK_DT_REG(uart20, NRF_UARTE20); +CHECK_DT_REG(uart21, NRF_UARTE21); +CHECK_DT_REG(uart22, NRF_UARTE22); +CHECK_DT_REG(uart30, NRF_UARTE30); +CHECK_DT_REG(uart120, NRF_UARTE120); +CHECK_DT_REG(uart130, NRF_UARTE130); +CHECK_DT_REG(uart131, NRF_UARTE131); +CHECK_DT_REG(uart132, NRF_UARTE132); +CHECK_DT_REG(uart133, NRF_UARTE133); +CHECK_DT_REG(uart134, NRF_UARTE134); +CHECK_DT_REG(uart135, NRF_UARTE135); +CHECK_DT_REG(uart136, NRF_UARTE136); +CHECK_DT_REG(uart137, NRF_UARTE137); CHECK_DT_REG(uicr, NRF_UICR); CHECK_DT_REG(usbd, NRF_USBD); CHECK_DT_REG(usbreg, NRF_USBREGULATOR); @@ -199,6 +230,8 @@ CHECK_DT_REG(vmc, NRF_VMC); CHECK_DT_REG(wdt, NRF_WDT0); /* this should be the same node as wdt0 */ CHECK_DT_REG(wdt0, NRF_WDT0); CHECK_DT_REG(wdt1, NRF_WDT1); +CHECK_DT_REG(wdt30, NRF_WDT30); +CHECK_DT_REG(wdt31, NRF_WDT31); /* nRF51/nRF52-specific addresses */ #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) diff --git a/soc/arm/nordic_nrf/validate_rram_partitions.c b/soc/arm/nordic_nrf/validate_rram_partitions.c new file mode 100644 index 000000000000..f35d9cf73f3c --- /dev/null +++ b/soc/arm/nordic_nrf/validate_rram_partitions.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define PAIR__(f, sep, arg_first, ...) FOR_EACH_FIXED_ARG(f, sep, arg_first, __VA_ARGS__) +#define PAIR_(f, sep, args_to_expand) PAIR__(f, sep, args_to_expand) +#define PAIR(n, f, sep, ...) PAIR_(f, sep, GET_ARGS_LESS_N(n, __VA_ARGS__)) + +/** + * @brief Call a macro on every unique pair of the given variadic arguments. + * + * For example, FOR_EACH_PAIR(f, (,), 1, 2, 3, 4) should expand to: + * + * f(2, 1) , f(3, 1) , f(4, 1) , f(3, 2) , f(4, 2) , f(4, 3) + * + * @param f Macro to call. Must accept two arguments. + * @param sep Separator between macro calls. Must be in parentheses. + * + * @see FOR_EACH + */ +#define FOR_EACH_PAIR(f, sep, ...) \ + LISTIFY(NUM_VA_ARGS_LESS_1(__VA_ARGS__), PAIR, sep, f, sep, __VA_ARGS__) + +/** + * @brief Get a node's non-secure register block start address. + * + * @param node_id Node identifier. + */ +#define REG_ADDR_NS(node_id) (DT_REG_ADDR(node_id) & 0xEFFFFFFFUL) + +/** + * @brief Get a node's non-secure register block end address. + * + * @param node_id Node identifier. + */ +#define REG_END_NS(node_id) (REG_ADDR_NS(node_id) + DT_REG_SIZE(node_id)) + +/* clang-format off */ + +#define RRAM_BASE REG_ADDR_NS(DT_NODELABEL(rram0)) +#define RRAM_CONTROLLER DT_NODELABEL(rram_controller) + +#if !DT_NODE_EXISTS(RRAM_CONTROLLER) +#error "Missing \"rram-controller\" node" +#endif + +#define CHECK_RRAM_NODE_COMPATIBLE(node_id) \ + BUILD_ASSERT(DT_NODE_HAS_COMPAT(node_id, soc_nv_flash), \ + "Missing compatible \"soc-nv-flash\" from " DT_NODE_FULL_NAME(node_id) \ + " (required for all children of " DT_NODE_PATH(RRAM_CONTROLLER) ")") + +#define CHECK_RRAM_PARTITION_WITHIN_PARENT(node_id) \ + BUILD_ASSERT(RRAM_BASE + REG_ADDR_NS(node_id) >= REG_ADDR_NS(DT_GPARENT(node_id)) && \ + RRAM_BASE + REG_END_NS(node_id) <= REG_END_NS(DT_GPARENT(node_id)), \ + DT_NODE_FULL_NAME(node_id) " is not fully contained within its parent " \ + DT_NODE_PATH(DT_GPARENT(node_id))) + +#define CHECK_NODES_NON_OVERLAPPING(node_id_1, node_id_2) \ + BUILD_ASSERT(REG_ADDR_NS(node_id_1) >= REG_END_NS(node_id_2) || \ + REG_ADDR_NS(node_id_2) >= REG_END_NS(node_id_1), \ + DT_NODE_PATH(node_id_1) " and " DT_NODE_PATH(node_id_2) " are overlapping") + +/* Retrieve all RRAM nodes that are children of "rram-controller". */ +#define COMMA(x) x, +#define RRAM_NODES_LIST LIST_DROP_EMPTY(DT_FOREACH_CHILD(RRAM_CONTROLLER, COMMA)) + +#if !IS_EMPTY(RRAM_NODES_LIST) + +/* Check that every RRAM node matches the "soc-nv-flash" compatible. */ +FOR_EACH(CHECK_RRAM_NODE_COMPATIBLE, (;), RRAM_NODES_LIST); + +/* Check that no two RRAM nodes are overlapping. */ +FOR_EACH_PAIR(CHECK_NODES_NON_OVERLAPPING, (;), RRAM_NODES_LIST); + +#endif + +/* Retrieve all RRAM partitions by looking for "fixed-partitions" compatibles in each RRAM node. */ +#define PARTITION_(x) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(x, fixed_partitions), (DT_FOREACH_CHILD(x, COMMA)), ()) +#define PARTITION(x, ...) DT_FOREACH_CHILD_STATUS_OKAY(x, PARTITION_) +#define RRAM_PARTITION_LIST LIST_DROP_EMPTY(DT_FOREACH_CHILD_VARGS(RRAM_CONTROLLER, PARTITION)) + +#if !IS_EMPTY(RRAM_PARTITION_LIST) + +/* Check that every RRAM partition is within the bounds of its parent RRAM node. */ +FOR_EACH(CHECK_RRAM_PARTITION_WITHIN_PARENT, (;), RRAM_PARTITION_LIST); + +/* Check that no two RRAM partitions are overlapping. */ +FOR_EACH_PAIR(CHECK_NODES_NON_OVERLAPPING, (;), RRAM_PARTITION_LIST); + +#endif diff --git a/soc/arm/nuvoton_npcx/npcx4/soc.h b/soc/arm/nuvoton_npcx/npcx4/soc.h index a9d4e88424ba..9c780ca034a6 100644 --- a/soc/arm/nuvoton_npcx/npcx4/soc.h +++ b/soc/arm/nuvoton_npcx/npcx4/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX4 SCFG multi-registers */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nuvoton_npcx/npcx7/soc.h b/soc/arm/nuvoton_npcx/npcx7/soc.h index 7099552cec38..9b523ce1b8fc 100644 --- a/soc/arm/nuvoton_npcx/npcx7/soc.h +++ b/soc/arm/nuvoton_npcx/npcx7/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX7 SCFG multi-registers offset */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nuvoton_npcx/npcx9/soc.h b/soc/arm/nuvoton_npcx/npcx9/soc.h index 6b6c3f30a44b..2ce745650fb0 100644 --- a/soc/arm/nuvoton_npcx/npcx9/soc.h +++ b/soc/arm/nuvoton_npcx/npcx9/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX9 SCFG multi-registers */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series b/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series index ac0428eff53a..7279ac8596ec 100644 --- a/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_IMX_6X_M4 select HAS_IMX_HAL select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU select CLOCK_CONTROL help Enable support for M4 core of i.MX 6SoloX MCU series diff --git a/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series b/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series index be0065cb3730..e7ae54bcbdad 100644 --- a/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_IMX7_M4 select SOC_FAMILY_IMX select CLOCK_CONTROL select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX7 M4 MCU series diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series index dddb12d1b70a..f860a7fbd262 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series @@ -9,5 +9,6 @@ config SOC_SERIES_IMX8MM_M4 select CPU_CORTEX_M4 select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX8MM M4 MCU series diff --git a/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series b/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series index c4b16d3fb5cd..3933037c3a03 100644 --- a/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series @@ -9,5 +9,6 @@ config SOC_SERIES_IMX8MQ_M4 select CPU_CORTEX_M4 select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX8MQ M4 MCU series diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index 0058993e8251..96dcd14dc866 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -21,6 +21,7 @@ config SOC_MIMXRT1011 select HAS_MCUX_LPUART select HAS_MCUX_GPT select HAS_MCUX_TRNG + select CPU_HAS_FPU select CPU_HAS_ARM_MPU select INIT_ENET_PLL select HAS_MCUX_USB_EHCI @@ -45,6 +46,7 @@ config SOC_MIMXRT1015 select HAS_MCUX_LPUART select HAS_MCUX_GPT select HAS_MCUX_TRNG + select CPU_HAS_FPU select CPU_HAS_FPU_DOUBLE_PRECISION select CPU_HAS_ARM_MPU select INIT_ENET_PLL @@ -368,6 +370,7 @@ config SOC_MIMXRT1176_CM4 select HAS_MCUX_FLEXSPI select HAS_MCUX_LPUART select HAS_MCUX_GPT + select CPU_HAS_FPU select CPU_HAS_ARM_MPU select INIT_ARM_PLL select INIT_ENET_PLL if NET_L2_ETHERNET && ETH_DRIVER @@ -435,6 +438,7 @@ config SOC_MIMXRT1166_CM4 select HAS_MCUX_FLEXSPI select HAS_MCUX_GPT select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select INIT_ARM_PLL select INIT_ENET_PLL if NET_L2_ETHERNET && ETH_DRIVER select INIT_VIDEO_PLL diff --git a/soc/arm/nxp_kinetis/kl2x/Kconfig.series b/soc/arm/nxp_kinetis/kl2x/Kconfig.series index 53558c816481..3c606c7db272 100644 --- a/soc/arm/nxp_kinetis/kl2x/Kconfig.series +++ b/soc/arm/nxp_kinetis/kl2x/Kconfig.series @@ -9,6 +9,7 @@ config SOC_SERIES_KINETIS_KL2X select CPU_CORTEX_M0PLUS select SOC_FAMILY_KINETIS select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select CLOCK_CONTROL select PLATFORM_SPECIFIC_INIT help diff --git a/soc/arm/nxp_kinetis/kwx/Kconfig.series b/soc/arm/nxp_kinetis/kwx/Kconfig.series index 4b00dd997a95..36ba7b54c219 100644 --- a/soc/arm/nxp_kinetis/kwx/Kconfig.series +++ b/soc/arm/nxp_kinetis/kwx/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_KINETIS_KWX select ARM select SOC_FAMILY_KINETIS select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select CLOCK_CONTROL select PLATFORM_SPECIFIC_INIT help diff --git a/soc/arm/nxp_lpc/lpc11u6x/soc.h b/soc/arm/nxp_lpc/lpc11u6x/soc.h index fd7ffbd54006..ec0abb4faf17 100644 --- a/soc/arm/nxp_lpc/lpc11u6x/soc.h +++ b/soc/arm/nxp_lpc/lpc11u6x/soc.h @@ -19,6 +19,7 @@ #ifndef _ASMLANGUAGE #include +#include #endif /* !_ASMLANGUAGE */ diff --git a/soc/arm/nxp_lpc/lpc51u68/Kconfig.series b/soc/arm/nxp_lpc/lpc51u68/Kconfig.series index 6995de0917ac..8b1a9dd18b18 100644 --- a/soc/arm/nxp_lpc/lpc51u68/Kconfig.series +++ b/soc/arm/nxp_lpc/lpc51u68/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_LPC51U68 select HAS_MCUX_SCTIMER select SOC_FAMILY_LPC select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select PLATFORM_SPECIFIC_INIT help Enable support for LPC LPC51U68 MCU Series diff --git a/soc/arm/nxp_lpc/lpc51u68/soc.h b/soc/arm/nxp_lpc/lpc51u68/soc.h index 45355fb148e2..9135c3fed717 100644 --- a/soc/arm/nxp_lpc/lpc51u68/soc.h +++ b/soc/arm/nxp_lpc/lpc51u68/soc.h @@ -10,6 +10,8 @@ #ifndef _ASMLANGUAGE #include +#include + #endif /* !_ASMLANGUAGE*/ #define IOCON_PIO_DIGITAL_EN 0x80u diff --git a/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc index 099dc832d5bb..e71bc8f451e4 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc @@ -12,6 +12,7 @@ config SOC_LPC54114_M4 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select PLATFORM_SPECIFIC_INIT select CLOCK_CONTROL select HAS_MCUX_IAP_LEGACY diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index c0341a8e9c5e..a80374f2d81d 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -35,6 +35,7 @@ config SOC_LPC55S16 config SOC_LPC55S28 bool "SOC_LPC55S28 M33" select CPU_CORTEX_M33 + select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_HAS_FPU select ARMV8_M_DSP diff --git a/soc/arm/nxp_s32/s32k3/soc.h b/soc/arm/nxp_s32/s32k3/soc.h index bbc53e18023b..9e273ac68162 100644 --- a/soc/arm/nxp_s32/s32k3/soc.h +++ b/soc/arm/nxp_s32/s32k3/soc.h @@ -8,6 +8,7 @@ #define _NXP_S32_S32K_SOC_H_ #include +#include #if defined(CONFIG_CMSIS_RTOS_V2) /* diff --git a/soc/arm/quicklogic_eos_s3/Kconfig.soc b/soc/arm/quicklogic_eos_s3/Kconfig.soc index cb5fd170870c..e555933430bb 100644 --- a/soc/arm/quicklogic_eos_s3/Kconfig.soc +++ b/soc/arm/quicklogic_eos_s3/Kconfig.soc @@ -7,4 +7,5 @@ config SOC_EOS_S3 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_SYSTICK select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select EOS_S3_HAL diff --git a/soc/arm/renesas_ra/common/ra_common_soc.h b/soc/arm/renesas_ra/common/ra_common_soc.h index 605597937435..f76c4c26fc0d 100644 --- a/soc/arm/renesas_ra/common/ra_common_soc.h +++ b/soc/arm/renesas_ra/common/ra_common_soc.h @@ -11,6 +11,8 @@ extern "C" { #endif +#include + #ifdef __cplusplus } #endif diff --git a/soc/arm/renesas_smartbond/da1469x/Kconfig.series b/soc/arm/renesas_smartbond/da1469x/Kconfig.series index a3a9e569460b..c3672a9ecaf7 100644 --- a/soc/arm/renesas_smartbond/da1469x/Kconfig.series +++ b/soc/arm/renesas_smartbond/da1469x/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_DA1469X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_SYSTICK + select ARMV8_M_DSP select SOC_FAMILY_SMARTBOND select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select CLOCK_CONTROL diff --git a/soc/arm/rpi_pico/rp2/soc.h b/soc/arm/rpi_pico/rp2/soc.h index b38d2edf4614..0eef4cf92a24 100644 --- a/soc/arm/rpi_pico/rp2/soc.h +++ b/soc/arm/rpi_pico/rp2/soc.h @@ -12,8 +12,6 @@ #ifndef _RPI_PICO_RP2040_SOC_H_ #define _RPI_PICO_RP2040_SOC_H_ - -#define __VTOR_PRESENT CONFIG_CPU_CORTEX_M_HAS_VTOR -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include #endif /* _RPI_PICO_RP2040_SOC_H_ */ diff --git a/soc/arm/silabs_exx32/efm32hg/Kconfig.series b/soc/arm/silabs_exx32/efm32hg/Kconfig.series index 33793b5386d8..d17c24fbcdb2 100644 --- a/soc/arm/silabs_exx32/efm32hg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32hg/Kconfig.series @@ -9,6 +9,7 @@ config SOC_SERIES_EFM32HG select CPU_CORTEX_M0PLUS select SOC_FAMILY_EXX32 select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select HAS_SILABS_GECKO select SOC_GECKO_CMU select SOC_GECKO_GPIO diff --git a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series index 146493469e8c..731658d29e34 100644 --- a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_EFR32MG21 select ARMV8_M_DSP select CPU_HAS_FPU select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU select SOC_FAMILY_EXX32 select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 diff --git a/soc/arm/st_stm32/stm32mp1/Kconfig.series b/soc/arm/st_stm32/stm32mp1/Kconfig.series index 0c6580e84cce..c1576a7ee178 100644 --- a/soc/arm/st_stm32/stm32mp1/Kconfig.series +++ b/soc/arm/st_stm32/stm32mp1/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_STM32MP1X select SOC_FAMILY_STM32 select HAS_STM32CUBE select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select OPENAMP_RSC_TABLE if RAM_CONSOLE help Enable support for STM32MP1 MPU series diff --git a/soc/arm/ti_k3/am62x_m4/soc.h b/soc/arm/ti_k3/am62x_m4/soc.h index 01ff4b07080c..2fd6537b9840 100644 --- a/soc/arm/ti_k3/am62x_m4/soc.h +++ b/soc/arm/ti_k3/am62x_m4/soc.h @@ -7,6 +7,8 @@ #ifndef __SOC_H_ #define __SOC_H_ +#include + #include #endif /* __SOC_H */ diff --git a/soc/arm/ti_lm3s6965/soc.h b/soc/arm/ti_lm3s6965/soc.h index bef939013bac..3c353b1a79b2 100644 --- a/soc/arm/ti_lm3s6965/soc.h +++ b/soc/arm/ti_lm3s6965/soc.h @@ -15,6 +15,7 @@ #ifndef _BOARD__H_ #define _BOARD__H_ +#include #include /* default system clock */ diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h b/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h index a1d3504b9867..fdc9214732c1 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h @@ -7,6 +7,8 @@ #ifndef TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ #define TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ +#include + /* CMSIS required values */ typedef enum { Reset_IRQn = -15, @@ -27,4 +29,6 @@ typedef enum { #define __Vendor_SysTickConfig 0 #define __FPU_PRESENT 1 +#include + #endif /* TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ */ diff --git a/soc/arm/ti_simplelink/cc32xx/soc.h b/soc/arm/ti_simplelink/cc32xx/soc.h index 9c841e0e4b0c..e18dfce626ae 100644 --- a/soc/arm/ti_simplelink/cc32xx/soc.h +++ b/soc/arm/ti_simplelink/cc32xx/soc.h @@ -7,6 +7,8 @@ #ifndef TI_SIMPLELINK_CC32XX_SOC_H_ #define TI_SIMPLELINK_CC32XX_SOC_H_ +#include + #include #include @@ -38,4 +40,6 @@ typedef enum { #define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS #define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ +#include + #endif /* TI_SIMPLELINK_CC32XX_SOC_H_ */ diff --git a/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series b/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series index 6bb0043ff900..8af48672ed23 100644 --- a/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series +++ b/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_MSP432P4XX select DYNAMIC_INTERRUPTS select SOC_FAMILY_TISIMPLELINK select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for TI SimpleLink MSP432P4XX. diff --git a/soc/common/CMakeLists.txt b/soc/common/CMakeLists.txt new file mode 100644 index 000000000000..d9abad218cd4 --- /dev/null +++ b/soc/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_NRF nordic_nrf) diff --git a/soc/common/nordic_nrf/CMakeLists.txt b/soc/common/nordic_nrf/CMakeLists.txt new file mode 100644 index 000000000000..6f397a07fab1 --- /dev/null +++ b/soc/common/nordic_nrf/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/common/nordic_nrf/Kconfig.peripherals similarity index 78% rename from soc/arm/nordic_nrf/Kconfig.peripherals rename to soc/common/nordic_nrf/Kconfig.peripherals index 3aacc35a08a0..b8b1198ca02c 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/common/nordic_nrf/Kconfig.peripherals @@ -13,10 +13,12 @@ config HAS_HW_NRF_BPROT def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_BPROT)) config HAS_HW_NRF_CC310 - def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_310)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_310)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_SERIES_NRF91X) config HAS_HW_NRF_CC312 - def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_312)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_ARM_CRYPTOCELL_312)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_NRF5340_CPUAPP) config HAS_HW_NRF_CCM def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CCM)) @@ -69,8 +71,23 @@ config HAS_HW_NRF_GPIO0 config HAS_HW_NRF_GPIO1 def_bool $(dt_nodelabel_enabled_with_compat,gpio1,$(DT_COMPAT_NORDIC_NRF_GPIO)) -config HAS_HW_NRF_GPIOTE - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) +config HAS_HW_NRF_GPIOTE0 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote0,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE1 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote1,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE20 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote20,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE30 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote30,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE130 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote130,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE131 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote131,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) config HAS_HW_NRF_I2S0 def_bool $(dt_nodelabel_enabled_with_compat,i2s0,$(DT_COMPAT_NORDIC_NRF_I2S)) @@ -303,6 +320,27 @@ config HAS_HW_NRF_TIMER3 config HAS_HW_NRF_TIMER4 def_bool $(dt_nodelabel_enabled_with_compat,timer4,$(DT_COMPAT_NORDIC_NRF_TIMER)) +config HAS_HW_NRF_TIMER00 + def_bool $(dt_nodelabel_enabled_with_compat,timer00,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER10 + def_bool $(dt_nodelabel_enabled_with_compat,timer10,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER20 + def_bool $(dt_nodelabel_enabled_with_compat,timer20,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER21 + def_bool $(dt_nodelabel_enabled_with_compat,timer21,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER22 + def_bool $(dt_nodelabel_enabled_with_compat,timer22,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER23 + def_bool $(dt_nodelabel_enabled_with_compat,timer23,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER24 + def_bool $(dt_nodelabel_enabled_with_compat,timer24,$(DT_COMPAT_NORDIC_NRF_TIMER)) + config HAS_HW_NRF_TWI0 def_bool $(dt_nodelabel_enabled_with_compat,i2c0,$(DT_COMPAT_NORDIC_NRF_TWI)) @@ -387,6 +425,48 @@ config HAS_HW_NRF_UARTE2 config HAS_HW_NRF_UARTE3 def_bool $(dt_nodelabel_enabled_with_compat,uart3,$(DT_COMPAT_NORDIC_NRF_UARTE)) +config HAS_HW_NRF_UARTE00 + def_bool $(dt_nodelabel_enabled_with_compat,uart00,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE20 + def_bool $(dt_nodelabel_enabled_with_compat,uart20,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE21 + def_bool $(dt_nodelabel_enabled_with_compat,uart21,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE22 + def_bool $(dt_nodelabel_enabled_with_compat,uart22,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE30 + def_bool $(dt_nodelabel_enabled_with_compat,uart30,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE120 + def_bool $(dt_nodelabel_enabled_with_compat,uart120,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE130 + def_bool $(dt_nodelabel_enabled_with_compat,uart130,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE131 + def_bool $(dt_nodelabel_enabled_with_compat,uart131,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE132 + def_bool $(dt_nodelabel_enabled_with_compat,uart132,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE133 + def_bool $(dt_nodelabel_enabled_with_compat,uart133,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE134 + def_bool $(dt_nodelabel_enabled_with_compat,uart134,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE135 + def_bool $(dt_nodelabel_enabled_with_compat,uart135,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE136 + def_bool $(dt_nodelabel_enabled_with_compat,uart136,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE137 + def_bool $(dt_nodelabel_enabled_with_compat,uart137,$(DT_COMPAT_NORDIC_NRF_UARTE)) + config HAS_HW_NRF_USBD def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_USBD)) @@ -401,3 +481,12 @@ config HAS_HW_NRF_WDT0 config HAS_HW_NRF_WDT1 def_bool $(dt_nodelabel_enabled_with_compat,wdt1,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT30 + def_bool $(dt_nodelabel_enabled_with_compat,wdt30,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT31 + def_bool $(dt_nodelabel_enabled_with_compat,wdt31,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT130 + def_bool $(dt_nodelabel_enabled_with_compat,wdt130,$(DT_COMPAT_NORDIC_NRF_WDT)) diff --git a/soc/arm/nordic_nrf/common/pinctrl_soc.h b/soc/common/nordic_nrf/pinctrl_soc.h similarity index 100% rename from soc/arm/nordic_nrf/common/pinctrl_soc.h rename to soc/common/nordic_nrf/pinctrl_soc.h diff --git a/soc/riscv/CMakeLists.txt b/soc/riscv/CMakeLists.txt index b826da926caf..79d115704b29 100644 --- a/soc/riscv/CMakeLists.txt +++ b/soc/riscv/CMakeLists.txt @@ -1,5 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 +add_subdirectory(common) + if(SOC_FAMILY) add_subdirectory(${SOC_FAMILY}) else() diff --git a/soc/riscv/andes_v5/CMakeLists.txt b/soc/riscv/andes_v5/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/andes_v5/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/andes_v5/Kconfig b/soc/riscv/andes_v5/Kconfig new file mode 100644 index 000000000000..f3c78ab7f813 --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_ANDES_V5 + bool + +if SOC_FAMILY_ANDES_V5 + +config SOC_FAMILY + string + default "andes_v5" + +source "soc/riscv/andes_v5/*/Kconfig.soc" + +endif # SOC_FAMILY_ANDES_V5 diff --git a/soc/riscv/andes_v5/Kconfig.defconfig b/soc/riscv/andes_v5/Kconfig.defconfig new file mode 100644 index 000000000000..6213f28d2cb3 --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/andes_v5/*/Kconfig.defconfig.series" diff --git a/soc/riscv/andes_v5/Kconfig.soc b/soc/riscv/andes_v5/Kconfig.soc new file mode 100644 index 000000000000..9efb47819344 --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/andes_v5/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt b/soc/riscv/andes_v5/ae350/CMakeLists.txt similarity index 82% rename from soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt rename to soc/riscv/andes_v5/ae350/CMakeLists.txt index 212683123474..b8eac026dfbb 100644 --- a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt +++ b/soc/riscv/andes_v5/ae350/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(${CONFIG_SOC}) +zephyr_include_directories(.) zephyr_sources( start.S @@ -24,6 +24,6 @@ if(CONFIG_SOC_ANDES_V5_EXECIT) zephyr_ld_options(-Wl,--mexecit) endif() -if(CONFIG_SOC_RISCV_ANDES_AE350) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/ae350/linker.ld CACHE INTERNAL "") +if(CONFIG_SOC_ANDES_AE350) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 similarity index 88% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 rename to soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 index 5d652057a38b..fee73684b715 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 +++ b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_RISCV_ANDES_AE350 +if SOC_ANDES_AE350 config SOC default "ae350" @@ -25,4 +25,4 @@ config MP_MAX_NUM_CPUS default 1 range 1 8 -endif # SOC_RISCV_ANDES_AE350 +endif # SOC_ANDES_AE350 diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.series similarity index 76% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series rename to soc/riscv/andes_v5/ae350/Kconfig.defconfig.series index c6436807825f..7b9bbc3eadbb 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series +++ b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.series @@ -1,15 +1,15 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_ANDES_V5 +if SOC_SERIES_ANDES_AE350 # Kconfig picks the first default with a satisfied condition. # SoC defaults should be parsed before SoC Series defaults, because SoCs usually # overrides SoC Series values. -source "soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae*" +source "soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae*" config SOC_SERIES - default "andes_v5" + default "ae350" config SYS_CLOCK_HW_CYCLES_PER_SEC default 60000000 @@ -24,12 +24,6 @@ config RISCV_GENERIC_TOOLCHAIN config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -45,4 +39,4 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 64 -endif # SOC_SERIES_RISCV_ANDES_V5 +endif # SOC_SERIES_ANDES_AE350 diff --git a/soc/riscv/andes_v5/ae350/Kconfig.series b/soc/riscv/andes_v5/ae350/Kconfig.series new file mode 100644 index 000000000000..c2e9b40bfb7f --- /dev/null +++ b/soc/riscv/andes_v5/ae350/Kconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Andes Technology Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ANDES_AE350 + bool "Andes V5 AE350 SoC Series Implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_ANDES_V5 + help + Enable support for Andes V5 AE350 SoC Series diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.soc b/soc/riscv/andes_v5/ae350/Kconfig.soc similarity index 95% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.soc rename to soc/riscv/andes_v5/ae350/Kconfig.soc index 19f215e2c5ac..1731cc08f51c 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.soc +++ b/soc/riscv/andes_v5/ae350/Kconfig.soc @@ -3,9 +3,9 @@ choice prompt "Andes V5 SoC Selection" -depends on SOC_SERIES_RISCV_ANDES_V5 +depends on SOC_SERIES_ANDES_AE350 -config SOC_RISCV_ANDES_AE350 +config SOC_ANDES_AE350 bool "Andes AE350 SoC implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR @@ -18,7 +18,7 @@ config SOC_RISCV_ANDES_AE350 endchoice -if SOC_SERIES_RISCV_ANDES_V5 +if SOC_SERIES_ANDES_AE350 choice prompt "Base CPU ISA options" @@ -121,4 +121,4 @@ config SOC_ANDES_V5_IOCP between cache and external non-caching master, such as DMA controller. -endif # SOC_SERIES_RISCV_ANDES_V5 +endif # SOC_SERIES_ANDES_AE350 diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/execit.ld b/soc/riscv/andes_v5/ae350/common_linker/execit.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/execit.ld rename to soc/riscv/andes_v5/ae350/common_linker/execit.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/init.ld b/soc/riscv/andes_v5/ae350/common_linker/init.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/init.ld rename to soc/riscv/andes_v5/ae350/common_linker/init.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/ram_start_nonzero.ld b/soc/riscv/andes_v5/ae350/common_linker/ram_start_nonzero.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/ram_start_nonzero.ld rename to soc/riscv/andes_v5/ae350/common_linker/ram_start_nonzero.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/l2_cache.c b/soc/riscv/andes_v5/ae350/l2_cache.c similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/l2_cache.c rename to soc/riscv/andes_v5/ae350/l2_cache.c diff --git a/soc/riscv/riscv-privileged/andes_v5/ae350/linker.ld b/soc/riscv/andes_v5/ae350/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/ae350/linker.ld rename to soc/riscv/andes_v5/ae350/linker.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/pma.c b/soc/riscv/andes_v5/ae350/pma.c similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/pma.c rename to soc/riscv/andes_v5/ae350/pma.c diff --git a/soc/riscv/riscv-privileged/andes_v5/ae350/soc.h b/soc/riscv/andes_v5/ae350/soc.h similarity index 93% rename from soc/riscv/riscv-privileged/andes_v5/ae350/soc.h rename to soc/riscv/andes_v5/ae350/soc.h index 95ea7486fd3b..fd3a9e63c0d2 100644 --- a/soc/riscv/riscv-privileged/andes_v5/ae350/soc.h +++ b/soc/riscv/andes_v5/ae350/soc.h @@ -11,8 +11,6 @@ #ifndef __RISCV_ANDES_AE350_SOC_H_ #define __RISCV_ANDES_AE350_SOC_H_ -#include - /* Include CSRs available for Andes V5 SoCs */ #include "soc_v5.h" diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_context.h b/soc/riscv/andes_v5/ae350/soc_context.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_context.h rename to soc/riscv/andes_v5/ae350/soc_context.h diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_irq.S b/soc/riscv/andes_v5/ae350/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_irq.S rename to soc/riscv/andes_v5/ae350/soc_irq.S diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_offsets.h b/soc/riscv/andes_v5/ae350/soc_offsets.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_offsets.h rename to soc/riscv/andes_v5/ae350/soc_offsets.h diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_v5.h b/soc/riscv/andes_v5/ae350/soc_v5.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_v5.h rename to soc/riscv/andes_v5/ae350/soc_v5.h diff --git a/soc/riscv/riscv-privileged/andes_v5/start.S b/soc/riscv/andes_v5/ae350/start.S similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/start.S rename to soc/riscv/andes_v5/ae350/start.S diff --git a/soc/riscv/common/CMakeLists.txt b/soc/riscv/common/CMakeLists.txt new file mode 100644 index 000000000000..91ef5c975b91 --- /dev/null +++ b/soc/riscv/common/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory_ifdef(CONFIG_RISCV_PRIVILEGED riscv-privileged) diff --git a/soc/riscv/common/Kconfig b/soc/riscv/common/Kconfig new file mode 100644 index 000000000000..91f2c5cf80a4 --- /dev/null +++ b/soc/riscv/common/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +source "soc/riscv/common/riscv-privileged/Kconfig" diff --git a/soc/riscv/riscv-privileged/common/CMakeLists.txt b/soc/riscv/common/riscv-privileged/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/common/CMakeLists.txt rename to soc/riscv/common/riscv-privileged/CMakeLists.txt diff --git a/soc/riscv/common/riscv-privileged/Kconfig b/soc/riscv/common/riscv-privileged/Kconfig new file mode 100644 index 000000000000..10c2e37712bb --- /dev/null +++ b/soc/riscv/common/riscv-privileged/Kconfig @@ -0,0 +1,11 @@ +# Configuration options for riscv SOCs supporting the riscv privileged +# architecture specification + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config RISCV_VECTORED_MODE + bool "Should the SOC use vectored mode" + depends on RISCV_PRIVILEGED + help + Should the SOC use vectored mode. diff --git a/soc/riscv/riscv-privileged/common/soc_common_irq.c b/soc/riscv/common/riscv-privileged/soc_common_irq.c similarity index 100% rename from soc/riscv/riscv-privileged/common/soc_common_irq.c rename to soc/riscv/common/riscv-privileged/soc_common_irq.c diff --git a/soc/riscv/riscv-privileged/common/soc_irq.S b/soc/riscv/common/riscv-privileged/soc_irq.S similarity index 56% rename from soc/riscv/riscv-privileged/common/soc_irq.S rename to soc/riscv/common/riscv-privileged/soc_irq.S index 73fc24431d58..acf7e724aea4 100644 --- a/soc/riscv/riscv-privileged/common/soc_irq.S +++ b/soc/riscv/common/riscv-privileged/soc_irq.S @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* * __soc_handle_irq is defined as .weak to allow re-implementation by @@ -32,30 +32,3 @@ SECTION_FUNC(exception.other, __soc_handle_irq) /* Return */ ret - -/* - * __soc_is_irq is defined as .weak to allow re-implementation by - * SOCs that do not truly follow the riscv privilege specification. - */ -WTEXT(__soc_is_irq) - -/* - * SOC-specific function to determine if the exception is the result of a - * an interrupt or an exception - * return 1 (interrupt) or 0 (exception) - * - */ -SECTION_FUNC(exception.other, __soc_is_irq) - /* Read mcause and check if interrupt bit is set */ - csrr t0, mcause - li t1, SOC_MCAUSE_IRQ_MASK - and t0, t0, t1 - - /* If interrupt bit is not set, return with 0 */ - addi a0, x0, 0 - beqz t0, not_interrupt - addi a0, a0, 1 - -not_interrupt: - /* return */ - ret diff --git a/soc/riscv/riscv-privileged/common/vector.S b/soc/riscv/common/riscv-privileged/vector.S similarity index 100% rename from soc/riscv/riscv-privileged/common/vector.S rename to soc/riscv/common/riscv-privileged/vector.S diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt b/soc/riscv/efinix_sapphire/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt rename to soc/riscv/efinix_sapphire/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series b/soc/riscv/efinix_sapphire/Kconfig.defconfig similarity index 58% rename from soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series rename to soc/riscv/efinix_sapphire/Kconfig.defconfig index 233428931a38..95a33b4ab829 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series +++ b/soc/riscv/efinix_sapphire/Kconfig.defconfig @@ -1,25 +1,18 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_EFINIX_SAPPHIRE +if SOC_EFINIX_SAPPHIRE -config SOC_SERIES - default "efinix-sapphire" +config SOC + default "efinix_sapphire" config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 -config RISCV_HAS_CPU_IDLE - bool - config RISCV_SOC_INTERRUPT_INIT bool default y -config RISCV_HAS_PLIC - bool - default y - config NUM_IRQS int default 36 @@ -27,4 +20,4 @@ config NUM_IRQS config 2ND_LVL_INTR_00_OFFSET default 11 -endif # SOC_SERIES_EFINIX_SAPPHIRE +endif # SOC_EFINIX_SAPPHIRE diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc b/soc/riscv/efinix_sapphire/Kconfig.soc similarity index 72% rename from soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc rename to soc/riscv/efinix_sapphire/Kconfig.soc index dba8491b8bda..4bad3b5cb79f 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc +++ b/soc/riscv/efinix_sapphire/Kconfig.soc @@ -1,11 +1,7 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -choice - prompt "Efinix SoC selection" - depends on SOC_SERIES_EFINIX_SAPPHIRE - -config SOC_RISCV32_EFINIX_SAPPHIRE +config SOC_EFINIX_SAPPHIRE bool "Efinix Sapphire VexRiscv system implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR @@ -14,5 +10,6 @@ config SOC_RISCV32_EFINIX_SAPPHIRE select RISCV_ISA_EXT_A select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/soc.h b/soc/riscv/efinix_sapphire/soc.h similarity index 93% rename from soc/riscv/riscv-privileged/efinix-sapphire/soc.h rename to soc/riscv/efinix_sapphire/soc.h index 1d566e2f293d..5530af16729c 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/soc.h +++ b/soc/riscv/efinix_sapphire/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV32_EFINIX_SAPPHIRE_SOC_H_ #define __RISCV32_EFINIX_SAPPHIRE_SOC_H_ -#include "soc_common.h" #include #include diff --git a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt index e97f71751ef9..d6772eacbfc9 100644 --- a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt +++ b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources( - idle.c vectors.S soc_irq.S soc_irq.c diff --git a/soc/riscv/espressif_esp32/esp32c3/idle.c b/soc/riscv/espressif_esp32/esp32c3/idle.c deleted file mode 100644 index 1bfb28321877..000000000000 --- a/soc/riscv/espressif_esp32/esp32c3/idle.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -/** - * @brief Power save idle routine - * - * This function will be called by the kernel idle loop or possibly within - * an implementation of _pm_save_idle in the kernel when the - * '_pm_save_flag' variable is non-zero. - */ -void arch_cpu_idle(void) -{ - /* curiously it arrives here with the interrupts masked - * so umask it before wait for an event - */ - arch_irq_unlock(MSTATUS_IEN); - - /* Wait for interrupt */ - __asm__ volatile("wfi"); -} diff --git a/soc/riscv/espressif_esp32/esp32c3/soc.h b/soc/riscv/espressif_esp32/esp32c3/soc.h index a3709819abc5..68fb6fdb1cec 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc.h +++ b/soc/riscv/espressif_esp32/esp32c3/soc.h @@ -16,20 +16,6 @@ #include "esp32c3/clk.h" #endif -/* IRQ numbers */ -#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ -#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */ -#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ - -/* ECALL Exception numbers */ -#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ -#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ - -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 31) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF - #ifndef _ASMLANGUAGE void __esp_platform_start(void); diff --git a/soc/riscv/espressif_esp32/esp32c3/soc_irq.S b/soc/riscv/espressif_esp32/esp32c3/soc_irq.S index c1ad164c1536..6ce11ae6a818 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc_irq.S +++ b/soc/riscv/espressif_esp32/esp32c3/soc_irq.S @@ -7,15 +7,9 @@ #include /* Exports */ -GTEXT(__soc_is_irq) GTEXT(__soc_handle_irq) GTEXT(soc_intr_get_next_source) -SECTION_FUNC(exception.other, __soc_is_irq) - csrr a0, mcause - srli a0, a0, 31 - ret - SECTION_FUNC(exception.other, __soc_handle_irq) addi sp, sp,-4 sw ra, 0x00(sp) diff --git a/soc/riscv/gd_gd32/CMakeLists.txt b/soc/riscv/gd_gd32/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/gd_gd32/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/gd_gd32/Kconfig b/soc/riscv/gd_gd32/Kconfig new file mode 100644 index 000000000000..46f2dd0b1d6b --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_GD32 + bool + +if SOC_FAMILY_GD32 + +config SOC_FAMILY + string + default "gd_gd32" + +source "soc/riscv/gd_gd32/*/Kconfig.soc" + +endif # SOC_FAMILY_GIGADEVICE_GD32 diff --git a/soc/riscv/gd_gd32/Kconfig.defconfig b/soc/riscv/gd_gd32/Kconfig.defconfig new file mode 100644 index 000000000000..2be284db7eac --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/gd_gd32/*/Kconfig.defconfig.series" diff --git a/soc/riscv/gd_gd32/Kconfig.soc b/soc/riscv/gd_gd32/Kconfig.soc new file mode 100644 index 000000000000..09d7d5d627ea --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/gd_gd32/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt b/soc/riscv/gd_gd32/gd32vf103/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt rename to soc/riscv/gd_gd32/gd32vf103/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 similarity index 79% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 index 1e93f2703b23..94af3ff773c2 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 @@ -14,21 +14,15 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC # The CPU frequency is set to the maximum value of 108MHz by default. default 27000000 -config RISCV_SOC_MCAUSE_EXCEPTION_MASK - default $(dt_node_int_prop_hex,/cpus/cpu@0,mcause-exception-mask) +config RISCV_MCAUSE_EXCEPTION_MASK + default 0xFFF config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y -config RISCV_HAS_PLIC - default n - config NUM_IRQS default 87 if NUCLEI_ECLIC default 16 if !NUCLEI_ECLIC diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series similarity index 72% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series index 061b53b2514e..17ab7a87c392 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series @@ -3,7 +3,7 @@ if SOC_SERIES_GD32VF103 -source "soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103*" +source "soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103*" config SOC_SERIES default "gd32vf103" diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.series b/soc/riscv/gd_gd32/gd32vf103/Kconfig.series similarity index 90% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.series rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.series index 3922bf19bdda..e50567e07980 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.series +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.series @@ -6,7 +6,7 @@ config SOC_SERIES_GD32VF103 bool "GigaDevice GD32VF103 series SoC implementation" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED select ATOMIC_OPERATIONS_C select INCLUDE_RESET_VECTOR select BUILD_OUTPUT_HEX @@ -15,6 +15,6 @@ config SOC_SERIES_GD32VF103 select GD32_HAS_IRC_40K select HAS_GD32_HAL select RISCV_HAS_CLIC - + select SOC_FAMILY_GD32 help Enable support for GigaDevice GD32VF1 series SoC diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.soc b/soc/riscv/gd_gd32/gd32vf103/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.soc rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/gd32vf103/entry.S b/soc/riscv/gd_gd32/gd32vf103/entry.S similarity index 97% rename from soc/riscv/riscv-privileged/gd32vf103/entry.S rename to soc/riscv/gd_gd32/gd32vf103/entry.S index 5f8af0d691f5..41cc6cc686b3 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/entry.S +++ b/soc/riscv/gd_gd32/gd32vf103/entry.S @@ -4,9 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "nuclei_csr.h" + #include #include -#include GTEXT(__nuclei_start) SECTION_FUNC(vectors, __nuclei_start) diff --git a/soc/riscv/riscv-privileged/gd32vf103/gd32_regs.h b/soc/riscv/gd_gd32/gd32vf103/gd32_regs.h similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/gd32_regs.h rename to soc/riscv/gd_gd32/gd32vf103/gd32_regs.h diff --git a/soc/riscv/riscv-privileged/common/nuclei/nuclei_csr.h b/soc/riscv/gd_gd32/gd32vf103/nuclei_csr.h similarity index 100% rename from soc/riscv/riscv-privileged/common/nuclei/nuclei_csr.h rename to soc/riscv/gd_gd32/gd32vf103/nuclei_csr.h diff --git a/soc/riscv/riscv-privileged/gd32vf103/pinctrl_soc.h b/soc/riscv/gd_gd32/gd32vf103/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/pinctrl_soc.h rename to soc/riscv/gd_gd32/gd32vf103/pinctrl_soc.h diff --git a/soc/riscv/riscv-privileged/gd32vf103/soc.c b/soc/riscv/gd_gd32/gd32vf103/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/soc.c rename to soc/riscv/gd_gd32/gd32vf103/soc.c diff --git a/soc/riscv/riscv-privileged/gd32vf103/soc.h b/soc/riscv/gd_gd32/gd32vf103/soc.h similarity index 92% rename from soc/riscv/riscv-privileged/gd32vf103/soc.h rename to soc/riscv/gd_gd32/gd32vf103/soc.h index 14cdd6b733c1..ad2add6fa808 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/soc.h +++ b/soc/riscv/gd_gd32/gd32vf103/soc.h @@ -11,6 +11,4 @@ #ifndef RISCV_GD32VF103_SOC_H_ #define RISCV_GD32VF103_SOC_H_ -#include - #endif /* RISCV_GD32VF103_SOC_H */ diff --git a/soc/riscv/intel_niosv/CMakeLists.txt b/soc/riscv/intel_niosv/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/intel_niosv/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/intel_niosv/Kconfig b/soc/riscv/intel_niosv/Kconfig new file mode 100644 index 000000000000..b841d19c9227 --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_INTEL_NIOSV + bool + +if SOC_FAMILY_INTEL_NIOSV + +config SOC_FAMILY + string + default "intel_niosv" + +source "soc/riscv/intel_niosv/*/Kconfig.soc" + +endif # SOC_FAMILY_INTEL_NIOSV diff --git a/soc/riscv/intel_niosv/Kconfig.defconfig b/soc/riscv/intel_niosv/Kconfig.defconfig new file mode 100644 index 000000000000..2afa0f7e0e60 --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/intel_niosv/*/Kconfig.defconfig.series" diff --git a/soc/riscv/intel_niosv/Kconfig.soc b/soc/riscv/intel_niosv/Kconfig.soc new file mode 100644 index 000000000000..8567429c61f6 --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/intel_niosv/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/niosv/CMakeLists.txt b/soc/riscv/intel_niosv/niosv/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/niosv/CMakeLists.txt rename to soc/riscv/intel_niosv/niosv/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series b/soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series similarity index 86% rename from soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series rename to soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series index 532a67959d2c..15e98314c893 100644 --- a/soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series +++ b/soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series @@ -12,13 +12,10 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config NUM_IRQS # Platform interrupts IRQs index start from index 16 default 32 -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y config RISCV_SOC_INTERRUPT_INIT default y -endif # SOC_SERIES_NIOSV +endif # SOC_NIOSV diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.series b/soc/riscv/intel_niosv/niosv/Kconfig.series similarity index 77% rename from soc/riscv/riscv-privileged/niosv/Kconfig.series rename to soc/riscv/intel_niosv/niosv/Kconfig.series index 7de17cf2db09..9d7aa4926921 100644 --- a/soc/riscv/riscv-privileged/niosv/Kconfig.series +++ b/soc/riscv/intel_niosv/niosv/Kconfig.series @@ -4,6 +4,7 @@ config SOC_SERIES_NIOSV bool "INTEL FPGA NIOSV" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select SOC_FAMILY_INTEL_NIOSV help Enable support for the INTEL FPGA NIOSV. diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.soc b/soc/riscv/intel_niosv/niosv/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/niosv/Kconfig.soc rename to soc/riscv/intel_niosv/niosv/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/niosv/linker.ld b/soc/riscv/intel_niosv/niosv/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/niosv/linker.ld rename to soc/riscv/intel_niosv/niosv/linker.ld diff --git a/soc/riscv/riscv-privileged/niosv/soc.h b/soc/riscv/intel_niosv/niosv/soc.h similarity index 90% rename from soc/riscv/riscv-privileged/niosv/soc.h rename to soc/riscv/intel_niosv/niosv/soc.h index 8c10fec45405..87458c91dff7 100644 --- a/soc/riscv/riscv-privileged/niosv/soc.h +++ b/soc/riscv/intel_niosv/niosv/soc.h @@ -7,7 +7,6 @@ #ifndef RISCV_INTEL_FPGA_NIOSV_H #define RISCV_INTEL_FPGA_NIOSV_H -#include #include #endif /* RISCV_INTEL_FPGA_NIOSV_H */ diff --git a/soc/riscv/riscv-ite/CMakeLists.txt b/soc/riscv/ite_ec/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/CMakeLists.txt rename to soc/riscv/ite_ec/CMakeLists.txt diff --git a/soc/riscv/ite_ec/Kconfig b/soc/riscv/ite_ec/Kconfig new file mode 100644 index 000000000000..54628029a4ec --- /dev/null +++ b/soc/riscv/ite_ec/Kconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2020 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_ITE_EC + bool + help + ITE Embedded Controller SoC family + +if SOC_FAMILY_ITE_EC + +config SOC_FAMILY + string + default "ite_ec" + +source "soc/riscv/ite_ec/*/Kconfig.soc" + +endif # SOC_FAMILY_ITE_EC diff --git a/soc/riscv/riscv-ite/Kconfig.defconfig b/soc/riscv/ite_ec/Kconfig.defconfig similarity index 63% rename from soc/riscv/riscv-ite/Kconfig.defconfig rename to soc/riscv/ite_ec/Kconfig.defconfig index ae18beac098b..8994f47abd9c 100644 --- a/soc/riscv/riscv-ite/Kconfig.defconfig +++ b/soc/riscv/ite_ec/Kconfig.defconfig @@ -1,4 +1,4 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -source "soc/riscv/riscv-ite/*/Kconfig.defconfig.series" +source "soc/riscv/ite_ec/*/Kconfig.defconfig.series" diff --git a/soc/riscv/riscv-ite/Kconfig.soc b/soc/riscv/ite_ec/Kconfig.soc similarity index 68% rename from soc/riscv/riscv-ite/Kconfig.soc rename to soc/riscv/ite_ec/Kconfig.soc index 925edb1543ce..13f951c04666 100644 --- a/soc/riscv/riscv-ite/Kconfig.soc +++ b/soc/riscv/ite_ec/Kconfig.soc @@ -1,4 +1,4 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -source "soc/riscv/riscv-ite/*/Kconfig.series" +source "soc/riscv/ite_ec/*/Kconfig.series" diff --git a/soc/riscv/riscv-ite/common/CMakeLists.txt b/soc/riscv/ite_ec/common/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/common/CMakeLists.txt rename to soc/riscv/ite_ec/common/CMakeLists.txt diff --git a/soc/riscv/riscv-ite/common/check_regs.c b/soc/riscv/ite_ec/common/check_regs.c similarity index 100% rename from soc/riscv/riscv-ite/common/check_regs.c rename to soc/riscv/ite_ec/common/check_regs.c diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/ite_ec/common/chip_chipregs.h similarity index 100% rename from soc/riscv/riscv-ite/common/chip_chipregs.h rename to soc/riscv/ite_ec/common/chip_chipregs.h diff --git a/soc/riscv/riscv-ite/common/pinctrl_soc.h b/soc/riscv/ite_ec/common/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-ite/common/pinctrl_soc.h rename to soc/riscv/ite_ec/common/pinctrl_soc.h diff --git a/soc/riscv/riscv-ite/common/policy.c b/soc/riscv/ite_ec/common/policy.c similarity index 100% rename from soc/riscv/riscv-ite/common/policy.c rename to soc/riscv/ite_ec/common/policy.c diff --git a/soc/riscv/riscv-ite/common/power.c b/soc/riscv/ite_ec/common/power.c similarity index 100% rename from soc/riscv/riscv-ite/common/power.c rename to soc/riscv/ite_ec/common/power.c diff --git a/soc/riscv/riscv-ite/common/soc_common.h b/soc/riscv/ite_ec/common/soc_common.h similarity index 82% rename from soc/riscv/riscv-ite/common/soc_common.h rename to soc/riscv/ite_ec/common/soc_common.h index 5b9817831646..b7e0cdd5e55f 100644 --- a/soc/riscv/riscv-ite/common/soc_common.h +++ b/soc/riscv/ite_ec/common/soc_common.h @@ -14,17 +14,6 @@ #include "chip_chipregs.h" -/* SOC-specific MCAUSE bitfields */ - -/* Interrupt Mask. 1 (interrupt) or 0 (exception) */ -#define SOC_MCAUSE_IRQ_MASK BIT(31) - -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF - -/* Exception code of environment call from M-mode */ -#define SOC_MCAUSE_ECALL_EXP 11 - #ifndef _ASMLANGUAGE #ifdef CONFIG_HAS_ITE_INTC diff --git a/soc/riscv/riscv-ite/common/soc_common_irq.c b/soc/riscv/ite_ec/common/soc_common_irq.c similarity index 100% rename from soc/riscv/riscv-ite/common/soc_common_irq.c rename to soc/riscv/ite_ec/common/soc_common_irq.c diff --git a/soc/riscv/riscv-ite/common/soc_dt.h b/soc/riscv/ite_ec/common/soc_dt.h similarity index 100% rename from soc/riscv/riscv-ite/common/soc_dt.h rename to soc/riscv/ite_ec/common/soc_dt.h diff --git a/soc/riscv/riscv-ite/common/soc_espi.h b/soc/riscv/ite_ec/common/soc_espi.h similarity index 100% rename from soc/riscv/riscv-ite/common/soc_espi.h rename to soc/riscv/ite_ec/common/soc_espi.h diff --git a/soc/riscv/riscv-ite/common/soc_irq.S b/soc/riscv/ite_ec/common/soc_irq.S similarity index 59% rename from soc/riscv/riscv-ite/common/soc_irq.S rename to soc/riscv/ite_ec/common/soc_irq.S index a412ca6a7966..ceb0f3afecb7 100644 --- a/soc/riscv/riscv-ite/common/soc_irq.S +++ b/soc/riscv/ite_ec/common/soc_irq.S @@ -25,21 +25,3 @@ GTEXT(__soc_handle_irq) */ SECTION_FUNC(exception.other, __soc_handle_irq) j get_irq - -/* - * __soc_is_irq is defined as .weak to allow re-implementation by - * SOCs that does not truely follow the riscv privilege specification. - */ -WTEXT(__soc_is_irq) - -/* - * SOC-specific function to determine if the exception is the result of a - * an interrupt or an exception - * return 1 (interrupt) or 0 (exception) - * - */ -SECTION_FUNC(exception.other, __soc_is_irq) - /* Read mcause and check if interrupt bit (bit 31) is set */ - csrr a0, mcause - srli a0, a0, 31 - ret diff --git a/soc/riscv/riscv-ite/common/vector.S b/soc/riscv/ite_ec/common/vector.S similarity index 100% rename from soc/riscv/riscv-ite/common/vector.S rename to soc/riscv/ite_ec/common/vector.S diff --git a/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt b/soc/riscv/ite_ec/it8xxx2/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt rename to soc/riscv/ite_ec/it8xxx2/CMakeLists.txt diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202bx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202bx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202bx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202bx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202cx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202cx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202cx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202cx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302bx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302bx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302bx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302bx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302cx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302cx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302cx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302cx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82002aw similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82002aw diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82202ax b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82202ax similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82202ax rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82202ax diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82302ax b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82302ax similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82302ax rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82302ax diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series similarity index 83% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series index 4e6b7c18cca3..0ed7358b631d 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series @@ -1,7 +1,7 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV32_IT8XXX2 +if SOC_SERIES_ITE_IT8XXX2 config SOC_SERIES default "it8xxx2" @@ -22,9 +22,6 @@ config UART_NS16550_WA_ISR_REENABLE_INTERRUPT default y depends on UART_NS16550 -config RISCV_HAS_CPU_IDLE - default y - config FLASH_INIT_PRIORITY default 0 @@ -57,6 +54,6 @@ config GEN_SW_ISR_TABLE config RISCV_SOC_INTERRUPT_INIT default y -source "soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it8*" +source "soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it8*" -endif # SOC_SERIES_RISCV32_IT8XXX2 +endif # SOC_SERIES_ITE_IT8XXX2 diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series b/soc/riscv/ite_ec/it8xxx2/Kconfig.series similarity index 86% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.series rename to soc/riscv/ite_ec/it8xxx2/Kconfig.series index ebed0fcd120e..265bf855f12c 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.series @@ -1,13 +1,13 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV32_IT8XXX2 +config SOC_SERIES_ITE_IT8XXX2 bool "ITE IT8XXX2 implementation" #depends on RISCV # RV32IAFC is an uncommon configuration which is not supported by # default in most toolchains, causing link-time errors. select CPU_HAS_FPU if "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "zephyr" || RISCV_ISA_EXT_M - select SOC_FAMILY_RISCV_ITE + select SOC_FAMILY_ITE_EC select HAS_PM help Enable support for ITE IT8XXX2 diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc b/soc/riscv/ite_ec/it8xxx2/Kconfig.soc similarity index 99% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.soc rename to soc/riscv/ite_ec/it8xxx2/Kconfig.soc index 38525449f89f..800a2a9dafd7 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.soc @@ -3,7 +3,7 @@ choice prompt "ITE IT8XXX2 system implementation" -depends on SOC_SERIES_RISCV32_IT8XXX2 +depends on SOC_SERIES_ITE_IT8XXX2 config SOC_IT8XXX2 bool "ITE IT8XXX2 system implementation" diff --git a/soc/riscv/riscv-ite/it8xxx2/__arithmetic.S b/soc/riscv/ite_ec/it8xxx2/__arithmetic.S similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/__arithmetic.S rename to soc/riscv/ite_ec/it8xxx2/__arithmetic.S diff --git a/soc/riscv/riscv-ite/it8xxx2/ilm.c b/soc/riscv/ite_ec/it8xxx2/ilm.c similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/ilm.c rename to soc/riscv/ite_ec/it8xxx2/ilm.c diff --git a/soc/riscv/riscv-ite/it8xxx2/ilm.h b/soc/riscv/ite_ec/it8xxx2/ilm.h similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/ilm.h rename to soc/riscv/ite_ec/it8xxx2/ilm.h diff --git a/soc/riscv/riscv-ite/it8xxx2/linker.ld b/soc/riscv/ite_ec/it8xxx2/linker.ld similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/linker.ld rename to soc/riscv/ite_ec/it8xxx2/linker.ld diff --git a/soc/riscv/riscv-ite/it8xxx2/soc.c b/soc/riscv/ite_ec/it8xxx2/soc.c similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/soc.c rename to soc/riscv/ite_ec/it8xxx2/soc.c diff --git a/soc/riscv/riscv-ite/it8xxx2/soc.h b/soc/riscv/ite_ec/it8xxx2/soc.h similarity index 94% rename from soc/riscv/riscv-ite/it8xxx2/soc.h rename to soc/riscv/ite_ec/it8xxx2/soc.h index bc7907683692..ea9d30d11fc1 100644 --- a/soc/riscv/riscv-ite/it8xxx2/soc.h +++ b/soc/riscv/ite_ec/it8xxx2/soc.h @@ -25,8 +25,4 @@ COND_CODE_1(DT_NODE_EXISTS(DT_INST(1, ite_it8xxx2_usbpd)), (2), (1)) */ #define SOC_USBPD_ITE_ACTIVE_PORT_COUNT DT_NUM_INST_STATUS_OKAY(ite_it8xxx2_usbpd) -#ifndef _ASMLANGUAGE -void soc_interrupt_init(void); -#endif - #endif /* __RISCV_ITE_SOC_H_ */ diff --git a/soc/riscv/litex-vexriscv/CMakeLists.txt b/soc/riscv/litex_vexriscv/CMakeLists.txt similarity index 73% rename from soc/riscv/litex-vexriscv/CMakeLists.txt rename to soc/riscv/litex_vexriscv/CMakeLists.txt index 9d100ea0e2a3..98386f6b57a6 100644 --- a/soc/riscv/litex-vexriscv/CMakeLists.txt +++ b/soc/riscv/litex_vexriscv/CMakeLists.txt @@ -5,8 +5,8 @@ # zephyr_sources( - ../riscv-privileged/common/soc_irq.S - ../riscv-privileged/common/vector.S + ../common/riscv-privileged/soc_irq.S + ../common/riscv-privileged/vector.S ) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/litex-vexriscv/Kconfig.defconfig b/soc/riscv/litex_vexriscv/Kconfig.defconfig similarity index 74% rename from soc/riscv/litex-vexriscv/Kconfig.defconfig rename to soc/riscv/litex_vexriscv/Kconfig.defconfig index 9447948b5676..0088420459f0 100644 --- a/soc/riscv/litex-vexriscv/Kconfig.defconfig +++ b/soc/riscv/litex_vexriscv/Kconfig.defconfig @@ -4,17 +4,11 @@ if SOC_RISCV32_LITEX_VEXRISCV config SOC - default "litex-vexriscv" + default "litex_vexriscv" config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 -config RISCV_HAS_CPU_IDLE - bool - -config RISCV_HAS_PLIC - bool - config NUM_IRQS default 12 diff --git a/soc/riscv/litex-vexriscv/Kconfig.soc b/soc/riscv/litex_vexriscv/Kconfig.soc similarity index 100% rename from soc/riscv/litex-vexriscv/Kconfig.soc rename to soc/riscv/litex_vexriscv/Kconfig.soc diff --git a/soc/riscv/litex-vexriscv/soc.h b/soc/riscv/litex_vexriscv/soc.h similarity index 98% rename from soc/riscv/litex-vexriscv/soc.h rename to soc/riscv/litex_vexriscv/soc.h index b738deec7713..4334be4ec1ca 100644 --- a/soc/riscv/litex-vexriscv/soc.h +++ b/soc/riscv/litex_vexriscv/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV32_LITEX_VEXRISCV_SOC_H_ #define __RISCV32_LITEX_VEXRISCV_SOC_H_ -#include "../riscv-privileged/common/soc_common.h" #include #include diff --git a/soc/riscv/microchip_miv/CMakeLists.txt b/soc/riscv/microchip_miv/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/microchip_miv/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/microchip_miv/Kconfig b/soc/riscv/microchip_miv/Kconfig new file mode 100644 index 000000000000..46616636aa12 --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_MIV + bool + +if SOC_FAMILY_MICROCHIP_MIV + +config SOC_FAMILY + string + default "microchip_miv" + +source "soc/riscv/microchip_miv/*/Kconfig.soc" + +endif # SOC_FAMILY_MICROCHIP_MIV diff --git a/soc/riscv/microchip_miv/Kconfig.defconfig b/soc/riscv/microchip_miv/Kconfig.defconfig new file mode 100644 index 000000000000..2fe508bddbac --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/microchip_miv/*/Kconfig.defconfig.series" diff --git a/soc/riscv/microchip_miv/Kconfig.soc b/soc/riscv/microchip_miv/Kconfig.soc new file mode 100644 index 000000000000..8677f1ba4487 --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/microchip_miv/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/miv/CMakeLists.txt b/soc/riscv/microchip_miv/miv/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/miv/CMakeLists.txt rename to soc/riscv/microchip_miv/miv/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series b/soc/riscv/microchip_miv/miv/Kconfig.defconfig.series similarity index 73% rename from soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series rename to soc/riscv/microchip_miv/miv/Kconfig.defconfig.series index 81b224ed3971..35f4365b02b6 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series +++ b/soc/riscv/microchip_miv/miv/Kconfig.defconfig.series @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV32_MIV +if SOC_SERIES_MIV config SOC_SERIES default "miv" @@ -11,12 +11,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -32,4 +26,4 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 42 -endif # SOC_SERIES_RISCV32_MIV +endif # SOC_SERIES_MIV diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.series b/soc/riscv/microchip_miv/miv/Kconfig.series similarity index 67% rename from soc/riscv/riscv-privileged/miv/Kconfig.series rename to soc/riscv/microchip_miv/miv/Kconfig.series index 00a6f129f9fa..9f3486196246 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.series +++ b/soc/riscv/microchip_miv/miv/Kconfig.series @@ -3,9 +3,11 @@ # Copyright (c) 2018 Antmicro # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV32_MIV +config SOC_SERIES_MIV bool "Microchip Mi-V implementation" + select SOC_FAMILY_MICROCHIP_MIV select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Microchip Mi-V diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.soc b/soc/riscv/microchip_miv/miv/Kconfig.soc similarity index 88% rename from soc/riscv/riscv-privileged/miv/Kconfig.soc rename to soc/riscv/microchip_miv/miv/Kconfig.soc index 189abb6879ce..0a48c2e0524e 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.soc +++ b/soc/riscv/microchip_miv/miv/Kconfig.soc @@ -5,9 +5,9 @@ choice prompt "Microchip Mi-V system implementation" - depends on SOC_SERIES_RISCV32_MIV + depends on SOC_SERIES_MIV -config SOC_RISCV32_MIV +config SOC_MIV bool "Microchip Mi-V system implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR diff --git a/soc/riscv/riscv-privileged/miv/soc.h b/soc/riscv/microchip_miv/miv/soc.h similarity index 89% rename from soc/riscv/riscv-privileged/miv/soc.h rename to soc/riscv/microchip_miv/miv/soc.h index 1608c9e6773e..c5827ceed215 100644 --- a/soc/riscv/riscv-privileged/miv/soc.h +++ b/soc/riscv/microchip_miv/miv/soc.h @@ -4,8 +4,6 @@ #ifndef __RISCV32_MIV_SOC_H_ #define __RISCV32_MIV_SOC_H_ -#include - /* UART Configuration */ #define MIV_UART_0_LINECFG 0x1 diff --git a/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt b/soc/riscv/microchip_miv/polarfire/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/mpfs/CMakeLists.txt rename to soc/riscv/microchip_miv/polarfire/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series b/soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series similarity index 78% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series rename to soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series index fb9f6d2d3af3..5a3f113c13e3 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series @@ -1,10 +1,10 @@ # Copyright (c) 2020-2021 Microchip Technology Inc # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV64_MIV +if SOC_SERIES_POLARFIRE config SOC_SERIES - default "mpfs" + default "polarfire" # MPFS should be configured so that the mtimer clock is 1MHz independent of the CPU clock... @@ -14,12 +14,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -38,4 +32,4 @@ config NUM_IRQS # config NO_OPTIMIZATIONS # default y -endif # SOC_SERIES_RISCV64_MIV +endif # SOC_SERIES_POLARFIRE diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.series b/soc/riscv/microchip_miv/polarfire/Kconfig.series similarity index 66% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.series rename to soc/riscv/microchip_miv/polarfire/Kconfig.series index ca37731f1925..59ec4dbdd7a9 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.series +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.series @@ -3,9 +3,11 @@ # Copyright (c) 2018 Antmicro # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV64_MIV +config SOC_SERIES_POLARFIRE bool "Microchip RV64 implementation" + select SOC_FAMILY_MICROCHIP_MIV select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Microchip RISCV 64bit diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.soc b/soc/riscv/microchip_miv/polarfire/Kconfig.soc similarity index 89% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.soc rename to soc/riscv/microchip_miv/polarfire/Kconfig.soc index 7f20dc703c22..101e8b4d0294 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.soc +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.soc @@ -5,9 +5,9 @@ choice prompt "Microchip Polarfire SOC implementation" - depends on SOC_SERIES_RISCV64_MIV + depends on SOC_SERIES_POLARFIRE -config SOC_MPFS +config SOC_POLARFIRE bool "Microchip MPFS system implementation" select ATOMIC_OPERATIONS_BUILTIN select RISCV_GP @@ -25,6 +25,6 @@ config SOC_MPFS endchoice config MPFS_HAL - depends on SOC_MPFS + depends on SOC_POLARFIRE bool "Microchip Polarfire SOC hardware abstracton layer" select HAS_MPFS_HAL diff --git a/soc/riscv/riscv-privileged/mpfs/soc.h b/soc/riscv/microchip_miv/polarfire/soc.h similarity index 77% rename from soc/riscv/riscv-privileged/mpfs/soc.h rename to soc/riscv/microchip_miv/polarfire/soc.h index d6a7d2d2e374..3bcb9569c6e5 100644 --- a/soc/riscv/riscv-privileged/mpfs/soc.h +++ b/soc/riscv/microchip_miv/polarfire/soc.h @@ -6,10 +6,6 @@ #ifndef __RISCV64_MPFS_SOC_H_ #define __RISCV64_MPFS_SOC_H_ -#include #include - -#define RISCV_MSIP_BASE 0x02000000 - #endif /* __RISCV64_MPFS_SOC_H_ */ diff --git a/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt b/soc/riscv/neorv32/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/CMakeLists.txt rename to soc/riscv/neorv32/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series b/soc/riscv/neorv32/Kconfig.defconfig similarity index 81% rename from soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series rename to soc/riscv/neorv32/Kconfig.defconfig index 11bd7ef7d337..bc37ea74727d 100644 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series +++ b/soc/riscv/neorv32/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NEORV32 +if SOC_NEORV32 -config SOC_SERIES +config SOC default "neorv32" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,9 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config NUM_IRQS default 32 -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y @@ -29,4 +26,4 @@ config ENTROPY_INIT_PRIORITY default 55 depends on ENTROPY_GENERATOR -endif # SOC_SERIES_NEORV32 +endif # SOC_NEORV32 diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.series b/soc/riscv/neorv32/Kconfig.soc similarity index 55% rename from soc/riscv/riscv-privileged/neorv32/Kconfig.series rename to soc/riscv/neorv32/Kconfig.soc index 98c7f34024d2..3155d1b7c31c 100644 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.series +++ b/soc/riscv/neorv32/Kconfig.soc @@ -1,7 +1,7 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NEORV32 +config SOC_NEORV32 bool "NEORV32 Processor" select RISCV select RISCV_ISA_RV32I @@ -9,7 +9,7 @@ config SOC_SERIES_NEORV32 select RISCV_ISA_EXT_A select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED help Enable support for the NEORV32 Processor (SoC). @@ -24,3 +24,27 @@ config SOC_SERIES_NEORV32 - E (Embedded, only 16 integer registers) - Zbb (Basic Bit Manipulation) - Zfinx (Floating Point in Integer Registers) + +if SOC_NEORV32 + +config SOC_NEORV32_V1_8_6 + bool "v1.8.6" + # NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO + select ATOMIC_OPERATIONS_C + +config SOC_NEORV32_VERSION + hex + default 0x01080600 if SOC_NEORV32_V1_8_6 + help + The targeted NEORV32 version as BCD-coded number. The format is + identical to that of the NEORV32 Machine implementation ID (mimpid) + register. + +config SOC_NEORV32_ISA_C + bool "RISC-V ISA Extension \"C\"" + select RISCV_ISA_EXT_C + help + Enable this if the NEORV32 CPU implementation supports the RISC-V ISA + "C" extension (Compressed Instructions). + +endif # SOC_NEORV32 diff --git a/soc/riscv/riscv-privileged/neorv32/linker.ld b/soc/riscv/neorv32/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/linker.ld rename to soc/riscv/neorv32/linker.ld diff --git a/soc/riscv/riscv-privileged/neorv32/reset.S b/soc/riscv/neorv32/reset.S similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/reset.S rename to soc/riscv/neorv32/reset.S diff --git a/soc/riscv/riscv-privileged/neorv32/soc.c b/soc/riscv/neorv32/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/soc.c rename to soc/riscv/neorv32/soc.c diff --git a/soc/riscv/riscv-privileged/neorv32/soc.h b/soc/riscv/neorv32/soc.h similarity index 98% rename from soc/riscv/riscv-privileged/neorv32/soc.h rename to soc/riscv/neorv32/soc.h index a1e721923a42..a97daa0fc153 100644 --- a/soc/riscv/riscv-privileged/neorv32/soc.h +++ b/soc/riscv/neorv32/soc.h @@ -7,8 +7,6 @@ #ifndef RISCV_NEORV32_SOC_H #define RISCV_NEORV32_SOC_H -#include - /* System information (SYSINFO) register offsets */ #define NEORV32_SYSINFO_CLK 0x00U #define NEORV32_SYSINFO_CPU 0x04U diff --git a/soc/riscv/riscv-privileged/neorv32/soc_irq.S b/soc/riscv/neorv32/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/soc_irq.S rename to soc/riscv/neorv32/soc_irq.S diff --git a/soc/riscv/riscv-privileged/CMakeLists.txt b/soc/riscv/nordic_nrf/CMakeLists.txt similarity index 69% rename from soc/riscv/riscv-privileged/CMakeLists.txt rename to soc/riscv/nordic_nrf/CMakeLists.txt index c5f97039eb75..6a5b10545ff1 100644 --- a/soc/riscv/riscv-privileged/CMakeLists.txt +++ b/soc/riscv/nordic_nrf/CMakeLists.txt @@ -1,3 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor # SPDX-License-Identifier: Apache-2.0 add_subdirectory(common) diff --git a/soc/riscv/nordic_nrf/Kconfig b/soc/riscv/nordic_nrf/Kconfig new file mode 100644 index 000000000000..a39db4671d5c --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_NRF + bool + +if SOC_FAMILY_NRF + +config SOC_FAMILY + string + default "nordic_nrf" + +source "soc/riscv/nordic_nrf/common/Kconfig" + +source "soc/common/nordic_nrf/Kconfig.peripherals" +source "soc/riscv/nordic_nrf/*/Kconfig.soc" + +endif # SOC_FAMILY_NRF diff --git a/soc/riscv/nordic_nrf/Kconfig.defconfig b/soc/riscv/nordic_nrf/Kconfig.defconfig new file mode 100644 index 000000000000..cc3ec9549854 --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_NRF + +source "soc/riscv/nordic_nrf/*/Kconfig.defconfig.series" +source "soc/riscv/nordic_nrf/common/Kconfig.defconfig" + +config BUILD_OUTPUT_HEX + default y + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 if NRF_GRTC_TIMER + default 32768 if NRF_RTC_TIMER + +endif # SOC_FAMILY_NRF diff --git a/soc/riscv/nordic_nrf/Kconfig.soc b/soc/riscv/nordic_nrf/Kconfig.soc new file mode 100644 index 000000000000..593d6f91769b --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/nordic_nrf/*/Kconfig.series" diff --git a/soc/riscv/nordic_nrf/common/CMakeLists.txt b/soc/riscv/nordic_nrf/common/CMakeLists.txt new file mode 100644 index 000000000000..806a295ea22c --- /dev/null +++ b/soc/riscv/nordic_nrf/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) diff --git a/soc/riscv/nordic_nrf/common/Kconfig b/soc/riscv/nordic_nrf/common/Kconfig new file mode 100644 index 000000000000..610689ecc6df --- /dev/null +++ b/soc/riscv/nordic_nrf/common/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/nordic_nrf/common/vpr/Kconfig" diff --git a/soc/riscv/nordic_nrf/common/Kconfig.defconfig b/soc/riscv/nordic_nrf/common/Kconfig.defconfig new file mode 100644 index 000000000000..9beb943edb80 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if RISCV_CORE_NORDIC_VPR + +source "soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig" + +endif # RISCV_CORE_NORDIC_VPR diff --git a/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt b/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt new file mode 100644 index 000000000000..e0331bb8e0ba --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_library() +zephyr_library_sources(soc_irq.S soc_irq.c vector.S) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/nordic_nrf/common/vpr/Kconfig b/soc/riscv/nordic_nrf/common/vpr/Kconfig new file mode 100644 index 000000000000..40a7d199c0c0 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config RISCV_CORE_NORDIC_VPR + bool "RISC-V Nordic VPR core" + default y + depends on DT_HAS_NORDIC_VPR_ENABLED + depends on RISCV + select ATOMIC_OPERATIONS_C + select RISCV_ISA_RV32E + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select RISCV_SOC_HAS_ISR_STACKING + select RISCV_SOC_CONTEXT_SAVE + help + Enable support for the RISC-V Nordic VPR core. diff --git a/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig b/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig new file mode 100644 index 000000000000..f0014455b3a4 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CPU_PATH := $(dt_nodelabel_path,cpu) +CPU_ID := $(dt_node_reg_addr_int,$(CPU_PATH)) + +config RV_BOOT_HART + default $(CPU_ID) + +config RISCV_MCAUSE_EXCEPTION_MASK + default 0xFFF + +config RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET + default 16 + +config GEN_IRQ_VECTOR_TABLE + default y + +choice IRQ_VECTOR_TABLE_TYPE + default IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS +endchoice + +config ARCH_SW_ISR_TABLE_ALIGN + default 64 + +config RISCV_ALWAYS_SWITCH_THROUGH_ECALL + default y if MULTITHREADING diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_context.h b/soc/riscv/nordic_nrf/common/vpr/soc_context.h new file mode 100644 index 000000000000..8cd0d1e5094e --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_context.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ + +#define SOC_ESF_MEMBERS unsigned long minttresh +#define SOC_ESF_INIT 0 + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_irq.S b/soc/riscv/nordic_nrf/common/vpr/soc_irq.S new file mode 100644 index 000000000000..0e9db48d9b48 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_irq.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_handle_irq) +GTEXT(__soc_save_context) +GTEXT(__soc_restore_context) + +/* + * No need to clear anything, pending bit is cleared by HW. + */ +SECTION_FUNC(exception.other, __soc_handle_irq) + ret + +SECTION_FUNC(exception.other, __soc_save_context) + csrr t0, 0x347 + sw t0, __soc_esf_t_minttresh_OFFSET(a0) + + ret + +SECTION_FUNC(exception.other, __soc_restore_context) + lw t0, __soc_esf_t_minttresh_OFFSET(a0) + csrw 0x347, t0 + + ret diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_irq.c b/soc/riscv/nordic_nrf/common/vpr/soc_irq.c new file mode 100644 index 000000000000..88655f6efa01 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_irq.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void arch_irq_enable(unsigned int irq) +{ + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, irq, true); +} + +void arch_irq_disable(unsigned int irq) +{ + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, irq, false); +} + +void arch_irq_priority_set(unsigned int irq, unsigned int prio) +{ + nrf_vpr_clic_int_priority_set(NRF_VPRCLIC, irq, prio); +} + +int arch_irq_is_enabled(unsigned int irq) +{ + return nrf_vpr_clic_int_enable_check(NRF_VPRCLIC, irq); +} diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h b/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h new file mode 100644 index 000000000000..d5b139111d0f --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ + +#include + +#if !defined(_ASMLANGUAGE) + +#include + +#define VPR_CPU DT_INST(0, nordic_vpr) + +#if DT_PROP(VPR_CPU, nordic_bus_width) == 64 + +#define SOC_ISR_STACKING_ESF_DECLARE \ + struct __esf { \ + unsigned long s0; \ + unsigned long mstatus; \ + unsigned long tp; \ + struct soc_esf soc_context; \ + \ + unsigned long t2; \ + unsigned long ra; \ + unsigned long t0; \ + unsigned long t1; \ + unsigned long a4; \ + unsigned long a5; \ + unsigned long a2; \ + unsigned long a3; \ + unsigned long a0; \ + unsigned long a1; \ + unsigned long mepc; \ + unsigned long _mcause; \ + } __aligned(16); + +#else /* DT_PROP(VPR_CPU, nordic_bus_width) == 32 */ + +#define SOC_ISR_STACKING_ESF_DECLARE \ + struct __esf { \ + unsigned long s0; \ + unsigned long mstatus; \ + unsigned long tp; \ + struct soc_esf soc_context; \ + \ + unsigned long ra; \ + unsigned long t2; \ + unsigned long t1; \ + unsigned long t0; \ + unsigned long a5; \ + unsigned long a4; \ + unsigned long a3; \ + unsigned long a2; \ + unsigned long a1; \ + unsigned long a0; \ + unsigned long mepc; \ + unsigned long _mcause; \ + } __aligned(16); + +#endif /* DT_PROP(VPR_CPU, nordic_bus_width) == 64 */ + +#else /* _ASMLANGUAGE */ + +/* + * Size of the HW managed part of the ESF: + * sizeof(_mcause) + sizeof(_mepc) + */ +#define ESF_HW_SIZEOF (0x8) + +/* + * Size of the SW managed part of the ESF in case of exception + */ +#define ESF_SW_EXC_SIZEOF (__z_arch_esf_t_SIZEOF - ESF_HW_SIZEOF) + +/* + * Size of the SW managed part of the ESF in case of interrupt + * sizeof(__padding) + ... + sizeof(soc_context) + */ +#define ESF_SW_IRQ_SIZEOF (0x10) + +#define SOC_ISR_SW_STACKING \ + csrw mscratch, t0; \ + \ + csrr t0, mcause; \ + srli t0, t0, RISCV_MCAUSE_IRQ_POS; \ + bnez t0, stacking_is_interrupt; \ + \ + csrrw t0, mscratch, zero; \ + \ + addi sp, sp, -ESF_SW_EXC_SIZEOF; \ + DO_CALLER_SAVED(sr); \ + j stacking_keep_going; \ + \ +stacking_is_interrupt: \ + addi sp, sp, -ESF_SW_IRQ_SIZEOF; \ + \ +stacking_keep_going: + +#define SOC_ISR_SW_UNSTACKING \ + csrr t0, mcause; \ + srli t0, t0, RISCV_MCAUSE_IRQ_POS; \ + bnez t0, unstacking_is_interrupt; \ + \ + DO_CALLER_SAVED(lr); \ + addi sp, sp, ESF_SW_EXC_SIZEOF; \ + j unstacking_keep_going; \ + \ +unstacking_is_interrupt: \ + addi sp, sp, ESF_SW_IRQ_SIZEOF; \ + \ +unstacking_keep_going: + +#endif /* _ASMLANGUAGE */ + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h b/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h new file mode 100644 index 000000000000..92d91044e1ad --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ + +#define GEN_SOC_OFFSET_SYMS() GEN_OFFSET_SYM(soc_esf_t, minttresh) + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/vector.S b/soc/riscv/nordic_nrf/common/vpr/vector.S new file mode 100644 index 000000000000..b8c6d97170c8 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/vector.S @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Imports */ +GTEXT(__initialize) + +/* Exports */ +GTEXT(__start) + +SECTION_FUNC(vectors, __start) + /* Set mtvec.base (mtvec.mode is RO, no need to mask it). */ + la t0, _isr_wrapper + csrw mtvec, t0 + + /* Set mtvt. */ + la t0, _irq_vector_table + csrw 0x307, t0 + + /* Enable mstatus.mie */ + li t0, 0x1888 + csrw mstatus, t0 + + /* Call into Zephyr initialization. */ + tail __initialize diff --git a/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt b/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt new file mode 100644 index 000000000000..5b37b3a54d89 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes +# for the image correctly +zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr new file mode 100644 index 000000000000..a36d24c72ae2 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPUPPR + +config SOC + default "nrf54h20_enga_cpuppr" + +config NUM_IRQS + default 496 + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +endif # SOC_NRF54H20_ENGA_CPUPPR diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series new file mode 100644 index 000000000000..0f827fbe96b2 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54HX + +rsource "Kconfig.defconfig.nrf54h*" + +config SOC_SERIES + default "nrf54h" + +DT_CHOSEN_Z_SRAM = zephyr,sram +DT_CHOSEN_Z_CODE = zephyr,code-partition + +config BUILD_OUTPUT_ADJUST_LMA + depends on !XIP + default "$(dt_chosen_partition_addr_hex,$(DT_CHOSEN_Z_CODE)) - \ + $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM))" + +endif # SOC_SERIES_NRF54HX diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.series b/soc/riscv/nordic_nrf/nrf54h/Kconfig.series new file mode 100644 index 000000000000..acb85b5623a6 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.series @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54HX + bool "Nordic Semiconductor nRF54H series MCU" + select SOC_FAMILY_NRF + select HAS_NRFX + select HAS_NORDIC_DRIVERS + help + Enable support for nRF54H MCU series diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc b/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc new file mode 100644 index 000000000000..17a6dd667c65 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF54H20 + bool "nRF54H20" + depends on SOC_SERIES_NRF54HX + +if SOC_NRF54H20 + +choice + prompt "nRF54Hx MCU Selection" + +config SOC_NRF54H20_ENGA_CPUPPR + bool "nRF54H20 ENGA CPUPPR" + select RISCV + +endchoice + +endif # SOC_NRF54H20 diff --git a/soc/riscv/nordic_nrf/nrf54h/align.ld b/soc/riscv/nordic_nrf/nrf54h/align.ld new file mode 100644 index 000000000000..0905aa7f7bcc --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/align.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.align16,,) +{ + . = (ALIGN(16) > 0 ? ALIGN(16) : 16) - 1; + BYTE(0); +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/riscv/openisa_rv32m1/Kconfig.defconfig b/soc/riscv/openisa_rv32m1/Kconfig.defconfig index 3976c9940c56..52d652a061e6 100644 --- a/soc/riscv/openisa_rv32m1/Kconfig.defconfig +++ b/soc/riscv/openisa_rv32m1/Kconfig.defconfig @@ -33,6 +33,9 @@ config RISCV_SOC_OFFSETS config RISCV_SOC_INTERRUPT_INIT default y +config RISCV_MCAUSE_EXCEPTION_MASK + default 0x1F + # We need to disable the watchdog out of reset, as it's enabled by # default. Use the WDOG_INIT hook for doing that. config WDOG_INIT diff --git a/soc/riscv/openisa_rv32m1/soc.h b/soc/riscv/openisa_rv32m1/soc.h index 1b2643d0b664..75011d362833 100644 --- a/soc/riscv/openisa_rv32m1/soc.h +++ b/soc/riscv/openisa_rv32m1/soc.h @@ -94,8 +94,6 @@ static inline uint32_t rv32m1_intmux_line(unsigned int irq) return ((irq >> 8) & 0xff) - 1; } -void soc_interrupt_init(void); - #endif /* !_ASMLANGUAGE */ #if defined(CONFIG_SOC_OPENISA_RV32M1_RI5CY) diff --git a/soc/riscv/openisa_rv32m1/soc_irq.S b/soc/riscv/openisa_rv32m1/soc_irq.S index 23222ea2c709..d3059d2bd280 100644 --- a/soc/riscv/openisa_rv32m1/soc_irq.S +++ b/soc/riscv/openisa_rv32m1/soc_irq.S @@ -10,22 +10,12 @@ #include /* Exports */ -GTEXT(__soc_is_irq) GTEXT(__soc_handle_irq) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE GTEXT(__soc_save_context) GTEXT(__soc_restore_context) #endif -/* - * Whether we're in an IRQ is bog-standard RISC-V on this SoC: - * yes if the top mcause bit is set, otherwise no. - */ -SECTION_FUNC(exception.other, __soc_is_irq) - csrr a0, mcause - srli a0, a0, 31 - ret - /* * With a0 == irq_num, this is equivalent to: * diff --git a/soc/riscv/openisa_rv32m1/soc_ri5cy.h b/soc/riscv/openisa_rv32m1/soc_ri5cy.h index 27ebcbe6f35c..d9158935e088 100644 --- a/soc/riscv/openisa_rv32m1/soc_ri5cy.h +++ b/soc/riscv/openisa_rv32m1/soc_ri5cy.h @@ -40,21 +40,4 @@ #define RI5CY_PRIVLV 0xC10 #define RI5CY_MHARTID 0xF14 -/* - * Map from SoC-specific configuration to generic Zephyr macros. - * - * These are expected by the code in arch/, and must be provided for - * the kernel to work (or even build at all). - * - * Some of these may also apply to ZERO-RISCY; needs investigation. - */ - -/* - * Exception code mask. Use of the bottom five bits is a subset of - * what the standard allocates (which is XLEN-1 bits). - */ -#define SOC_MCAUSE_EXP_MASK 0x1F - -/* The ecall exception number. This is a standard value. */ -#define SOC_MCAUSE_ECALL_EXP 11 #endif /* SOC_RISCV32_OPENISA_RV32M1_SOC_RI5CY_H_ */ diff --git a/soc/riscv/openisa_rv32m1/soc_zero_riscy.h b/soc/riscv/openisa_rv32m1/soc_zero_riscy.h index d5fa48297f76..43cd144823a0 100644 --- a/soc/riscv/openisa_rv32m1/soc_zero_riscy.h +++ b/soc/riscv/openisa_rv32m1/soc_zero_riscy.h @@ -28,22 +28,4 @@ #define ZERO_RISCY_PCMR 0x7A1U #define ZERO_RISCY_MHARTID 0xF14U -/* - * Map from SoC-specific configuration to generic Zephyr macros. - * - * These are expected by the code in arch/, and must be provided for - * the kernel to work (or even build at all). - * - * Some of these may also apply to ZERO-RISCY; needs investigation. - */ - -/* - * Exception code mask. Use of the bottom five bits is a subset of - * what the standard allocates (which is XLEN-1 bits). - */ -#define SOC_MCAUSE_EXP_MASK 0x1F - -/* The ecall exception number. This is a standard value. */ -#define SOC_MCAUSE_ECALL_EXP 11 - #endif /* SOC_RISCV32_OPENISA_RV32M1_SOC_ZERO_RISCY_H_ */ diff --git a/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt b/soc/riscv/opentitan/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/CMakeLists.txt rename to soc/riscv/opentitan/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series b/soc/riscv/opentitan/Kconfig.defconfig similarity index 68% rename from soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series rename to soc/riscv/opentitan/Kconfig.defconfig index c9e7f8396a0f..19a72fc70bda 100644 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series +++ b/soc/riscv/opentitan/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2023 Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_OPENTITAN +if SOC_OPENTITAN -config SOC_SERIES +config SOC default "opentitan" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -30,4 +24,4 @@ config 2ND_LVL_INTR_00_OFFSET config NUM_IRQS default 217 -endif # SOC_SERIES_RISCV_OPENTITAN +endif # SOC_OPENTITAN diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.soc b/soc/riscv/opentitan/Kconfig.soc similarity index 64% rename from soc/riscv/riscv-privileged/opentitan/Kconfig.soc rename to soc/riscv/opentitan/Kconfig.soc index 098b1844e52e..c76cfe013b18 100644 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.soc +++ b/soc/riscv/opentitan/Kconfig.soc @@ -1,11 +1,7 @@ # Copyright (c) 2023 Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -choice - prompt "OpenTitan implementation" - depends on SOC_SERIES_RISCV_OPENTITAN - -config SOC_RISCV_OPENTITAN +config SOC_OPENTITAN bool "OpenTitan implementation" select ATOMIC_OPERATIONS_C select INCLUDE_RESET_VECTOR @@ -18,5 +14,9 @@ config SOC_RISCV_OPENTITAN select RISCV_ISA_EXT_ZBB select RISCV_ISA_EXT_ZBC select RISCV_ISA_EXT_ZBS - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + # OpenTitan Ibex core mtvec mode is read-only / forced to vectored mode. + select RISCV_VECTORED_MODE + select GEN_IRQ_VECTOR_TABLE diff --git a/soc/riscv/riscv-privileged/opentitan/rom_header.S b/soc/riscv/opentitan/rom_header.S similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/rom_header.S rename to soc/riscv/opentitan/rom_header.S diff --git a/soc/riscv/riscv-privileged/opentitan/rom_header.ld b/soc/riscv/opentitan/rom_header.ld similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/rom_header.ld rename to soc/riscv/opentitan/rom_header.ld diff --git a/soc/riscv/riscv-privileged/opentitan/soc.c b/soc/riscv/opentitan/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/soc.c rename to soc/riscv/opentitan/soc.c diff --git a/soc/riscv/riscv-privileged/opentitan/soc.h b/soc/riscv/opentitan/soc.h similarity index 97% rename from soc/riscv/riscv-privileged/opentitan/soc.h rename to soc/riscv/opentitan/soc.h index 13bb5c43b54a..c7f75beb877c 100644 --- a/soc/riscv/riscv-privileged/opentitan/soc.h +++ b/soc/riscv/opentitan/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV_OPENTITAN_SOC_H_ #define __RISCV_OPENTITAN_SOC_H_ -#include #include /* OpenTitan power management regs. */ diff --git a/soc/riscv/renode_virt/CMakeLists.txt b/soc/riscv/renode_virt/CMakeLists.txt new file mode 100644 index 000000000000..56d36b84ec8b --- /dev/null +++ b/soc/riscv/renode_virt/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/renode_virt/Kconfig.defconfig b/soc/riscv/renode_virt/Kconfig.defconfig new file mode 100644 index 000000000000..fab597195950 --- /dev/null +++ b/soc/riscv/renode_virt/Kconfig.defconfig @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RISCV32_VIRTUAL_RENODE + +config SOC + default "renode_virt" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 4000000 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 1ST_LEVEL_INTERRUPT_BITS + default 4 + +config NUM_2ND_LEVEL_AGGREGATORS + default 2 + +config 2ND_LEVEL_INTERRUPT_BITS + default 11 + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config 2ND_LVL_INTR_01_OFFSET + default 4 + +config MAX_IRQ_PER_AGGREGATOR + default 1023 + +config NUM_IRQS + default 2058 + +endif # SOC_RISCV32_VIRTUAL_RENODE diff --git a/soc/riscv/renode_virt/Kconfig.soc b/soc/riscv/renode_virt/Kconfig.soc new file mode 100644 index 000000000000..ba42c40c28d1 --- /dev/null +++ b/soc/riscv/renode_virt/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RISCV32_VIRTUAL_RENODE + bool "Renode RISCV32 Virtual system implementation" + select RISCV + select RISCV_PRIVILEGED + select ATOMIC_OPERATIONS_BUILTIN + select INCLUDE_RESET_VECTOR + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select RISCV_HAS_PLIC diff --git a/soc/riscv/renode_virt/soc.h b/soc/riscv/renode_virt/soc.h new file mode 100644 index 000000000000..3edef49c88c4 --- /dev/null +++ b/soc/riscv/renode_virt/soc.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RISCV32_RENODE_SOC_H_ +#define __RISCV32_RENODE_SOC_H_ + +#endif /* __RISCV32_RENODE_SOC_H_ */ diff --git a/soc/riscv/riscv-ite/Kconfig b/soc/riscv/riscv-ite/Kconfig deleted file mode 100644 index f25c53d1ffb6..000000000000 --- a/soc/riscv/riscv-ite/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2020 ITE Corporation. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_FAMILY_RISCV_ITE - bool - help - omit prompt to signify a "hidden" option - -config SOC_FAMILY - string - default "riscv-ite" - depends on SOC_FAMILY_RISCV_ITE - -source "soc/riscv/riscv-ite/*/Kconfig.soc" diff --git a/soc/riscv/riscv-privileged/Kconfig b/soc/riscv/riscv-privileged/Kconfig deleted file mode 100644 index abbeeac242bc..000000000000 --- a/soc/riscv/riscv-privileged/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -# Configuration options for riscv SOCs supporting the riscv privileged -# architecture specification - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -config SOC_FAMILY_RISCV_PRIVILEGE - bool - select DEPRECATED - -config SOC_FAMILY_RISCV_PRIVILEGED - bool - select ARCH_HAS_RAMFUNC_SUPPORT if XIP - -config SOC_FAMILY - string - default "riscv-privileged" - depends on SOC_FAMILY_RISCV_PRIVILEGED - -config RISCV_HAS_PLIC - bool "Does the SOC provide support for a Platform Level Interrupt Controller (PLIC)" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Does the SOC provide support for a Platform Level Interrupt Controller (PLIC). - -config RISCV_HAS_CLIC - bool "Does the SOC provide support for a Core-Local Interrupt Controller (CLIC)" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Does the SOC provide support for a Core-Local Interrupt Controller (CLIC). - -config RISCV_VECTORED_MODE - bool "Should the SOC use vectored mode" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Should the SOC use vectored mode. - -source "soc/riscv/riscv-privileged/*/Kconfig.soc" diff --git a/soc/riscv/riscv-privileged/Kconfig.defconfig b/soc/riscv/riscv-privileged/Kconfig.defconfig deleted file mode 100644 index 6793d72a385b..000000000000 --- a/soc/riscv/riscv-privileged/Kconfig.defconfig +++ /dev/null @@ -1,6 +0,0 @@ -# riscv SOC family supporting the riscv privileged architecture spec - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -source "soc/riscv/riscv-privileged/*/Kconfig.defconfig.series" diff --git a/soc/riscv/riscv-privileged/Kconfig.soc b/soc/riscv/riscv-privileged/Kconfig.soc deleted file mode 100644 index 14d141223e0a..000000000000 --- a/soc/riscv/riscv-privileged/Kconfig.soc +++ /dev/null @@ -1,6 +0,0 @@ -# riscv SOC series supporting the riscv privileged architecture spec - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -source "soc/riscv/riscv-privileged/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.series b/soc/riscv/riscv-privileged/andes_v5/Kconfig.series deleted file mode 100644 index 9a99711b04c6..000000000000 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.series +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2021 Andes Technology Corporation -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_ANDES_V5 - bool "Andes V5 SoC Series Implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for Andes V5 SoC Series diff --git a/soc/riscv/riscv-privileged/common/idle.c b/soc/riscv/riscv-privileged/common/idle.c deleted file mode 100644 index e61ce72b2806..000000000000 --- a/soc/riscv/riscv-privileged/common/idle.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * Contributors: 2018 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include - -static ALWAYS_INLINE void riscv_idle(unsigned int key) -{ - sys_trace_idle(); - /* unlock interrupts */ - irq_unlock(key); - - /* Wait for interrupt */ - __asm__ volatile("wfi"); -} - -/** - * @brief Power save idle routine - * - * This function will be called by the kernel idle loop or possibly within - * an implementation of _pm_save_idle in the kernel when the - * '_pm_save_flag' variable is non-zero. - */ -void arch_cpu_idle(void) -{ - riscv_idle(MSTATUS_IEN); -} - -/** - * @brief Atomically re-enable interrupts and enter low power mode - * - * INTERNAL - * The requirements for arch_cpu_atomic_idle() are as follows: - * 1) The enablement of interrupts and entering a low-power mode needs to be - * atomic, i.e. there should be no period of time where interrupts are - * enabled before the processor enters a low-power mode. See the comments - * in k_lifo_get(), for example, of the race condition that - * occurs if this requirement is not met. - * - * 2) After waking up from the low-power mode, the interrupt lockout state - * must be restored as indicated in the 'imask' input parameter. - */ -void arch_cpu_atomic_idle(unsigned int key) -{ - riscv_idle(key); -} diff --git a/soc/riscv/riscv-privileged/common/soc_common.h b/soc/riscv/riscv-privileged/common/soc_common.h deleted file mode 100644 index 79f458924c6e..000000000000 --- a/soc/riscv/riscv-privileged/common/soc_common.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file configuration macros for riscv SOCs supporting the riscv - * privileged architecture specification - */ - -#ifndef __SOC_COMMON_H_ -#define __SOC_COMMON_H_ - -/* IRQ numbers */ -#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ -#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ - -/* ECALL Exception numbers */ -#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ -#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ - -/* SOC-specific MCAUSE bitfields */ -#ifdef CONFIG_64BIT -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 63) -#else -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 31) -#endif - -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK CONFIG_RISCV_SOC_MCAUSE_EXCEPTION_MASK - -#ifndef _ASMLANGUAGE - -#include -#include - -#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) -void soc_interrupt_init(void); -#endif - -#endif /* !_ASMLANGUAGE */ - -#endif /* __SOC_COMMON_H_ */ diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series b/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series deleted file mode 100644 index 8505cf1318a6..000000000000 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023 Efinix Inc. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_EFINIX_SAPPHIRE - bool "Efinix Sapphire SOC implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for Efinix Sapphire SOC implementation diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.soc b/soc/riscv/riscv-privileged/neorv32/Kconfig.soc deleted file mode 100644 index 93c9da8cc3d4..000000000000 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.soc +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2021 Henrik Brix Andersen -# SPDX-License-Identifier: Apache-2.0 - -choice - prompt "NEORV32 Version" - depends on SOC_SERIES_NEORV32 - -config SOC_NEORV32_V1_8_6 - bool "v1.8.6" - # NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO - select ATOMIC_OPERATIONS_C - -endchoice - -if SOC_SERIES_NEORV32 - -config SOC_NEORV32_VERSION - hex - default 0x01080600 if SOC_NEORV32_V1_8_6 - help - The targeted NEORV32 version as BCD-coded number. The format is - identical to that of the NEORV32 Machine implementation ID (mimpid) - register. - -config SOC_NEORV32_ISA_C - bool "RISC-V ISA Extension \"C\"" - select RISCV_ISA_EXT_C - help - Enable this if the NEORV32 CPU implementation supports the RISC-V ISA - "C" extension (Compressed Instructions). - -endif # SOC_SERIES_NEORV32 diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.series b/soc/riscv/riscv-privileged/opentitan/Kconfig.series deleted file mode 100644 index f8bbc2840fed..000000000000 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.series +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2023 Rivos Inc. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_OPENTITAN - bool "OpenTitan implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - # OpenTitan Ibex core mtvec mode is read-only / forced to vectored mode. - select RISCV_VECTORED_MODE - select GEN_IRQ_VECTOR_TABLE - help - Enable support for OpenTitan diff --git a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt b/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt deleted file mode 100644 index ff4cc56d7398..000000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_sources() -zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FREEDOM fe310_clock.c) -zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU540 fu540_clock.c) -zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU740 fu740_clock.c) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.series b/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.series deleted file mode 100644 index 523f6a4ffe97..000000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.series +++ /dev/null @@ -1,11 +0,0 @@ -# RISCV_SIFIVE_FREEDOM SOC implementation - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_SIFIVE_FREEDOM - bool "SiFive Freedom SOC implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for SiFive Freedom SOC diff --git a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc b/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc deleted file mode 100644 index 7840f8a09ba7..000000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc +++ /dev/null @@ -1,44 +0,0 @@ -# RISCV_SIFIVE_FREEDOM SOC configuration options - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -choice - prompt "SiFive Freedom SOC implementation" - depends on SOC_SERIES_RISCV_SIFIVE_FREEDOM - -config SOC_RISCV_SIFIVE_FREEDOM - bool "SiFive Freedom SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select RISCV_ISA_RV32I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -config SOC_RISCV_SIFIVE_FU540 - bool "SiFive Freedom U540 SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select 64BIT - select RISCV_ISA_RV64I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -config SOC_RISCV_SIFIVE_FU740 - bool "SiFive Freedom U740 SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select 64BIT - select RISCV_ISA_RV64I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -endchoice diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc b/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc deleted file mode 100644 index 3f4f96c332e5..000000000000 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2021 Telink Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -choice -prompt "CPU Architecture of SoC" -depends on SOC_SERIES_RISCV_TELINK_B91 - -config B91_CPU_RISCV32 - bool "RISCV32 CPU Architecture" - select RISCV_ISA_RV32I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -endchoice - -config TELINK_B91_HWDSP - bool "Support Hardware DSP" - select RISCV_SOC_CONTEXT_SAVE - depends on SOC_SERIES_RISCV_TELINK_B91 - -config TELINK_B91_PFT_ARCH - bool "Support performance throttling" - default y - select RISCV_SOC_CONTEXT_SAVE - depends on SOC_SERIES_RISCV_TELINK_B91 - -choice -prompt "Telink B91 SoC implementation" -depends on SOC_SERIES_RISCV_TELINK_B91 - -config SOC_RISCV_TELINK_B91 - bool "Telink B91 SoC implementation" - select ATOMIC_OPERATIONS_BUILTIN - select CPU_HAS_FPU - select INCLUDE_RESET_VECTOR - -endchoice diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.series b/soc/riscv/riscv-privileged/virt/Kconfig.series deleted file mode 100644 index e9846764f6ba..000000000000 --- a/soc/riscv/riscv-privileged/virt/Kconfig.series +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 Cobham Gaisler AB -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_VIRT - bool "QEMU RISC-V VirtIO Board" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED diff --git a/soc/riscv/sifive_freedom/CMakeLists.txt b/soc/riscv/sifive_freedom/CMakeLists.txt new file mode 100644 index 000000000000..6a5b10545ff1 --- /dev/null +++ b/soc/riscv/sifive_freedom/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/sifive_freedom/Kconfig b/soc/riscv/sifive_freedom/Kconfig new file mode 100644 index 000000000000..0fed11158afc --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_SIFIVE_FREEDOM + bool + +if SOC_FAMILY_SIFIVE_FREEDOM + +config SOC_FAMILY + string + default "sifive_freedom" + +source "soc/riscv/sifive_freedom/*/Kconfig.soc" + +endif # SOC_FAMILY_SIFIVE_FREEDOM diff --git a/soc/riscv/sifive_freedom/Kconfig.defconfig b/soc/riscv/sifive_freedom/Kconfig.defconfig new file mode 100644 index 000000000000..5adf8fc437e5 --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/sifive_freedom/*/Kconfig.defconfig.series" diff --git a/soc/riscv/sifive_freedom/Kconfig.soc b/soc/riscv/sifive_freedom/Kconfig.soc new file mode 100644 index 000000000000..54274defd919 --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/sifive_freedom/*/Kconfig.series" diff --git a/soc/riscv/sifive_freedom/common/CMakeLists.txt b/soc/riscv/sifive_freedom/common/CMakeLists.txt new file mode 100644 index 000000000000..f75aec6b3117 --- /dev/null +++ b/soc/riscv/sifive_freedom/common/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/riscv/riscv-privileged/sifive-freedom/pinctrl_soc.h b/soc/riscv/sifive_freedom/common/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/pinctrl_soc.h rename to soc/riscv/sifive_freedom/common/pinctrl_soc.h diff --git a/soc/riscv/sifive_freedom/e300/CMakeLists.txt b/soc/riscv/sifive_freedom/e300/CMakeLists.txt new file mode 100644 index 000000000000..baf01a6b0473 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 new file mode 100644 index 000000000000..cb0131f14270 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "e340" if SOC_SIFIVE_FREEDOM_E340 diff --git a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series similarity index 61% rename from soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series rename to soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series index 0c3cd5417734..eaa43e68e705 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series +++ b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series @@ -1,9 +1,10 @@ +# Copyright (c) 2017 Jean-Paul Etienne # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_SIFIVE_FREEDOM +if SOC_SERIES_SIFIVE_FREEDOM_E300 config SOC_SERIES - default "sifive-freedom" + default "e300" config SYS_CLOCK_HW_CYCLES_PER_SEC default 32768 @@ -11,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -32,4 +27,6 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 64 -endif # SOC_SERIES_RISCV_SIFIVE_FREEDOM +source "soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_E300 diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.series b/soc/riscv/sifive_freedom/e300/Kconfig.series new file mode 100644 index 000000000000..81634da000d4 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_E300 + bool "SiFive Freedom E300 SOC implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom FE300 SOC diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.soc b/soc/riscv/sifive_freedom/e300/Kconfig.soc new file mode 100644 index 000000000000..e53b84c08907 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.soc @@ -0,0 +1,20 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_E300 + +config SOC_SIFIVE_FREEDOM_E340 + bool "SiFive Freedom SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c b/soc/riscv/sifive_freedom/e300/clock.c similarity index 98% rename from soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c rename to soc/riscv/sifive_freedom/e300/clock.c index 0b642f3e8b22..8fde8121db95 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c +++ b/soc/riscv/sifive_freedom/e300/clock.c @@ -7,7 +7,7 @@ #include #include -#include "fe310_prci.h" +#include "prci.h" #define CORECLK_HZ (DT_PROP(DT_NODELABEL(coreclk), clock_frequency)) BUILD_ASSERT(DT_PROP(DT_NODELABEL(tlclk), clock_div) == 1, diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fe310_prci.h b/soc/riscv/sifive_freedom/e300/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fe310_prci.h rename to soc/riscv/sifive_freedom/e300/prci.h diff --git a/soc/riscv/riscv-privileged/sifive-freedom/soc.h b/soc/riscv/sifive_freedom/e300/soc.h similarity index 51% rename from soc/riscv/riscv-privileged/sifive-freedom/soc.h rename to soc/riscv/sifive_freedom/e300/soc.h index 958891a9d6a1..3c29efb2a713 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/soc.h +++ b/soc/riscv/sifive_freedom/e300/soc.h @@ -8,30 +8,15 @@ * @file SoC configuration macros for the SiFive Freedom processor */ -#ifndef __RISCV_SIFIVE_FREEDOM_SOC_H_ -#define __RISCV_SIFIVE_FREEDOM_SOC_H_ +#ifndef __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ -#include - -#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM) /* PINMUX MAX PINS */ #define SIFIVE_PINMUX_PINS 32 /* Clock controller. */ #define PRCI_BASE_ADDR 0x10008000 -#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540) || defined(CONFIG_SOC_RISCV_SIFIVE_FU740) - -/* Clock controller. */ -#define PRCI_BASE_ADDR 0x10000000 - -/* PINMUX MAX PINS */ -#define SIFIVE_PINMUX_PINS 16 - -#endif - -#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM) || defined(CONFIG_SOC_RISCV_SIFIVE_FU540) - /* * On FE310 and FU540, peripherals such as SPI, UART, I2C and PWM are clocked * by TLCLK, which is derived from CORECLK. @@ -42,12 +27,4 @@ #define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ (SIFIVE_TLCLK_BASE_FREQUENCY / SIFIVE_TLCLK_DIVIDER) -#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU740) - -/* On FU740, peripherals are clocked by PCLK. */ -#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ - DT_PROP(DT_NODELABEL(pclk), clock_frequency) - -#endif - -#endif /* __RISCV_SIFIVE_FREEDOM_SOC_H_ */ +#endif /* __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ */ diff --git a/soc/riscv/sifive_freedom/u500/CMakeLists.txt b/soc/riscv/sifive_freedom/u500/CMakeLists.txt new file mode 100644 index 000000000000..baf01a6b0473 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series new file mode 100644 index 000000000000..d306b60252a7 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series @@ -0,0 +1,32 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SIFIVE_FREEDOM_U500 + +config SOC_SERIES + default "u500" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config MAX_IRQ_PER_AGGREGATOR + default 52 + +config NUM_IRQS + default 64 + +source "soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_U500 diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 new file mode 100644 index 000000000000..f559f5914b3f --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "u540" if SOC_SIFIVE_FREEDOM_U540 diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.series b/soc/riscv/sifive_freedom/u500/Kconfig.series new file mode 100644 index 000000000000..7335a1a52936 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_U500 + bool "SiFive Freedom U500 SOC implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom U500 SOC diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.soc b/soc/riscv/sifive_freedom/u500/Kconfig.soc new file mode 100644 index 000000000000..0a88ccf8cc1f --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.soc @@ -0,0 +1,22 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_U500 + +config SOC_SIFIVE_FREEDOM_U540 + bool "SiFive Freedom U540 SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select 64BIT + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c b/soc/riscv/sifive_freedom/u500/clock.c similarity index 97% rename from soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c rename to soc/riscv/sifive_freedom/u500/clock.c index bc68a502f598..87929892f77d 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c +++ b/soc/riscv/sifive_freedom/u500/clock.c @@ -7,7 +7,7 @@ #include #include #include -#include "fu540_prci.h" +#include "prci.h" BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), "Unsupported CORECLK frequency"); diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu540_prci.h b/soc/riscv/sifive_freedom/u500/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fu540_prci.h rename to soc/riscv/sifive_freedom/u500/prci.h diff --git a/soc/riscv/sifive_freedom/u500/soc.h b/soc/riscv/sifive_freedom/u500/soc.h new file mode 100644 index 000000000000..1e18850787b6 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/soc.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the SiFive Freedom processor + */ + +#ifndef __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ + +/* Clock controller. */ +#define PRCI_BASE_ADDR 0x10000000 + +/* PINMUX MAX PINS */ +#define SIFIVE_PINMUX_PINS 16 + +/* + * On FE310 and FU540, peripherals such as SPI, UART, I2C and PWM are clocked + * by TLCLK, which is derived from CORECLK. + */ +#define SIFIVE_TLCLK_BASE_FREQUENCY \ + DT_PROP_BY_PHANDLE_IDX(DT_NODELABEL(tlclk), clocks, 0, clock_frequency) +#define SIFIVE_TLCLK_DIVIDER DT_PROP(DT_NODELABEL(tlclk), clock_div) +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + (SIFIVE_TLCLK_BASE_FREQUENCY / SIFIVE_TLCLK_DIVIDER) + +#endif /* __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ */ diff --git a/soc/riscv/sifive_freedom/u700/CMakeLists.txt b/soc/riscv/sifive_freedom/u700/CMakeLists.txt new file mode 100644 index 000000000000..baf01a6b0473 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series new file mode 100644 index 000000000000..a0e730d608f8 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series @@ -0,0 +1,32 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SIFIVE_FREEDOM_U700 + +config SOC_SERIES + default "u700" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config MAX_IRQ_PER_AGGREGATOR + default 52 + +config NUM_IRQS + default 64 + +source "soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_U700 diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 new file mode 100644 index 000000000000..ca935f772eb0 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "u740" if SOC_SIFIVE_FREEDOM_U740 diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.series b/soc/riscv/sifive_freedom/u700/Kconfig.series new file mode 100644 index 000000000000..04bdc1fb9b2b --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_U700 + bool "SiFive Freedom SOC U700 implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom U700 SOC diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.soc b/soc/riscv/sifive_freedom/u700/Kconfig.soc new file mode 100644 index 000000000000..1eec9b4bb17a --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.soc @@ -0,0 +1,22 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_U700 + +config SOC_SIFIVE_FREEDOM_U740 + bool "SiFive Freedom U740 SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select 64BIT + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c b/soc/riscv/sifive_freedom/u700/clock.c similarity index 99% rename from soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c rename to soc/riscv/sifive_freedom/u700/clock.c index e6bbee93689f..5c3fa5673432 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c +++ b/soc/riscv/sifive_freedom/u700/clock.c @@ -8,7 +8,7 @@ #include #include -#include "fu740_prci.h" +#include "prci.h" BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), "Unsupported CORECLK frequency"); diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu740_prci.h b/soc/riscv/sifive_freedom/u700/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fu740_prci.h rename to soc/riscv/sifive_freedom/u700/prci.h diff --git a/soc/riscv/sifive_freedom/u700/soc.h b/soc/riscv/sifive_freedom/u700/soc.h new file mode 100644 index 000000000000..2f15ba3b1cbd --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/soc.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the SiFive Freedom processor + */ + +#ifndef __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ + +/* Clock controller. */ +#define PRCI_BASE_ADDR 0x10000000 + +/* PINMUX MAX PINS */ +#define SIFIVE_PINMUX_PINS 16 + +/* On FU740, peripherals are clocked by PCLK. */ +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + DT_PROP(DT_NODELABEL(pclk), clock_frequency) + +#endif /* __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ */ diff --git a/soc/riscv/starfive_jh71xx/CMakeLists.txt b/soc/riscv/starfive_jh71xx/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/starfive_jh71xx/Kconfig b/soc/riscv/starfive_jh71xx/Kconfig new file mode 100644 index 000000000000..65694c07eff7 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_STARFIVE_JH71XX + bool + +if SOC_FAMILY_STARFIVE_JH71XX + +config SOC_FAMILY + string + default "starfive_jh71xx" + +source "soc/riscv/starfive_jh71xx/*/Kconfig.soc" + +endif # SOC_FAMILY_STARFIVE_JH71XX diff --git a/soc/riscv/starfive_jh71xx/Kconfig.defconfig b/soc/riscv/starfive_jh71xx/Kconfig.defconfig new file mode 100644 index 000000000000..b399e38b3406 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/starfive_jh71xx/*/Kconfig.defconfig.series" diff --git a/soc/riscv/starfive_jh71xx/Kconfig.soc b/soc/riscv/starfive_jh71xx/Kconfig.soc new file mode 100644 index 000000000000..1ff54faa9701 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/starfive_jh71xx/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt b/soc/riscv/starfive_jh71xx/jh71xx/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt rename to soc/riscv/starfive_jh71xx/jh71xx/CMakeLists.txt diff --git a/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 new file mode 100644 index 000000000000..6f38d61dd4e5 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "jh7100" if SOC_JH7100 diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series similarity index 80% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series index c488c614b7d2..0f058cb6c252 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series @@ -4,7 +4,7 @@ if SOC_SERIES_STARFIVE_JH71XX config SOC_SERIES - default "starfive_jh71xx" + default "jh71xx" config SYS_CLOCK_HW_CYCLES_PER_SEC default 6250000 @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -30,4 +24,6 @@ config 2ND_LVL_INTR_00_OFFSET config NUM_IRQS default 139 +source "soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh71*" + endif diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series similarity index 83% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series index b360f78b77b4..f392a5d1f972 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series @@ -4,6 +4,7 @@ config SOC_SERIES_STARFIVE_JH71XX bool "Starfive JH71XX series" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Starfive JH71XX SoC Series. diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.soc b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.soc rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/soc.h b/soc/riscv/starfive_jh71xx/jh71xx/soc.h similarity index 86% rename from soc/riscv/riscv-privileged/starfive_jh71xx/soc.h rename to soc/riscv/starfive_jh71xx/jh71xx/soc.h index 796f07201d9d..df3559c96e3d 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/soc.h +++ b/soc/riscv/starfive_jh71xx/jh71xx/soc.h @@ -7,6 +7,4 @@ #ifndef __RISCV_VIRT_SOC_H_ #define __RISCV_VIRT_SOC_H_ -#include - #endif diff --git a/soc/riscv/telink_tlsr/CMakeLists.txt b/soc/riscv/telink_tlsr/CMakeLists.txt new file mode 100644 index 000000000000..69b2926358e5 --- /dev/null +++ b/soc/riscv/telink_tlsr/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/telink_tlsr/Kconfig b/soc/riscv/telink_tlsr/Kconfig new file mode 100644 index 000000000000..144751311ba9 --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_TELINK_TLSR + bool + +if SOC_FAMILY_TELINK_TLSR + +config SOC_FAMILY + string + default "telink_tlsr" + +source "soc/riscv/telink_tlsr/*/Kconfig.soc" + +endif # SOC_FAMILY_TELINK_TLSR diff --git a/soc/riscv/telink_tlsr/Kconfig.defconfig b/soc/riscv/telink_tlsr/Kconfig.defconfig new file mode 100644 index 000000000000..04a888381fa9 --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/telink_tlsr/*/Kconfig.defconfig.series" diff --git a/soc/riscv/telink_tlsr/Kconfig.soc b/soc/riscv/telink_tlsr/Kconfig.soc new file mode 100644 index 000000000000..db09c69d1f4e --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/telink_tlsr/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt b/soc/riscv/telink_tlsr/tlsr951x/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt rename to soc/riscv/telink_tlsr/tlsr951x/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series similarity index 77% rename from soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series rename to soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series index 986b62407505..2b72ad9960cc 100644 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series @@ -1,11 +1,11 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_TELINK_B91 +if SOC_SERIES_TELINK_TLSR951X config SOC_SERIES string - default "telink_b91" + default "tlsr951x" config SYS_CLOCK_HW_CYCLES_PER_SEC int @@ -15,14 +15,6 @@ config RISCV_SOC_INTERRUPT_INIT bool default y -config RISCV_HAS_CPU_IDLE - bool - default y - -config RISCV_HAS_PLIC - bool - default y - config RISCV_GP bool default y @@ -56,4 +48,6 @@ config 2ND_LVL_INTR_00_OFFSET config HAS_FLASH_LOAD_OFFSET default y if BOOTLOADER_MCUBOOT -endif # SOC_SERIES_RISCV_TELINK_B91 +source "soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr*" + +endif # SOC_SERIES_TELINK_TLSR951X diff --git a/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 new file mode 100644 index 000000000000..4ffdebdaf6b6 --- /dev/null +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "tlsr9518" if SOC_TELINK_TLSR9518 diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.series b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.series similarity index 52% rename from soc/riscv/riscv-privileged/telink_b91/Kconfig.series rename to soc/riscv/telink_tlsr/tlsr951x/Kconfig.series index a966dfe447bd..5d5fc3226e5b 100644 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.series +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.series @@ -1,8 +1,8 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV_TELINK_B91 - bool "Telink B91 SoC Implementation" +config SOC_SERIES_TELINK_TLSR951X + bool "Telink TLSR951X" select RISCV select RISCV_ISA_RV32I select RISCV_ISA_EXT_M @@ -10,7 +10,12 @@ config SOC_SERIES_RISCV_TELINK_B91 select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC select HAS_TELINK_DRIVERS + select ATOMIC_OPERATIONS_BUILTIN + select CPU_HAS_FPU + select INCLUDE_RESET_VECTOR + select SOC_FAMILY_TELINK_TLSR help - Enable support for Telink B91 SoC + Enable support for Telink TLSR951X diff --git a/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc new file mode 100644 index 000000000000..2abc12cc58c5 --- /dev/null +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Telink Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_TELINK_TLSR951X + +choice + prompt "Telink TLSR951X SoC implementation" + +config SOC_TELINK_TLSR9518 + bool "Telink TLSR9518" + +endchoice + +config TELINK_B91_HWDSP + bool "Support Hardware DSP" + select RISCV_SOC_CONTEXT_SAVE + +config TELINK_B91_PFT_ARCH + bool "Support performance throttling" + default y + select RISCV_SOC_CONTEXT_SAVE + +endif # SOC_SERIES_TELINK_TLSR951X diff --git a/soc/riscv/riscv-privileged/telink_b91/init.ld b/soc/riscv/telink_tlsr/tlsr951x/init.ld similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/init.ld rename to soc/riscv/telink_tlsr/tlsr951x/init.ld diff --git a/soc/riscv/riscv-privileged/telink_b91/linker.ld b/soc/riscv/telink_tlsr/tlsr951x/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/linker.ld rename to soc/riscv/telink_tlsr/tlsr951x/linker.ld diff --git a/soc/riscv/riscv-privileged/telink_b91/pinctrl_soc.h b/soc/riscv/telink_tlsr/tlsr951x/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/pinctrl_soc.h rename to soc/riscv/telink_tlsr/tlsr951x/pinctrl_soc.h diff --git a/soc/riscv/riscv-privileged/telink_b91/soc.c b/soc/riscv/telink_tlsr/tlsr951x/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc.c rename to soc/riscv/telink_tlsr/tlsr951x/soc.c diff --git a/soc/riscv/riscv-privileged/telink_b91/soc.h b/soc/riscv/telink_tlsr/tlsr951x/soc.h similarity index 88% rename from soc/riscv/riscv-privileged/telink_b91/soc.h rename to soc/riscv/telink_tlsr/tlsr951x/soc.h index a46b4c620c78..6acfd63dd02d 100644 --- a/soc/riscv/riscv-privileged/telink_b91/soc.h +++ b/soc/riscv/telink_tlsr/tlsr951x/soc.h @@ -7,6 +7,4 @@ #ifndef RISCV_TELINK_B91_SOC_H #define RISCV_TELINK_B91_SOC_H -#include - #endif /* RISCV_TELINK_B91_SOC_H */ diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_context.h b/soc/riscv/telink_tlsr/tlsr951x/soc_context.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_context.h rename to soc/riscv/telink_tlsr/tlsr951x/soc_context.h diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_irq.S b/soc/riscv/telink_tlsr/tlsr951x/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_irq.S rename to soc/riscv/telink_tlsr/tlsr951x/soc_irq.S diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_offsets.h b/soc/riscv/telink_tlsr/tlsr951x/soc_offsets.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_offsets.h rename to soc/riscv/telink_tlsr/tlsr951x/soc_offsets.h diff --git a/soc/riscv/riscv-privileged/telink_b91/start.S b/soc/riscv/telink_tlsr/tlsr951x/start.S similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/start.S rename to soc/riscv/telink_tlsr/tlsr951x/start.S diff --git a/soc/riscv/riscv-privileged/virt/CMakeLists.txt b/soc/riscv/virt/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/virt/CMakeLists.txt rename to soc/riscv/virt/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series b/soc/riscv/virt/Kconfig.defconfig similarity index 78% rename from soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series rename to soc/riscv/virt/Kconfig.defconfig index 231d4519d677..bed5ff8bec7b 100644 --- a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series +++ b/soc/riscv/virt/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2020 Cobham Gaisler AB # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_VIRT +if SOC_RISCV_VIRT -config SOC_SERIES +config SOC default "virt" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.soc b/soc/riscv/virt/Kconfig.soc similarity index 75% rename from soc/riscv/riscv-privileged/virt/Kconfig.soc rename to soc/riscv/virt/Kconfig.soc index 35a2853eb500..59e553a9d7bc 100644 --- a/soc/riscv/riscv-privileged/virt/Kconfig.soc +++ b/soc/riscv/virt/Kconfig.soc @@ -1,10 +1,6 @@ # Copyright (c) 2020 Cobham Gaisler AB # SPDX-License-Identifier: Apache-2.0 -choice - prompt "QEMU RISC-V VirtIO Board" - depends on SOC_SERIES_RISCV_VIRT - config SOC_RISCV_VIRT bool "QEMU RISC-V VirtIO Board" select ATOMIC_OPERATIONS_BUILTIN @@ -12,5 +8,6 @@ config SOC_RISCV_VIRT select RISCV_ISA_EXT_M select RISCV_ISA_EXT_A select RISCV_ISA_EXT_C - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC diff --git a/soc/riscv/riscv-privileged/virt/soc.c b/soc/riscv/virt/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/virt/soc.c rename to soc/riscv/virt/soc.c diff --git a/soc/riscv/riscv-privileged/virt/soc.h b/soc/riscv/virt/soc.h similarity index 73% rename from soc/riscv/riscv-privileged/virt/soc.h rename to soc/riscv/virt/soc.h index 8fd5e2108ce4..8aa4238010ce 100644 --- a/soc/riscv/riscv-privileged/virt/soc.h +++ b/soc/riscv/virt/soc.h @@ -7,9 +7,6 @@ #ifndef __RISCV_VIRT_SOC_H_ #define __RISCV_VIRT_SOC_H_ -#include - #define SIFIVE_SYSCON_TEST 0x00100000 -#define RISCV_MSIP_BASE 0x02000000 #endif diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index 54b3d77c0cbe..00b0408c454f 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -28,7 +28,7 @@ manifest: groups: - optional - name: psa-arch-tests - revision: 6a17330e0dfb5f319730f974d5b05f7b7f04757b + revision: 2cadb02a72eacda7042505dcbdd492371e8ce024 path: modules/tee/tf-m/psa-arch-tests remote: upstream groups: @@ -40,7 +40,7 @@ manifest: groups: - optional - name: tf-m-tests - revision: a878426da78fbd1486dfc29d6c6b82be4ee79e72 + revision: 08a3158f0623a4205608a52d880b17ae394e31d2 path: modules/tee/tf-m/tf-m-tests remote: upstream groups: diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index e02901cd9066..912846e4cda1 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -175,6 +175,14 @@ config BT_SCA_UPDATE depends on !BT_CTLR || BT_CTLR_SCA_UPDATE_SUPPORT help Enable support for Bluetooth 5.1 Sleep Clock Accuracy Update Procedure + +config BT_TRANSMIT_POWER_CONTROL + bool "LE Power Control" + depends on !BT_CTLR || BT_CTLR_LE_POWER_CONTROL_SUPPORT + help + Enable support for LE Power Control Request feature that is defined in the + Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.31. + endif # BT_CONN rsource "Kconfig.iso" diff --git a/subsys/bluetooth/Kconfig.logging b/subsys/bluetooth/Kconfig.logging index ec95ddad10eb..b6505f6e53ad 100644 --- a/subsys/bluetooth/Kconfig.logging +++ b/subsys/bluetooth/Kconfig.logging @@ -469,56 +469,56 @@ config BT_MESH_DEBUG_NET select DEPRECATED help Use this option to enable Network layer debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_RPL bool "[DEPRECATED] Replay protection list debug" select DEPRECATED help Use this option to enable Replay protection list debug logs - for the Bluetooth mesh functionality. + for the Bluetooth Mesh functionality. config BT_MESH_DEBUG_TRANS bool "[DEPRECATED] Transport layer debug" select DEPRECATED help Use this option to enable Transport layer debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_BEACON bool "[DEPRECATED] Beacon debug" select DEPRECATED help Use this option to enable Beacon-related debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_CRYPTO bool "[DEPRECATED] Crypto debug" select DEPRECATED help Use this option to enable cryptographic debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_KEYS bool "[DEPRECATED] Key management debug" select DEPRECATED help Use this option to enable key management debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROV bool "[DEPRECATED] Provisioning debug" select DEPRECATED help Use this option to enable Provisioning debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROVISIONER bool "[DEPRECATED] Provisioner debug" select DEPRECATED help Use this option to enable Provisioner debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROV_DEVICE bool "[DEPRECATED] Provisioning device debug" @@ -532,7 +532,7 @@ config BT_MESH_DEBUG_ACCESS select DEPRECATED help Use this option to enable Access layer and device composition - related debug logs for Bluetooth mesh. + related debug logs for Bluetooth Mesh. config BT_MESH_DEBUG_MODEL bool "[DEPRECATED] Foundation model debug" @@ -546,21 +546,21 @@ config BT_MESH_DEBUG_ADV select DEPRECATED help Use this option to enable advertising debug logs for - the Bluetooth mesh functionality. + the Bluetooth Mesh functionality. config BT_MESH_DEBUG_LOW_POWER bool "[DEPRECATED] Low Power debug" select DEPRECATED help Use this option to enable Low Power debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_FRIEND bool "[DEPRECATED] Friend debug" select DEPRECATED help Use this option to enable Friend debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROXY bool "[DEPRECATED] Proxy debug" @@ -588,7 +588,7 @@ config BT_MESH_DEBUG_CFG select DEPRECATED help Use this option to enable node configuration debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. endmenu # [DEPRECATED] Mesh @@ -1002,7 +1002,7 @@ legacy-debug-sym = BT_MESH_DEBUG_PROVISIONER module-str = "Provisioner" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" -module = BT_MESH_PROV_DEVICE +module = BT_MESH_PROVISIONEE legacy-debug-sym = BT_MESH_DEBUG_PROV_DEVICE module-str = "Provisioning device" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 116071d4c0f6..1709bc452d85 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -766,7 +766,8 @@ static void ascs_iso_recv(struct bt_iso_chan *chan, * host as HCI ISO data packets, which we should just ignore */ if ((info->flags & BT_ISO_FLAGS_VALID) != 0) { - LOG_ERR("iso %p not bound with ep", chan); + LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep", + net_buf_frags_len(buf), chan); } return; @@ -1820,11 +1821,7 @@ static int ase_stream_qos(struct bt_bap_stream *stream, struct bt_audio_codec_qo * we have the ISO <-> EP coupling completed (due to setting * the CIS ID in the QoS procedure). */ - if (ep->dir == BT_AUDIO_DIR_SINK) { - bt_audio_codec_cfg_to_iso_path(&ep->iso->rx.path, stream->codec_cfg); - } else { - bt_audio_codec_cfg_to_iso_path(&ep->iso->tx.path, stream->codec_cfg); - } + bt_bap_iso_configure_data_path(ep, stream->codec_cfg); ep->cig_id = cig_id; ep->cis_id = cis_id; diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 4d2134455b88..aa4bc08f7612 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -764,7 +764,7 @@ static int bt_bap_broadcast_sink_setup_stream(struct bt_bap_broadcast_sink *sink bt_bap_iso_bind_ep(iso, ep); bt_audio_codec_qos_to_iso_qos(iso->chan.qos->rx, &sink->codec_qos); - bt_audio_codec_cfg_to_iso_path(iso->chan.qos->rx->path, codec_cfg); + bt_bap_iso_configure_data_path(ep, codec_cfg); bt_bap_iso_unref(iso); diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 8978e2816cbc..33fd1f0e17d0 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -288,7 +288,7 @@ static int broadcast_source_setup_stream(uint8_t index, struct bt_bap_stream *st bt_bap_iso_bind_ep(iso, ep); bt_audio_codec_qos_to_iso_qos(iso->chan.qos->tx, qos); - bt_audio_codec_cfg_to_iso_path(iso->chan.qos->tx->path, codec_cfg); + bt_bap_iso_configure_data_path(ep, codec_cfg); #if defined(CONFIG_BT_ISO_TEST_PARAMS) iso->chan.qos->num_subevents = qos->num_subevents; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ @@ -878,7 +878,7 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, iso_qos = stream->ep->iso->chan.qos->tx; bt_bap_stream_attach(NULL, stream, stream->ep, codec_cfg); - bt_audio_codec_cfg_to_iso_path(iso_qos->path, codec_cfg); + bt_bap_iso_configure_data_path(stream->ep, codec_cfg); } } diff --git a/subsys/bluetooth/audio/bap_iso.c b/subsys/bluetooth/audio/bap_iso.c index cb68a8032f51..3fa2059ea94d 100644 --- a/subsys/bluetooth/audio/bap_iso.c +++ b/subsys/bluetooth/audio/bap_iso.c @@ -129,19 +129,12 @@ void bt_bap_iso_init(struct bt_bap_iso *iso, struct bt_iso_chan_ops *ops) iso->chan.ops = ops; iso->chan.qos = &iso->qos; - /* Setup points for both Tx and Rx + /* Setup the QoS for both Tx and Rx * This is due to the limitation in the ISO API where pointers like - * the `qos->tx` shall be initialized before the CIS is connected if - * ever want to use it for TX, and ditto for RX. They cannot be - * initialized after the CIS has been connected + * the `qos->tx` shall be initialized before the CIS is created */ iso->chan.qos->rx = &iso->rx.qos; - iso->chan.qos->rx->path = &iso->rx.path; - iso->chan.qos->rx->path->cc = iso->rx.cc; - iso->chan.qos->tx = &iso->tx.qos; - iso->chan.qos->tx->path = &iso->tx.path; - iso->chan.qos->tx->path->cc = iso->tx.cc; } static struct bt_bap_iso_dir *bap_iso_get_iso_dir(bool unicast_client, struct bt_bap_iso *iso, @@ -164,6 +157,43 @@ static struct bt_bap_iso_dir *bap_iso_get_iso_dir(bool unicast_client, struct bt } } +void bt_bap_iso_configure_data_path(struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg) +{ + struct bt_bap_iso *bap_iso = ep->iso; + struct bt_iso_chan_qos *qos = bap_iso->chan.qos; + const bool is_unicast_client = + IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && bt_bap_ep_is_unicast_client(ep); + struct bt_bap_iso_dir *iso_dir = bap_iso_get_iso_dir(is_unicast_client, bap_iso, ep->dir); + struct bt_iso_chan_path *path = &iso_dir->path; + + /* Setup the data path objects */ + if (iso_dir == &bap_iso->rx) { + qos->rx->path = path; + } else { + qos->tx->path = path; + } + + /* Configure the data path to either use the controller for transcoding, or set the path to + * be transparant to indicate that the transcoding happens somewhere else + */ + path->pid = codec_cfg->path_id; + + if (codec_cfg->ctlr_transcode) { + path->format = codec_cfg->id; + path->cid = codec_cfg->cid; + path->vid = codec_cfg->vid; + path->delay = 0; + path->cc_len = codec_cfg->data_len; + path->cc = codec_cfg->data; + } else { + path->format = BT_HCI_CODING_FORMAT_TRANSPARENT; + path->cid = 0; + path->vid = 0; + path->delay = 0; + path->cc_len = 0; + path->cc = NULL; + } +} static bool is_unicast_client_ep(struct bt_bap_ep *ep) { return IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && bt_bap_ep_is_unicast_client(ep); diff --git a/subsys/bluetooth/audio/bap_iso.h b/subsys/bluetooth/audio/bap_iso.h index d3b27f3823af..4384182d697f 100644 --- a/subsys/bluetooth/audio/bap_iso.h +++ b/subsys/bluetooth/audio/bap_iso.h @@ -41,6 +41,7 @@ void bt_bap_iso_foreach(bt_bap_iso_func_t func, void *user_data); struct bt_bap_iso *bt_bap_iso_find(bt_bap_iso_func_t func, void *user_data); void bt_bap_iso_init(struct bt_bap_iso *iso, struct bt_iso_chan_ops *ops); void bt_bap_iso_bind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep); +void bt_bap_iso_configure_data_path(struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg); void bt_bap_iso_unbind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep); struct bt_bap_ep *bt_bap_iso_get_ep(bool unicast_client, struct bt_bap_iso *iso, enum bt_audio_dir dir); diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 23e5bb8564b5..d6df9524e142 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -31,18 +31,6 @@ LOG_MODULE_REGISTER(bt_bap_stream, CONFIG_BT_BAP_STREAM_LOG_LEVEL); -void bt_audio_codec_cfg_to_iso_path(struct bt_iso_chan_path *path, - struct bt_audio_codec_cfg *codec_cfg) -{ - path->pid = codec_cfg->path_id; - path->format = codec_cfg->id; - path->cid = codec_cfg->cid; - path->vid = codec_cfg->vid; - path->delay = 0; /* TODO: Add to bt_audio_codec_cfg? Use presentation delay? */ - path->cc_len = codec_cfg->data_len; - path->cc = codec_cfg->data; -} - #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || \ defined(CONFIG_BT_BAP_BROADCAST_SINK) void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, diff --git a/subsys/bluetooth/audio/bap_stream.h b/subsys/bluetooth/audio/bap_stream.h index 67e8c0470dfd..d16cf2cfcc9d 100644 --- a/subsys/bluetooth/audio/bap_stream.h +++ b/subsys/bluetooth/audio/bap_stream.h @@ -17,8 +17,6 @@ void bt_bap_stream_reset(struct bt_bap_stream *stream); void bt_bap_stream_attach(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg); -void bt_audio_codec_cfg_to_iso_path(struct bt_iso_chan_path *path, - struct bt_audio_codec_cfg *codec_cfg); void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, const struct bt_audio_codec_qos *codec_qos); diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 933db93ec72d..369381297735 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -231,7 +231,8 @@ static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, * host as HCI ISO data packets, which we should just ignore */ if ((info->flags & BT_ISO_FLAGS_VALID) != 0) { - LOG_ERR("iso %p not bound with ep", chan); + LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep", + net_buf_frags_len(buf), chan); } return; @@ -774,17 +775,8 @@ static void unicast_client_ep_qos_state(struct bt_bap_ep *ep, struct net_buf_sim * we have the ISO <-> EP coupling completed (due to setting * the CIS ID in the QoS procedure). */ - if (ep->dir == BT_AUDIO_DIR_SOURCE) { - /* If the endpoint is a source, then we need to - * configure our RX parameters - */ - bt_audio_codec_cfg_to_iso_path(&ep->iso->rx.path, stream->codec_cfg); - } else { - /* If the endpoint is a sink, then we need to - * configure our TX parameters - */ - bt_audio_codec_cfg_to_iso_path(&ep->iso->tx.path, stream->codec_cfg); - } + + bt_bap_iso_configure_data_path(ep, stream->codec_cfg); } /* Notify upper layer */ diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index bf4aee75e48d..2fdc98694b19 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -33,6 +33,7 @@ config BT_BUF_ACL_TX_SIZE config BT_BUF_ACL_TX_COUNT int "Number of outgoing ACL data buffers" default 7 if BT_HCI_RAW + default 4 if BT_MESH_GATT default 3 range 1 255 help @@ -242,7 +243,7 @@ config BT_HCI_MESH_EXT bool "Mesh HCI Command support" depends on BT_BROADCASTER && BT_OBSERVER && !BT_LL_SW_SPLIT help - Enable support for the Bluetooth mesh HCI Commands. + Enable support for the Bluetooth Mesh HCI Commands. config BT_WAIT_NOP bool "Wait for \"NOP\" Command Complete event during init" diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 742534beff33..077c8e4f6f55 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -101,6 +101,9 @@ config BT_CTLR_READ_ISO_LINK_QUALITY_SUPPORT BT_CTLR_PERIPHERAL_ISO_SUPPORT bool +config BT_CTLR_LE_POWER_CONTROL_SUPPORT + bool + config BT_CTLR bool "Bluetooth Controller" help @@ -114,7 +117,8 @@ choice BT_LL_CHOICE Select the Bluetooth Link Layer to compile. config BT_LL_SW_SPLIT - bool "Software-based BLE Link Layer" + bool "Software-based BLE Link Layer [EXPERIMENTAL]" + select EXPERIMENTAL select ENTROPY_GENERATOR help Use Zephyr software BLE Link Layer ULL LLL split implementation. @@ -484,6 +488,14 @@ config BT_CTLR_CONN_RSSI help Enable connection RSSI measurement. +config BT_CTLR_LE_POWER_CONTROL + bool "LE Power Control Request Feature" + depends on BT_CTLR_LE_POWER_CONTROL_SUPPORT + default y if BT_TRANSMIT_POWER_CONTROL + help + Enable support for LE Power Control Request feature that is defined in the + Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.31. + endif # BT_CONN config BT_CTLR_FILTER_ACCEPT_LIST diff --git a/subsys/bluetooth/host/Kconfig.gatt b/subsys/bluetooth/host/Kconfig.gatt index 9209368f9438..a2364bbe5577 100644 --- a/subsys/bluetooth/host/Kconfig.gatt +++ b/subsys/bluetooth/host/Kconfig.gatt @@ -276,4 +276,13 @@ config DEVICE_NAME_GATT_WRITABLE_AUTHEN endif #BT_DEVICE_NAME_GATT_WRITABLE +config BT_GATT_AUTHORIZATION_CUSTOM + bool "Custom authorization of GATT operations [EXPERIMENTAL]" + select EXPERIMENTAL + help + This option allows the user to define application-specific + authorization logic for GATT operations that can be registered + with the bt_gatt_authorization_cb_register API. See the API + documentation for more details. + endmenu diff --git a/subsys/bluetooth/host/Kconfig.l2cap b/subsys/bluetooth/host/Kconfig.l2cap index acb948c425a0..f8d602acd57b 100644 --- a/subsys/bluetooth/host/Kconfig.l2cap +++ b/subsys/bluetooth/host/Kconfig.l2cap @@ -66,7 +66,7 @@ config BT_L2CAP_DYNAMIC_CHANNEL allowing the creation of dynamic L2CAP Channels. config BT_L2CAP_ECRED - bool "L2CAP Enhanced Credit Based Flow Control support" + bool "L2CAP Enhanced Credit Based Flow Control support [EXPERIMENTAL]" depends on BT_L2CAP_DYNAMIC_CHANNEL help This option enables support for LE Connection oriented Channels with diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 7134e6fa89a4..7a312d5e05c8 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -2064,7 +2064,7 @@ void bt_hci_le_per_adv_response_report(struct net_buf *buf) response = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response)); info.tx_power = response->tx_power; info.rssi = response->rssi; - info.cte_type = BIT(response->cte_type); + info.cte_type = bt_get_df_cte_type(response->cte_type); info.response_slot = response->response_slot; if (buf->len < response->data_length) { @@ -2185,11 +2185,10 @@ void bt_hci_le_adv_set_terminated(struct net_buf *buf) if (evt->status && IS_ENABLED(CONFIG_BT_PERIPHERAL) && atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) { - /* Only set status for legacy advertising API. - * This will call connected callback for high duty cycle + /* This will call connected callback for high duty cycle * directed advertiser timeout. */ - le_adv_stop_free_conn(adv, adv == bt_dev.adv ? evt->status : 0); + le_adv_stop_free_conn(adv, evt->status); } if (IS_ENABLED(CONFIG_BT_CONN) && !evt->status) { diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 130b4ab0853a..44862f5bf255 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -115,6 +115,11 @@ static uint16_t bt_att_mtu(struct bt_att_chan *chan) return MIN(chan->chan.rx.mtu, chan->chan.tx.mtu); } +/* Descriptor of application-specific authorization callbacks that are used + * with the CONFIG_BT_GATT_AUTHORIZATION_CUSTOM Kconfig enabled. + */ +const static struct bt_gatt_authorization_cb *authorization_cb; + /* ATT connection specific data */ struct bt_att { struct bt_conn *conn; @@ -1289,6 +1294,20 @@ struct read_type_data { typedef bool (*attr_read_cb)(struct net_buf *buf, ssize_t read, void *user_data); +static bool attr_read_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return true; + } + + if (!authorization_cb || !authorization_cb->read_operation_authorize) { + return true; + } + + return authorization_cb->read_operation_authorize(conn, attr); +} + static bool attr_read_type_cb(struct net_buf *frag, ssize_t read, void *user_data) { @@ -1398,6 +1417,12 @@ static uint8_t read_type_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* * If any attribute is founded in handle range it means that error * should be changed from pre-set: attr not found error to no error. @@ -1526,6 +1551,12 @@ static uint8_t read_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Read attribute value and store in the buffer */ ret = att_chan_read(chan, attr, data->buf, data->offset, NULL, NULL); if (ret < 0) { @@ -1693,6 +1724,12 @@ static uint8_t read_vl_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* The Length Value Tuple List may be truncated within the first two * octets of a tuple due to the size limits of the current ATT_MTU. */ @@ -1940,6 +1977,20 @@ struct write_data { uint8_t err; }; +static bool attr_write_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return true; + } + + if (!authorization_cb || !authorization_cb->write_operation_authorize) { + return true; + } + + return authorization_cb->write_operation_authorize(conn, attr); +} + static uint8_t write_cb(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) { @@ -1956,6 +2007,12 @@ static uint8_t write_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_write_authorize(data->conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Set command flag if not a request */ if (!data->req) { flags |= BT_GATT_WRITE_FLAG_CMD; @@ -2069,6 +2126,12 @@ static uint8_t prep_write_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_write_authorize(data->conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Check if attribute requires handler to accept the data */ if (!(attr->perm & BT_GATT_PERM_PREPARE_WRITE)) { goto append; @@ -3997,3 +4060,23 @@ bool bt_att_chan_opt_valid(struct bt_conn *conn, enum bt_att_chan_opt chan_opt) return true; } + +int bt_gatt_authorization_cb_register(const struct bt_gatt_authorization_cb *cb) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return -ENOSYS; + } + + if (!cb) { + authorization_cb = NULL; + return 0; + } + + if (authorization_cb) { + return -EALREADY; + } + + authorization_cb = cb; + + return 0; +} diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 1fd2f5fbc492..06a3e7553a27 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2619,16 +2619,116 @@ static int bt_conn_get_tx_power_level(struct bt_conn *conn, uint8_t type, return 0; } +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void notify_tx_power_report(struct bt_conn *conn, + struct bt_conn_le_tx_power_report report) +{ + for (struct bt_conn_cb *cb = callback_list; cb; cb = cb->_next) { + if (cb->tx_power_report) { + cb->tx_power_report(conn, &report); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) + { + if (cb->tx_power_report) { + cb->tx_power_report(conn, &report); + } + } +} + +int bt_conn_le_enhanced_get_tx_power_level(struct bt_conn *conn, + struct bt_conn_le_tx_power *tx_power) +{ + int err; + struct bt_hci_rp_le_read_tx_power_level *rp; + struct net_buf *rsp; + struct bt_hci_cp_le_read_tx_power_level *cp; + struct net_buf *buf; + + if (!tx_power->phy) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->phy = tx_power->phy; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL, buf, &rsp); + if (err) { + return err; + } + + rp = (void *) rsp->data; + tx_power->phy = rp->phy; + tx_power->current_level = rp->current_tx_power_level; + tx_power->max_level = rp->max_tx_power_level; + net_buf_unref(rsp); + + return 0; +} + +int bt_conn_le_get_remote_tx_power_level(struct bt_conn *conn, + enum bt_conn_le_tx_power_phy phy) +{ + struct bt_hci_cp_le_read_tx_power_level *cp; + struct net_buf *buf; + + if (!phy) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->phy = phy; + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL, buf, NULL); +} + +int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, + bool local_enable, + bool remote_enable) +{ + struct bt_hci_cp_le_set_tx_power_report_enable *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->local_enable = local_enable ? BT_HCI_LE_TX_POWER_REPORT_ENABLE : + BT_HCI_LE_TX_POWER_REPORT_DISABLE; + cp->remote_enable = remote_enable ? BT_HCI_LE_TX_POWER_REPORT_ENABLE : + BT_HCI_LE_TX_POWER_REPORT_DISABLE; + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE, buf, NULL); +} +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + int bt_conn_le_get_tx_power_level(struct bt_conn *conn, struct bt_conn_le_tx_power *tx_power_level) { int err; if (tx_power_level->phy != 0) { - /* Extend the implementation when LE Enhanced Read Transmit - * Power Level HCI command is available for use. - */ - return -ENOTSUP; + if (IS_ENABLED(CONFIG_BT_TRANSMIT_POWER_CONTROL)) { + return bt_conn_le_enhanced_get_tx_power_level(conn, tx_power_level); + } else { + return -ENOTSUP; + } } err = bt_conn_get_tx_power_level(conn, BT_TX_POWER_LEVEL_CURRENT, diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 7741e259a618..a13adff704a0 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -364,6 +364,9 @@ void notify_le_phy_updated(struct bt_conn *conn); bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); +void notify_tx_power_report(struct bt_conn *conn, + struct bt_conn_le_tx_power_report report); + #if defined(CONFIG_BT_SMP) /* If role specific LTK is present */ bool bt_conn_ltk_present(const struct bt_conn *conn); diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index de4fb637b492..ee1c822d9f98 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -422,6 +422,22 @@ uint8_t bt_get_phy(uint8_t hci_phy) } } +int bt_get_df_cte_type(uint8_t hci_cte_type) +{ + switch (hci_cte_type) { + case BT_HCI_LE_AOA_CTE: + return BT_DF_CTE_TYPE_AOA; + case BT_HCI_LE_AOD_CTE_1US: + return BT_DF_CTE_TYPE_AOD_1US; + case BT_HCI_LE_AOD_CTE_2US: + return BT_DF_CTE_TYPE_AOD_2US; + case BT_HCI_LE_NO_CTE: + return BT_DF_CTE_TYPE_NONE; + default: + return BT_DF_CTE_TYPE_NONE; + } +} + #if defined(CONFIG_BT_CONN_TX) static void hci_num_completed_packets(struct net_buf *buf) { @@ -2399,6 +2415,33 @@ int bt_hci_register_vnd_evt_cb(bt_hci_vnd_evt_cb_t cb) } #endif /* CONFIG_BT_HCI_VS_EVT_USER */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void bt_hci_le_transmit_power_report(struct net_buf *buf) +{ + struct bt_hci_evt_le_transmit_power_report *evt; + struct bt_conn_le_tx_power_report report; + struct bt_conn *conn; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE); + if (!conn) { + LOG_ERR("Unknown conn handle 0x%04X for transmit power report", + sys_le16_to_cpu(evt->handle)); + return; + } + + report.reason = evt->reason; + report.phy = evt->phy; + report.tx_power_level = evt->tx_power_level; + report.tx_power_level_flag = evt->tx_power_level_flag; + report.delta = evt->delta; + + notify_tx_power_report(conn, report); + + bt_conn_unref(conn); +} +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + static const struct event_handler vs_events[] = { #if defined(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES) EVENT_HANDLER(BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT, @@ -2544,6 +2587,10 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + EVENT_HANDLER(BT_HCI_EVT_LE_TRANSMIT_POWER_REPORT, bt_hci_le_transmit_power_report, + sizeof(struct bt_hci_evt_le_transmit_power_report)), +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ #if defined(CONFIG_BT_PER_ADV_SYNC_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2, sizeof(struct bt_hci_evt_le_per_advertising_report_v2)), @@ -3089,6 +3136,9 @@ static int le_set_event_mask(void) BT_FEAT_LE_PHY_CODED(bt_dev.le.features))) { mask |= BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE; } + if (IS_ENABLED(CONFIG_BT_TRANSMIT_POWER_CONTROL)) { + mask |= BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING; + } } if (IS_ENABLED(CONFIG_BT_SMP) && diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index ce4fc5a9b63e..1a3c06414a02 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -434,7 +434,14 @@ int bt_le_set_data_len(struct bt_conn *conn, uint16_t tx_octets, uint16_t tx_tim int bt_le_set_phy(struct bt_conn *conn, uint8_t all_phys, uint8_t pref_tx_phy, uint8_t pref_rx_phy, uint8_t phy_opts); uint8_t bt_get_phy(uint8_t hci_phy); - +/** + * @brief Convert CTE type value from HCI format to @ref bt_df_cte_type format. + * + * @param hci_cte_type CTE type in an HCI format. + * + * @return CTE type (@ref bt_df_cte_type). + */ +int bt_get_df_cte_type(uint8_t hci_cte_type); int bt_le_scan_update(bool fast_scan); int bt_le_create_conn(const struct bt_conn *conn); diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 42e9c877a9aa..05b5cc2f613f 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -233,9 +233,10 @@ static int hci_le_setup_iso_data_path(const struct bt_conn *iso, uint8_t dir, cp->codec_id.vs_codec_id = sys_cpu_to_le16(path->vid); sys_put_le24(path->delay, cp->controller_delay); cp->codec_config_len = path->cc_len; - cc = net_buf_add(buf, cp->codec_config_len); - memcpy(cc, path->cc, cp->codec_config_len); - + cc = net_buf_add(buf, path->cc_len); + if (path->cc_len) { + memcpy(cc, path->cc, path->cc_len); + } err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SETUP_ISO_PATH, buf, &rsp); if (err) { return err; @@ -1117,7 +1118,8 @@ void hci_le_cis_established(struct net_buf *buf) bt_conn_set_state(iso, BT_CONN_CONNECTED); bt_conn_unref(iso); return; - } else if (evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) { + } else if (iso->role == BT_HCI_ROLE_PERIPHERAL || + evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) { iso->err = evt->status; bt_iso_disconnected(iso); } /* else we wait for disconnect event */ diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index e6fbe2144f85..b8faa1efcaee 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -977,7 +977,9 @@ static void l2cap_chan_destroy(struct bt_l2cap_chan *chan) * In the case where we are in the context of executing the rtx_work * item, we don't sync as it will deadlock the workqueue. */ - if (k_current_get() != &le_chan->rtx_work.queue->thread) { + struct k_work_q *rtx_work_queue = le_chan->rtx_work.queue; + + if (rtx_work_queue == NULL || k_current_get() != &rtx_work_queue->thread) { k_work_cancel_delayable_sync(&le_chan->rtx_work, &le_chan->rtx_sync); } else { k_work_cancel_delayable(&le_chan->rtx_work); diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index e9a10ff8d72a..3a33ff293c60 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -165,7 +165,9 @@ static void l2cap_br_chan_destroy(struct bt_l2cap_chan *chan) * In the case where we are in the context of executing the rtx_work * item, we don't sync as it will deadlock the workqueue. */ - if (k_current_get() != &br_chan->rtx_work.queue->thread) { + struct k_work_q *rtx_work_queue = br_chan->rtx_work.queue; + + if (rtx_work_queue == NULL || k_current_get() != &rtx_work_queue->thread) { k_work_cancel_delayable_sync(&br_chan->rtx_work, &br_chan->rtx_sync); } else { k_work_cancel_delayable(&br_chan->rtx_work); diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 168d7f6ead38..0b61305e2c30 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -825,7 +825,7 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) info.tx_power = evt->tx_power; info.rssi = evt->rssi; - info.cte_type = BIT(evt->cte_type); + info.cte_type = bt_get_df_cte_type(evt->cte_type); info.addr = &per_adv_sync->addr; info.sid = per_adv_sync->sid; diff --git a/subsys/bluetooth/mesh/CMakeLists.txt b/subsys/bluetooth/mesh/CMakeLists.txt index 10b142e87f59..4c597c12a687 100644 --- a/subsys/bluetooth/mesh/CMakeLists.txt +++ b/subsys/bluetooth/mesh/CMakeLists.txt @@ -40,7 +40,7 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_FRIEND friend.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROV prov.c) -zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROV_DEVICE prov_device.c) +zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROVISIONEE provisionee.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROVISIONER provisioner.c) @@ -122,6 +122,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_STATISTIC statistic.c) +zephyr_library_sources_ifdef(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG delayable_msg.c) + if (CONFIG_BT_MESH_USES_TINYCRYPT) zephyr_library_sources(crypto_tc.c) else() @@ -132,6 +134,6 @@ zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) if (CONFIG_BUILD_WITH_TFM) target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index de409e9c53cb..555aac45bc0b 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1,13 +1,13 @@ -# Bluetooth mesh configuration options +# Bluetooth Mesh configuration options # Copyright (c) 2017 Intel Corporation # SPDX-License-Identifier: Apache-2.0 menuconfig BT_MESH - bool "Bluetooth mesh support" + bool "Bluetooth Mesh support" depends on BT_OBSERVER && BT_BROADCASTER help - This option enables Bluetooth mesh support. The specific + This option enables Bluetooth Mesh support. The specific features that are available may depend on other features that have been enabled in the stack, such as GATT support. @@ -240,7 +240,7 @@ config BT_MESH_PB_GATT select BT_MESH_GATT_SERVER select BT_MESH_PROV select BT_MESH_PB_GATT_COMMON - select BT_MESH_PROV_DEVICE + select BT_MESH_PROVISIONEE help Enable this option to allow the device to be provisioned over GATT. @@ -268,7 +268,16 @@ config BT_MESH_PB_GATT_CLIENT endif # BT_CONN config BT_MESH_PROV_DEVICE - bool "Provisioning device role support" + bool "[DEPRECATED] Provisioning device role support" + select DEPRECATED + select BT_MESH_PROVISIONEE + help + Enable this option to allow the device to be provisioned into a mesh network. + The option is marked as deprecated and will be replaced by BT_MESH_PROVISIONEE + option. + +config BT_MESH_PROVISIONEE + bool "Provisionee role support" depends on BT_MESH_PB_ADV || BT_MESH_PB_GATT default y help @@ -276,7 +285,7 @@ config BT_MESH_PROV_DEVICE config BT_MESH_PROV_OOB_PUBLIC_KEY bool "OOB Public key support" - depends on BT_MESH_PROV_DEVICE + depends on BT_MESH_PROVISIONEE help Enable this option if public key is to be exchanged via Out of Band (OOB) technology. @@ -598,7 +607,7 @@ config BT_MESH_ACCESS_LAYER_MSG help This option allows the application to directly access Bluetooth access layer messages without the need to - instantiate Bluetooth mesh models. + instantiate Bluetooth Mesh models. config BT_MESH_MODEL_VND_MSG_CID_FORCE bool "Force vendor model to use the corresponding CID field message" @@ -628,6 +637,61 @@ config BT_MESH_LABEL_NO_RECOVER unprovisioned before upgrading to the version with this option). The option is marked as deprecated to remove the recovery code eventually. +menuconfig BT_MESH_ACCESS_DELAYABLE_MSG + bool "Access layer tx delayable message" + default y + help + Enable following of the message transmitting recommendations, the Access layer + specification. The recommendations are optional. + However, they are strictly recommended if the device participates in the network with + intensive communication where the device receives a lot of requests that require responses. + +if BT_MESH_ACCESS_DELAYABLE_MSG + +config BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED + bool "The delayable message in the notification message context" + default y + help + Controls whether the delayable message feature is enabled by default in + the message context of the opcode notifications. This allows the server part of any + model to not bother about additional context configuration to enable the delayable message. + Note that if this is disabled then all foundation models stop using the delayable message + functionality. + +config BT_MESH_ACCESS_DELAYABLE_MSG_COUNT + int "Number of simultaneously delayed messages" + default 4 + help + The maximum number of messages the Access layer can manage to delay + at the same time. The number of messages can be handled only if the Access layer + has a sufficient amount of memory to store the model payload for them. + +config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE + int "Maximum delayable message storage chunk" + default 10 + help + Size of memory that Access layer uses to split model message to. It allocates + a sufficient number of these chunks from the pool to store the full model payload. + +config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT + int "Maximum number of available chunks" + default 40 + help + The maximum number of available chunks the Access layer allocates to store model payload. + It is recommended to keep chunk size equal to the reasonable small value to prevent + unnecessary memory wasting. + +endif # BT_MESH_ACCESS_DELAYABLE_MSG + +config BT_MESH_DELAYABLE_PUBLICATION + bool "Delayable publication" + default y + help + When enabled, the periodic publications are randomly delayed by 20 to 50ms. Publications + triggered at the start of the stack or by the bt_mesh_model_publish() call are delayed by + 20 to 500ms. This option reduces the probability of collisions when multiple nodes publish + at the same time. + endmenu # Access layer menu "Models" @@ -958,7 +1022,7 @@ config BT_MESH_LPN_INIT_POLL_TIMEOUT config BT_MESH_LPN_SCAN_LATENCY int "Latency for enabling scanning" range 0 50 - default 15 + default 2 help Latency in milliseconds that it takes to enable scanning. This is in practice how much time in advance before the Receive Window @@ -1049,9 +1113,9 @@ config BT_MESH_FRIEND_ADV_LATENCY endif # BT_MESH_FRIEND menuconfig BT_MESH_V1d1 - bool "Bluetooth mesh v1.1 support" + bool "Bluetooth Mesh v1.1 support" help - This option enables Bluetooth mesh v1.1 support. Bluetooth mesh v1.1 + This option enables Bluetooth Mesh v1.1 support. Bluetooth Mesh v1.1 is backward compatible with v1.0.1. config BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM @@ -1201,7 +1265,7 @@ config BT_MESH_DFU_METADATA bool "Support for the default metadata format" help This option adds a set of functions that can be used to encode and decode a firmware - metadata using the format defined in the Bluetooth mesh DFU subsystem. + metadata using the format defined in the Bluetooth Mesh DFU subsystem. config BT_MESH_DFU_URI_MAXLEN int "DFU URI max length" @@ -1734,16 +1798,16 @@ config BT_MESH_RPL_STORE_TIMEOUT endif # BT_MESH_RPL_STORAGE_MODE_SETTINGS && BT_SETTINGS config BT_MESH_SETTINGS_WORKQ - bool "Store the Bluetooth mesh settings in a separate work queue" + bool "Store the Bluetooth Mesh settings in a separate work queue" default y help This option enables a separate cooperative thread which is used to - store Bluetooth mesh configuration. When this option is disabled, + store Bluetooth Mesh configuration. When this option is disabled, the stack's configuration is stored in the system workqueue. This means that the system workqueue will be blocked for the time needed to store the pending data. This time may significantly increase if the flash driver does the erase operation. Enabling this option - allows Bluetooth mesh not to block the system workqueue, and thus + allows Bluetooth Mesh not to block the system workqueue, and thus process the incoming and outgoing messages while the flash driver waits for the controller to allocate the time needed to write the data and/or erase the required flash pages. diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index dcf7f0f783b9..23fbb8e82c2a 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -19,7 +19,6 @@ #include "host/testing.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "lpn.h" #include "transport.h" @@ -28,11 +27,17 @@ #include "op_agg.h" #include "settings.h" #include "va.h" +#include "delayable_msg.h" #define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_access); +/* 20 - 50ms */ +#define RANDOM_DELAY_SHORT 30 +/* 20 - 500ms */ +#define RANDOM_DELAY_LONG 480 + /* Model publication information for persistent storage. */ struct mod_pub_val { struct { @@ -761,8 +766,16 @@ static int32_t next_period(const struct bt_mesh_model *mod) if (period && elapsed >= period) { LOG_WRN("Retransmission interval is too short"); - /* Return smallest positive number since 0 means disabled */ - return 1; + + if (!!pub->delayable) { + LOG_WRN("Publication period is too short for" + " retransmissions"); + } + + /* Keep retransmitting the message with the interval sacrificing the + * next publication period start. + */ + return BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit); } } @@ -775,6 +788,11 @@ static int32_t next_period(const struct bt_mesh_model *mod) if (elapsed >= period) { LOG_WRN("Publication sending took longer than the period"); + + if (!!pub->delayable) { + LOG_WRN("Publication period is too short to be delayable"); + } + /* Return smallest positive number since 0 means disabled */ return 1; } @@ -855,6 +873,39 @@ static int pub_period_start(struct bt_mesh_model_pub *pub) return 0; } +static uint16_t pub_delay_get(int random_delay_window) +{ + if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) { + return 0; + } + + uint16_t num = 0; + + (void)bt_rand(&num, sizeof(num)); + + return 20 + (num % random_delay_window); +} + +static int pub_delay_schedule(struct bt_mesh_model_pub *pub, int delay) +{ + uint16_t random; + int err; + + if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) { + return -ENOTSUP; + } + + random = pub_delay_get(delay); + err = k_work_reschedule(&pub->timer, K_MSEC(random)); + if (err < 0) { + LOG_ERR("Unable to delay publication (err %d)", err); + return err; + } + + LOG_DBG("Publication delayed by %dms", random); + return 0; +} + static void mod_publish(struct k_work *work) { struct k_work_delayable *dwork = k_work_delayable_from_work(work); @@ -871,7 +922,7 @@ static void mod_publish(struct k_work *work) return; } - LOG_DBG("%u", k_uptime_get_32()); + LOG_DBG("timestamp: %u", k_uptime_get_32()); if (pub->count) { pub->count--; @@ -890,6 +941,13 @@ static void mod_publish(struct k_work *work) if (err) { return; } + + /* Delay the first publication in a period. */ + if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_SHORT)) { + /* Increment count as it would do BT_MESH_PUB_MSG_TOTAL */ + pub->count++; + return; + } } err = publish_transmit(pub->mod); @@ -1424,7 +1482,7 @@ static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple op = find_op(elem, opcode, &model); if (!op) { - LOG_ERR("No OpCode 0x%08x for elem 0x%02x", opcode, elem->rt->addr); + LOG_DBG("No OpCode 0x%08x for elem 0x%02x", opcode, elem->rt->addr); return ACCESS_STATUS_WRONG_OPCODE; } @@ -1446,6 +1504,10 @@ static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD; } + if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED)) { + ctx->rnd_delay = true; + } + net_buf_simple_save(buf, &state); err = op->func(model, ctx, buf); net_buf_simple_restore(buf, &state); @@ -1519,6 +1581,15 @@ int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx return -EINVAL; } +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + /* No sense to use delayable message for unicast loopback. */ + if (ctx->rnd_delay && + !(bt_mesh_has_addr(ctx->addr) && BT_MESH_ADDR_IS_UNICAST(ctx->addr))) { + return bt_mesh_delayable_msg_manage(ctx, msg, bt_mesh_model_elem(model)->rt->addr, + cb, cb_data); + } +#endif + return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->rt->addr, cb, cb_data); } @@ -1557,6 +1628,18 @@ int bt_mesh_model_publish(const struct bt_mesh_model *model) LOG_DBG("Publish Retransmit Count %u Interval %ums", pub->count, BT_MESH_PUB_TRANSMIT_INT(pub->retransmit)); + /* Delay the publication for longer time when the publication is triggered manually (section + * 3.7.3.1): + * + * When the publication of a message is the result of a power-up, a state transition + * progress update, or completion of a state transition, multiple nodes may be reporting the + * state change at the same time. To reduce the probability of a message collision, these + * messages should be sent with a random delay between 20 and 500 milliseconds. + */ + if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_LONG)) { + return 0; + } + k_work_reschedule(&pub->timer, K_NO_WAIT); return 0; @@ -2561,8 +2644,21 @@ static void commit_mod(const struct bt_mesh_model *mod, const struct bt_mesh_ele int32_t ms = bt_mesh_model_pub_period_get(mod); if (ms > 0) { - LOG_DBG("Starting publish timer (period %u ms)", ms); - k_work_schedule(&mod->pub->timer, K_MSEC(ms)); + /* Delay the first publication after power-up for longer time (section + * 3.7.3.1): + * + * When the publication of a message is the result of a power-up, a state + * transition progress update, or completion of a state transition, multiple + * nodes may be reporting the state change at the same time. To reduce the + * probability of a message collision, these messages should be sent with a + * random delay between 20 and 500 milliseconds. + */ + uint16_t random; + + random = !!mod->pub->delayable ? pub_delay_get(RANDOM_DELAY_LONG) : 0; + + LOG_DBG("Starting publish timer (period %u ms, delay %u ms)", ms, random); + k_work_schedule(&mod->pub->timer, K_MSEC(ms + random)); } } @@ -2614,3 +2710,24 @@ uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf) return page; } + +void bt_mesh_access_init(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_init(); +#endif +} + +void bt_mesh_access_suspend(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_stop(); +#endif +} + +void bt_mesh_access_reset(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_stop(); +#endif +} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index b7ce1abd0ea3..210fceee3195 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -94,10 +94,27 @@ void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, * Send a mesh model layer message out into the mesh network without having instantiated * the relevant mesh models. * - * @param ctx The Bluetooth mesh message context. + * @param ctx The Bluetooth Mesh message context. * @param buf The message payload. + * @param src_addr The source address of model + * @param cb Callback function. + * @param cb_data Callback data. * * @return 0 on success or negative error code on failure. */ int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr, const struct bt_mesh_send_cb *cb, void *cb_data); + +/** @brief Initialize the Access layer. + * + * Initialize the delayable message mechanism if it has been enabled. + */ +void bt_mesh_access_init(void); + +/** @brief Suspend the Access layer. + */ +void bt_mesh_access_suspend(void); + +/** @brief Reset the Access layer. + */ +void bt_mesh_access_reset(void); diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index 548e7f3fe151..00e2a4aa7bba 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -17,7 +17,6 @@ #include "common/bt_str.h" -#include "adv.h" #include "net.h" #include "foundation.h" #include "beacon.h" @@ -47,124 +46,144 @@ static K_FIFO_DEFINE(bt_mesh_adv_queue); static K_FIFO_DEFINE(bt_mesh_relay_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); -void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) +K_MEM_SLAB_DEFINE_STATIC(local_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_ADV_BUF_COUNT, __alignof__(struct bt_mesh_adv)); + +#if defined(CONFIG_BT_MESH_RELAY_BUF_COUNT) +K_MEM_SLAB_DEFINE_STATIC(relay_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_RELAY_BUF_COUNT, __alignof__(struct bt_mesh_adv)); +#endif + +#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) +K_MEM_SLAB_DEFINE_STATIC(friend_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_FRIEND_LPN_COUNT, __alignof__(struct bt_mesh_adv)); +#endif + +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv_ctx *ctx) { - if (!adv->started) { - adv->started = 1; + if (!ctx->started) { + ctx->started = 1; - if (adv->cb && adv->cb->start) { - adv->cb->start(duration, err, adv->cb_data); + if (ctx->cb && ctx->cb->start) { + ctx->cb->start(duration, err, ctx->cb_data); } if (err) { - adv->cb = NULL; + ctx->cb = NULL; } else if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { - bt_mesh_stat_succeeded_count(adv); + bt_mesh_stat_succeeded_count(ctx); } } } -static void bt_mesh_adv_send_end(int err, struct bt_mesh_adv const *adv) +static void bt_mesh_adv_send_end(int err, struct bt_mesh_adv_ctx const *ctx) { - if (adv->started && adv->cb && adv->cb->end) { - adv->cb->end(err, adv->cb_data); + if (ctx->started && ctx->cb && ctx->cb->end) { + ctx->cb->end(err, ctx->cb_data); } } -static void adv_buf_destroy(struct net_buf *buf) +static struct bt_mesh_adv *adv_create_from_pool(struct k_mem_slab *buf_pool, + enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout) { - struct bt_mesh_adv adv = *BT_MESH_ADV(buf); + struct bt_mesh_adv_ctx *ctx; + struct bt_mesh_adv *adv; + int err; - net_buf_destroy(buf); + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + LOG_WRN("Refusing to allocate buffer while suspended"); + return NULL; + } - bt_mesh_adv_send_end(0, &adv); -} + err = k_mem_slab_alloc(buf_pool, (void **)&adv, timeout); + if (err) { + return NULL; + } -NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BT_MESH_ADV_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + adv->__ref = 1; -static struct bt_mesh_adv adv_local_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; + net_buf_simple_init_with_data(&adv->b, adv->__bufs, BT_MESH_ADV_DATA_SIZE); + net_buf_simple_reset(&adv->b); -#if defined(CONFIG_BT_MESH_RELAY) -NET_BUF_POOL_DEFINE(relay_buf_pool, CONFIG_BT_MESH_RELAY_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + ctx = &adv->ctx; -static struct bt_mesh_adv adv_relay_pool[CONFIG_BT_MESH_RELAY_BUF_COUNT]; -#endif + (void)memset(ctx, 0, sizeof(*ctx)); -#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) -NET_BUF_POOL_DEFINE(friend_buf_pool, CONFIG_BT_MESH_FRIEND_LPN_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + ctx->type = type; + ctx->tag = tag; + ctx->xmit = xmit; -static struct bt_mesh_adv adv_friend_pool[CONFIG_BT_MESH_FRIEND_LPN_COUNT]; -#endif + return adv; +} -static struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *buf_pool, - struct bt_mesh_adv *adv_pool, - enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_ref(struct bt_mesh_adv *adv) { - struct bt_mesh_adv *adv; - struct net_buf *buf; + __ASSERT_NO_MSG(adv->__ref < UINT8_MAX); - if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { - LOG_WRN("Refusing to allocate buffer while suspended"); - return NULL; - } + adv->__ref++; - buf = net_buf_alloc(buf_pool, timeout); - if (!buf) { - return NULL; + return adv; +} + +void bt_mesh_adv_unref(struct bt_mesh_adv *adv) +{ + __ASSERT_NO_MSG(adv->__ref > 0); + + if (--adv->__ref > 0) { + return; } - adv = &adv_pool[net_buf_id(buf)]; - BT_MESH_ADV(buf) = adv; + struct k_mem_slab *slab = &local_adv_pool; + struct bt_mesh_adv_ctx ctx = adv->ctx; - (void)memset(adv, 0, sizeof(*adv)); +#if defined(CONFIG_BT_MESH_RELAY) + if (adv->ctx.tag == BT_MESH_ADV_TAG_RELAY) { + slab = &relay_adv_pool; + } +#endif - adv->type = type; - adv->tag = tag; - adv->xmit = xmit; +#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) + if (adv->ctx.tag == BT_MESH_ADV_TAG_FRIEND) { + slab = &friend_adv_pool; + } +#endif - return buf; + k_mem_slab_free(slab, (void *)adv); + bt_mesh_adv_send_end(0, &ctx); } -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_create(enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) if (tag == BT_MESH_ADV_TAG_RELAY) { - return bt_mesh_adv_create_from_pool(&relay_buf_pool, - adv_relay_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&relay_adv_pool, + type, tag, xmit, timeout); } #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) if (tag == BT_MESH_ADV_TAG_FRIEND) { - return bt_mesh_adv_create_from_pool(&friend_buf_pool, - adv_friend_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&friend_adv_pool, + type, tag, xmit, timeout); } #endif - return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_local_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&local_adv_pool, type, + tag, xmit, timeout); } -static struct net_buf *process_events(struct k_poll_event *ev, int count) +static struct bt_mesh_adv *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { LOG_DBG("ev->state %u", ev->state); switch (ev->state) { case K_POLL_STATE_FIFO_DATA_AVAILABLE: - return net_buf_get(ev->fifo, K_NO_WAIT); + return k_fifo_get(ev->fifo, K_NO_WAIT); case K_POLL_STATE_NOT_READY: case K_POLL_STATE_CANCELLED: break; @@ -177,7 +196,7 @@ static struct net_buf *process_events(struct k_poll_event *ev, int count) return NULL; } -struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_get(k_timeout_t timeout) { int err; struct k_poll_event events[] = { @@ -204,22 +223,22 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) return process_events(events, ARRAY_SIZE(events)); } -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout) { if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tags & BT_MESH_ADV_TAG_BIT_FRIEND) { - return net_buf_get(&bt_mesh_friend_queue, timeout); + return k_fifo_get(&bt_mesh_friend_queue, timeout); } if (IS_ENABLED(CONFIG_BT_MESH_RELAY) && !(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { - return net_buf_get(&bt_mesh_relay_queue, timeout); + return k_fifo_get(&bt_mesh_relay_queue, timeout); } - return bt_mesh_adv_buf_get(timeout); + return bt_mesh_adv_get(timeout); } -void bt_mesh_adv_buf_get_cancel(void) +void bt_mesh_adv_get_cancel(void) { LOG_DBG(""); @@ -234,38 +253,38 @@ void bt_mesh_adv_buf_get_cancel(void) } } -void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, +void bt_mesh_adv_send(struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data) { - LOG_DBG("type 0x%02x len %u: %s", BT_MESH_ADV(buf)->type, buf->len, - bt_hex(buf->data, buf->len)); + LOG_DBG("type 0x%02x len %u: %s", adv->ctx.type, adv->b.len, + bt_hex(adv->b.data, adv->b.len)); - BT_MESH_ADV(buf)->cb = cb; - BT_MESH_ADV(buf)->cb_data = cb_data; - BT_MESH_ADV(buf)->busy = 1U; + adv->ctx.cb = cb; + adv->ctx.cb_data = cb_data; + adv->ctx.busy = 1U; if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { - bt_mesh_stat_planned_count(BT_MESH_ADV(buf)); + bt_mesh_stat_planned_count(&adv->ctx); } if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_FRIEND) { - net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_friend_ready(); + adv->ctx.tag == BT_MESH_ADV_TAG_FRIEND) { + k_fifo_put(&bt_mesh_friend_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_friend_ready(); return; } if ((IS_ENABLED(CONFIG_BT_MESH_RELAY) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY) || + adv->ctx.tag == BT_MESH_ADV_TAG_RELAY) || (IS_ENABLED(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_PROV)) { - net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_relay_ready(); + adv->ctx.tag == BT_MESH_ADV_TAG_PROV)) { + k_fifo_put(&bt_mesh_relay_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_relay_ready(); return; } - net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_local_ready(); + k_fifo_put(&bt_mesh_adv_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_local_ready(); } int bt_mesh_adv_gatt_send(void) diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index a80ff7e8d4b6..0c936a1aa528 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -4,14 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ + /* Maximum advertising data payload for a single data type */ #define BT_MESH_ADV_DATA_SIZE 29 -/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ -#define BT_MESH_ADV_USER_DATA_SIZE 4 - -#define BT_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) - #define BT_MESH_ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) #define BT_MESH_SCAN_INTERVAL_MS 30 #define BT_MESH_SCAN_WINDOW_MS 30 @@ -41,7 +39,7 @@ enum bt_mesh_adv_tag_bit { BT_MESH_ADV_TAG_BIT_PROV = BIT(BT_MESH_ADV_TAG_PROV), }; -struct bt_mesh_adv { +struct bt_mesh_adv_ctx { const struct bt_mesh_send_cb *cb; void *cb_data; @@ -53,24 +51,39 @@ struct bt_mesh_adv { uint8_t xmit; }; +struct bt_mesh_adv { + sys_snode_t node; + + struct bt_mesh_adv_ctx ctx; + + struct net_buf_simple b; + + uint8_t __ref; + + uint8_t __bufs[BT_MESH_ADV_DATA_SIZE]; +}; + /* Lookup table for Advertising data types for bt_mesh_adv_type: */ extern const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES]; +struct bt_mesh_adv *bt_mesh_adv_ref(struct bt_mesh_adv *adv); +void bt_mesh_adv_unref(struct bt_mesh_adv *adv); + /* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */ -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout); +struct bt_mesh_adv *bt_mesh_adv_create(enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout); -void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, +void bt_mesh_adv_send(struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data); -struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); +struct bt_mesh_adv *bt_mesh_adv_get(k_timeout_t timeout); -struct net_buf *bt_mesh_adv_buf_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout); +struct bt_mesh_adv *bt_mesh_adv_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); -void bt_mesh_adv_buf_get_cancel(void); +void bt_mesh_adv_get_cancel(void); void bt_mesh_adv_init(void); @@ -80,13 +93,16 @@ int bt_mesh_scan_disable(void); int bt_mesh_adv_enable(void); -void bt_mesh_adv_buf_local_ready(void); +/* Should not be called from work queue due to undefined behavior */ +int bt_mesh_adv_disable(void); + +void bt_mesh_adv_local_ready(void); -void bt_mesh_adv_buf_relay_ready(void); +void bt_mesh_adv_relay_ready(void); -void bt_mesh_adv_buf_terminate(const struct net_buf *buf); +void bt_mesh_adv_terminate(struct bt_mesh_adv *adv); -void bt_mesh_adv_buf_friend_ready(void); +void bt_mesh_adv_friend_ready(void); int bt_mesh_adv_gatt_send(void); @@ -94,9 +110,11 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len); -void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv); +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv_ctx *ctx); int bt_mesh_scan_active_set(bool active); int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len); + +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ */ diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 0bfc2041c7df..c30a3a2b9bc2 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -13,12 +13,14 @@ #include #include #include +#if defined(CONFIG_BT_LL_SOFTDEVICE) +#include +#endif #include "common/bt_str.h" #include "host/hci_core.h" -#include "adv.h" #include "net.h" #include "proxy.h" #include "solicitation.h" @@ -60,14 +62,14 @@ struct bt_mesh_ext_adv { const enum bt_mesh_adv_tag_bit tags; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; - struct net_buf *buf; - uint64_t timestamp; - struct k_work_delayable work; + struct bt_mesh_adv *adv; + uint32_t timestamp; + struct k_work work; struct bt_le_adv_param adv_param; }; static void send_pending_adv(struct k_work *work); -static bool schedule_send(struct bt_mesh_ext_adv *adv); +static bool schedule_send(struct bt_mesh_ext_adv *ext_adv); static struct bt_mesh_ext_adv advs[] = { [0] = { @@ -86,7 +88,7 @@ static struct bt_mesh_ext_adv advs[] = { #endif /* CONFIG_BT_MESH_PB_ADV */ BT_MESH_ADV_TAG_BIT_LOCAL ), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #if CONFIG_BT_MESH_RELAY_ADV_SETS [1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = { @@ -98,19 +100,19 @@ static struct bt_mesh_ext_adv advs[] = { BT_MESH_ADV_TAG_BIT_PROV | #endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */ 0), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */ #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) { .tags = BT_MESH_ADV_TAG_BIT_FRIEND, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */ #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE) { .tags = BT_MESH_ADV_TAG_BIT_PROXY, - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ }; @@ -136,7 +138,29 @@ static inline struct bt_mesh_ext_adv *gatt_adv_get(void) } } -static int adv_start(struct bt_mesh_ext_adv *adv, +static int set_adv_randomness(uint8_t handle, int rand_us) +{ +#if defined(CONFIG_BT_LL_SOFTDEVICE) + struct net_buf *buf; + sdc_hci_cmd_vs_set_adv_randomness_t *cmd_params; + + buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, sizeof(*cmd_params)); + if (!buf) { + LOG_ERR("Could not allocate command buffer"); + return -ENOMEM; + } + + cmd_params = net_buf_add(buf, sizeof(*cmd_params)); + cmd_params->adv_handle = handle; + cmd_params->rand_us = rand_us; + + return bt_hci_cmd_send_sync(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, buf, NULL); +#else + return 0; +#endif /* defined(CONFIG_BT_LL_SOFTDEVICE) */ +} + +static int adv_start(struct bt_mesh_ext_adv *ext_adv, const struct bt_le_adv_param *param, struct bt_le_ext_adv_start_param *start, const struct bt_data *ad, size_t ad_len, @@ -144,47 +168,47 @@ static int adv_start(struct bt_mesh_ext_adv *adv, { int err; - if (!adv->instance) { + if (!ext_adv->instance) { LOG_ERR("Mesh advertiser not enabled"); return -ENODEV; } - if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_ACTIVE)) { + if (atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { LOG_ERR("Advertiser is busy"); return -EBUSY; } - if (atomic_test_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS)) { - err = bt_le_ext_adv_update_param(adv->instance, param); + if (atomic_test_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS)) { + err = bt_le_ext_adv_update_param(ext_adv->instance, param); if (err) { LOG_ERR("Failed updating adv params: %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); return err; } - atomic_set_bit_to(adv->flags, ADV_FLAG_UPDATE_PARAMS, - param != &adv->adv_param); + atomic_set_bit_to(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS, + param != &ext_adv->adv_param); } - err = bt_le_ext_adv_set_data(adv->instance, ad, ad_len, sd, sd_len); + err = bt_le_ext_adv_set_data(ext_adv->instance, ad, ad_len, sd, sd_len); if (err) { LOG_ERR("Failed setting adv data: %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); return err; } - adv->timestamp = k_uptime_get(); + ext_adv->timestamp = k_uptime_get_32(); - err = bt_le_ext_adv_start(adv->instance, start); + err = bt_le_ext_adv_start(ext_adv->instance, start); if (err) { LOG_ERR("Advertising failed: err %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); } return err; } -static int bt_data_send(struct bt_mesh_ext_adv *adv, uint8_t num_events, uint16_t adv_interval, +static int bt_data_send(struct bt_mesh_ext_adv *ext_adv, uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len) { struct bt_le_ext_adv_start_param start = { @@ -194,41 +218,41 @@ static int bt_data_send(struct bt_mesh_ext_adv *adv, uint8_t num_events, uint16_ adv_interval = MAX(ADV_INT_FAST_MS, adv_interval); /* Only update advertising parameters if they're different */ - if (adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_interval)) { - adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_interval); - adv->adv_param.interval_max = adv->adv_param.interval_min; - atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS); + if (ext_adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_interval)) { + ext_adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_interval); + ext_adv->adv_param.interval_max = ext_adv->adv_param.interval_min; + atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS); } - return adv_start(adv, &adv->adv_param, &start, ad, ad_len, NULL, 0); + return adv_start(ext_adv, &ext_adv->adv_param, &start, ad, ad_len, NULL, 0); } -static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) +static int adv_send(struct bt_mesh_ext_adv *ext_adv, struct bt_mesh_adv *adv) { - uint8_t num_events = BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1; + uint8_t num_events = BT_MESH_TRANSMIT_COUNT(adv->ctx.xmit) + 1; uint16_t duration, adv_int; struct bt_data ad; int err; - adv_int = BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit); + adv_int = BT_MESH_TRANSMIT_INT(adv->ctx.xmit); /* Upper boundary estimate: */ duration = num_events * (adv_int + 10); - LOG_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); + LOG_DBG("type %u len %u: %s", adv->ctx.type, + adv->b.len, bt_hex(adv->b.data, adv->b.len)); LOG_DBG("count %u interval %ums duration %ums", num_events, adv_int, duration); - ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->len; - ad.data = buf->data; + ad.type = bt_mesh_adv_type[adv->ctx.type]; + ad.data_len = adv->b.len; + ad.data = adv->b.data; - err = bt_data_send(adv, num_events, adv_int, &ad, 1); + err = bt_data_send(ext_adv, num_events, adv_int, &ad, 1); if (!err) { - adv->buf = net_buf_ref(buf); + ext_adv->adv = bt_mesh_adv_ref(adv); } - bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); + bt_mesh_adv_send_start(duration, err, &adv->ctx); return err; } @@ -243,50 +267,45 @@ static const char * const adv_tag_to_str[] = { static void send_pending_adv(struct k_work *work) { - struct bt_mesh_ext_adv *adv; - struct net_buf *buf; + struct bt_mesh_ext_adv *ext_adv; + struct bt_mesh_adv *adv; int err; - adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work.work); - - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SENT)) { - /* Calling k_uptime_delta on a timestamp moves it to the current time. - * This is essential here, as schedule_send() uses the end of the event - * as a reference to avoid sending the next advertisement too soon. - */ - int64_t duration = k_uptime_delta(&adv->timestamp); + ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work); - LOG_DBG("Advertising stopped after %u ms for %s", (uint32_t)duration, - adv->buf ? adv_tag_to_str[BT_MESH_ADV(adv->buf)->tag] : - adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SENT)) { + LOG_DBG("Advertising stopped after %u ms for %s", + k_uptime_get_32() - ext_adv->timestamp, + ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag] + : adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY_START); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START); - if (adv->buf) { - net_buf_unref(adv->buf); - adv->buf = NULL; + if (ext_adv->adv) { + bt_mesh_adv_unref(ext_adv->adv); + ext_adv->adv = NULL; } - (void)schedule_send(adv); + (void)schedule_send(ext_adv); return; } - atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULED); - while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tags, K_NO_WAIT))) { + while ((adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT))) { /* busy == 0 means this was canceled */ - if (!BT_MESH_ADV(buf)->busy) { - net_buf_unref(buf); + if (!adv->ctx.busy) { + bt_mesh_adv_unref(adv); continue; } - BT_MESH_ADV(buf)->busy = 0U; - err = buf_send(adv, buf); + adv->ctx.busy = 0U; + err = adv_send(ext_adv, adv); - net_buf_unref(buf); + bt_mesh_adv_unref(adv); if (!err) { return; /* Wait for advertising to finish */ @@ -294,7 +313,7 @@ static void send_pending_adv(struct k_work *work) } if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { + !(ext_adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { return; } @@ -303,52 +322,35 @@ static void send_pending_adv(struct k_work *work) return; } - atomic_set_bit(adv->flags, ADV_FLAG_PROXY_START); + atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY_START); if (!bt_mesh_adv_gatt_send()) { - atomic_set_bit(adv->flags, ADV_FLAG_PROXY); + atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY); } - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING)) { - schedule_send(adv); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING)) { + schedule_send(ext_adv); } } -static bool schedule_send(struct bt_mesh_ext_adv *adv) +static bool schedule_send(struct bt_mesh_ext_adv *ext_adv) { - uint64_t timestamp; - int64_t delta; - - timestamp = adv->timestamp; - - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY)) { - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY_START); - (void)bt_le_ext_adv_stop(adv->instance); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) { + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START); + (void)bt_le_ext_adv_stop(ext_adv->instance); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); } - if (atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { - atomic_set_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); + if (atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { + atomic_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING); return false; - } else if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_SCHEDULED)) { + } else if (atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULED)) { return false; } - atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); - - if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - adv->tags & BT_MESH_ADV_TAG_BIT_FRIEND) || - (CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && adv->tags & BT_MESH_ADV_TAG_BIT_RELAY)) { - k_work_reschedule(&adv->work, K_NO_WAIT); - } else { - /* The controller will send the next advertisement immediately. - * Introduce a delay here to avoid sending the next mesh packet closer - * to the previous packet than what's permitted by the specification. - */ - delta = k_uptime_delta(×tamp); - k_work_reschedule(&adv->work, K_MSEC(ADV_INT_FAST_MS - delta)); - } + atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING); + k_work_submit(&ext_adv->work); return true; } @@ -358,17 +360,17 @@ void bt_mesh_adv_gatt_update(void) (void)schedule_send(gatt_adv_get()); } -void bt_mesh_adv_buf_local_ready(void) +void bt_mesh_adv_local_ready(void) { (void)schedule_send(advs); } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_relay_ready(void) { - struct bt_mesh_ext_adv *adv = relay_adv_get(); + struct bt_mesh_ext_adv *ext_adv = relay_adv_get(); for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { - if (schedule_send(&adv[i])) { + if (schedule_send(&ext_adv[i])) { return; } } @@ -379,7 +381,7 @@ void bt_mesh_adv_buf_relay_ready(void) } } -void bt_mesh_adv_buf_friend_ready(void) +void bt_mesh_adv_friend_ready(void) { if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { schedule_send(&advs[1 + CONFIG_BT_MESH_RELAY_ADV_SETS]); @@ -388,33 +390,33 @@ void bt_mesh_adv_buf_friend_ready(void) } } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +void bt_mesh_adv_terminate(struct bt_mesh_adv *adv) { int err; for (int i = 0; i < ARRAY_SIZE(advs); i++) { - struct bt_mesh_ext_adv *adv = &advs[i]; + struct bt_mesh_ext_adv *ext_adv = &advs[i]; - if (adv->buf != buf) { + if (ext_adv->adv != adv) { continue; } - if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { + if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { return; } - err = bt_le_ext_adv_stop(adv->instance); + err = bt_le_ext_adv_stop(ext_adv->instance); if (err) { LOG_ERR("Failed to stop adv %d", err); return; } /* Do not call `cb:end`, since this user action */ - BT_MESH_ADV(adv->buf)->cb = NULL; + adv->ctx.cb = NULL; - atomic_set_bit(adv->flags, ADV_FLAG_SENT); + atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT); - k_work_submit(&adv->work.work); + k_work_submit(&ext_adv->work); return; } @@ -450,31 +452,31 @@ static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance) static void adv_sent(struct bt_le_ext_adv *instance, struct bt_le_ext_adv_sent_info *info) { - struct bt_mesh_ext_adv *adv = adv_instance_find(instance); + struct bt_mesh_ext_adv *ext_adv = adv_instance_find(instance); - if (!adv) { + if (!ext_adv) { LOG_WRN("Unexpected adv instance"); return; } - if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { + if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { return; } - atomic_set_bit(adv->flags, ADV_FLAG_SENT); + atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT); - k_work_submit(&adv->work.work); + k_work_submit(&ext_adv->work); } #if defined(CONFIG_BT_MESH_GATT_SERVER) static void connected(struct bt_le_ext_adv *instance, struct bt_le_ext_adv_connected_info *info) { - struct bt_mesh_ext_adv *adv = gatt_adv_get(); + struct bt_mesh_ext_adv *ext_adv = gatt_adv_get(); - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY_START)) { - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); - (void)schedule_send(adv); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START)) { + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); + (void)schedule_send(ext_adv); } } #endif /* CONFIG_BT_MESH_GATT_SERVER */ @@ -501,6 +503,45 @@ int bt_mesh_adv_enable(void) if (err) { return err; } + + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && + IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && + advs[i].tags == BT_MESH_ADV_TAG_BIT_FRIEND) { + err = set_adv_randomness(advs[i].instance->handle, 0); + if (err) { + LOG_ERR("Failed to set zero randomness: %d", err); + } + } + } + + return 0; +} + +int bt_mesh_adv_disable(void) +{ + int err; + struct k_work_sync sync; + + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + k_work_flush(&advs[i].work, &sync); + + err = bt_le_ext_adv_stop(advs[i].instance); + if (err) { + LOG_ERR("Failed to stop adv %d", err); + return err; + } + + /* `adv_sent` is called to finish transmission of an adv buffer that was pushed to + * the host before the advertiser was stopped, but did not finish. + */ + adv_sent(advs[i].instance, NULL); + + err = bt_le_ext_adv_delete(advs[i].instance); + if (err) { + LOG_ERR("Failed to delete adv %d", err); + return err; + } + advs[i].instance = NULL; } return 0; @@ -511,7 +552,7 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { - struct bt_mesh_ext_adv *adv = gatt_adv_get(); + struct bt_mesh_ext_adv *ext_adv = gatt_adv_get(); struct bt_le_ext_adv_start_param start = { /* Timeout is set in 10 ms steps, with 0 indicating "forever" */ .timeout = (duration == SYS_FOREVER_MS) ? 0 : MAX(1, duration / 10), @@ -519,9 +560,9 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, LOG_DBG("Start advertising %d ms", duration); - atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS); + atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS); - return adv_start(adv, param, &start, ad, ad_len, sd, sd_len); + return adv_start(ext_adv, param, &start, ad, ad_len, sd, sd_len); } int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index a7d7dd1a3200..d4003e497bb2 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -19,7 +19,6 @@ #include "host/hci_core.h" -#include "adv.h" #include "net.h" #include "foundation.h" #include "beacon.h" @@ -39,10 +38,11 @@ LOG_MODULE_REGISTER(bt_mesh_adv_legacy); static struct k_thread adv_thread_data; static K_KERNEL_STACK_DEFINE(adv_thread_stack, CONFIG_BT_MESH_ADV_STACK_SIZE); static int32_t adv_timeout; +static bool enabled; static int bt_data_send(uint8_t num_events, uint16_t adv_int, const struct bt_data *ad, size_t ad_len, - struct bt_mesh_adv *adv) + struct bt_mesh_adv_ctx *ctx) { struct bt_le_adv_param param = {}; uint64_t uptime = k_uptime_get(); @@ -100,8 +100,8 @@ static int bt_data_send(uint8_t num_events, uint16_t adv_int, LOG_DBG("Advertising started. Sleeping %u ms", duration); - if (adv) { - bt_mesh_adv_send_start(duration, err, adv); + if (ctx) { + bt_mesh_adv_send_start(duration, err, ctx); } k_sleep(K_MSEC(duration)); @@ -123,38 +123,37 @@ int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_int, return bt_data_send(num_events, adv_int, ad, ad_len, NULL); } -static inline void buf_send(struct net_buf *buf) +static inline void adv_send(struct bt_mesh_adv *adv) { - uint16_t num_events = BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1; + uint16_t num_events = BT_MESH_TRANSMIT_COUNT(adv->ctx.xmit) + 1; uint16_t adv_int; struct bt_data ad; - adv_int = BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit); + adv_int = BT_MESH_TRANSMIT_INT(adv->ctx.xmit); - LOG_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); + LOG_DBG("type %u len %u: %s", adv->ctx.type, + adv->b.len, bt_hex(adv->b.data, adv->b.len)); - ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->len; - ad.data = buf->data; + ad.type = bt_mesh_adv_type[adv->ctx.type]; + ad.data_len = adv->b.len; + ad.data = adv->b.data; - bt_data_send(num_events, adv_int, &ad, 1, BT_MESH_ADV(buf)); + bt_data_send(num_events, adv_int, &ad, 1, &adv->ctx); } static void adv_thread(void *p1, void *p2, void *p3) { LOG_DBG("started"); + struct bt_mesh_adv *adv; - while (1) { - struct net_buf *buf; - + while (enabled) { if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER)) { - buf = bt_mesh_adv_buf_get(K_NO_WAIT); - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !buf) { + adv = bt_mesh_adv_get(K_NO_WAIT); + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !adv) { (void)bt_mesh_sol_send(); } - while (!buf) { + while (!adv) { /* Adv timeout may be set by a call from proxy * to bt_mesh_adv_gatt_start: @@ -162,52 +161,58 @@ static void adv_thread(void *p1, void *p2, void *p3) adv_timeout = SYS_FOREVER_MS; (void)bt_mesh_adv_gatt_send(); - buf = bt_mesh_adv_buf_get(SYS_TIMEOUT_MS(adv_timeout)); + adv = bt_mesh_adv_get(SYS_TIMEOUT_MS(adv_timeout)); bt_le_adv_stop(); - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !buf) { + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !adv) { (void)bt_mesh_sol_send(); } } } else { - buf = bt_mesh_adv_buf_get(K_FOREVER); + adv = bt_mesh_adv_get(K_FOREVER); } - if (!buf) { + if (!adv) { continue; } /* busy == 0 means this was canceled */ - if (BT_MESH_ADV(buf)->busy) { - BT_MESH_ADV(buf)->busy = 0U; - buf_send(buf); + if (adv->ctx.busy) { + adv->ctx.busy = 0U; + adv_send(adv); } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); /* Give other threads a chance to run */ k_yield(); } + + /* Empty the advertising pool when advertising is disabled */ + while ((adv = bt_mesh_adv_get(K_NO_WAIT))) { + bt_mesh_adv_send_start(0, -ENODEV, &adv->ctx); + bt_mesh_adv_unref(adv); + } } -void bt_mesh_adv_buf_local_ready(void) +void bt_mesh_adv_local_ready(void) { /* Will be handled automatically */ } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_relay_ready(void) { /* Will be handled automatically */ } void bt_mesh_adv_gatt_update(void) { - bt_mesh_adv_buf_get_cancel(); + bt_mesh_adv_get_cancel(); } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +void bt_mesh_adv_terminate(struct bt_mesh_adv *adv) { - ARG_UNUSED(buf); + ARG_UNUSED(adv); } void bt_mesh_adv_init(void) @@ -221,10 +226,19 @@ void bt_mesh_adv_init(void) int bt_mesh_adv_enable(void) { + enabled = true; k_thread_start(&adv_thread_data); return 0; } +int bt_mesh_adv_disable(void) +{ + enabled = false; + k_thread_join(&adv_thread_data, K_FOREVER); + LOG_DBG("Advertising disabled"); + return 0; +} + int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) diff --git a/subsys/bluetooth/mesh/app_keys.c b/subsys/bluetooth/mesh/app_keys.c index a47d31447c5f..5afd887a8e80 100644 --- a/subsys/bluetooth/mesh/app_keys.c +++ b/subsys/bluetooth/mesh/app_keys.c @@ -17,7 +17,6 @@ #include "rpl.h" #include "settings.h" #include "crypto.h" -#include "adv.h" #include "proxy.h" #include "friend.h" #include "foundation.h" diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index afdea5b4c6a1..ef337f9f5100 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -16,7 +16,6 @@ #include "common/bt_str.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "prov.h" @@ -256,7 +255,7 @@ static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *b .end = beacon_complete, }; uint32_t now = k_uptime_get_32(); - struct net_buf *buf; + struct bt_mesh_adv *adv; uint32_t time_diff; uint32_t time_since_last_recv; int err; @@ -271,19 +270,19 @@ static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *b return false; } - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, PROV_XMIT, K_NO_WAIT); - if (!buf) { - LOG_ERR("Unable to allocate beacon buffer"); + if (!adv) { + LOG_ERR("Unable to allocate beacon adv"); return true; /* Bail out */ } - err = beacon_create(sub, &buf->b); + err = beacon_create(sub, &adv->b); if (!err) { - bt_mesh_adv_send(buf, &send_cb, beacon); + bt_mesh_adv_send(adv, &send_cb, beacon); } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return err != 0; } @@ -330,22 +329,22 @@ static int unprovisioned_beacon_send(void) { const struct bt_mesh_prov *prov; uint8_t uri_hash[16] = { 0 }; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint16_t oob_info; LOG_DBG(""); - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, UNPROV_XMIT, K_NO_WAIT); - if (!buf) { - LOG_ERR("Unable to allocate beacon buffer"); + if (!adv) { + LOG_ERR("Unable to allocate beacon adv"); return -ENOBUFS; } prov = bt_mesh_prov_get(); - net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED); - net_buf_add_mem(buf, prov->uuid, 16); + net_buf_simple_add_u8(&adv->b, BEACON_TYPE_UNPROVISIONED); + net_buf_simple_add_mem(&adv->b, prov->uuid, 16); if (prov->uri && bt_mesh_s1_str(prov->uri, uri_hash) == 0) { oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI; @@ -353,31 +352,31 @@ static int unprovisioned_beacon_send(void) oob_info = prov->oob_info; } - net_buf_add_be16(buf, oob_info); - net_buf_add_mem(buf, uri_hash, 4); + net_buf_simple_add_be16(&adv->b, oob_info); + net_buf_simple_add_mem(&adv->b, uri_hash, 4); - bt_mesh_adv_send(buf, NULL, NULL); - net_buf_unref(buf); + bt_mesh_adv_send(adv, NULL, NULL); + bt_mesh_adv_unref(adv); if (prov->uri) { size_t len; - buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_ADV_TAG_LOCAL, UNPROV_XMIT, K_NO_WAIT); - if (!buf) { - LOG_ERR("Unable to allocate URI buffer"); + if (!adv) { + LOG_ERR("Unable to allocate URI adv"); return -ENOBUFS; } len = strlen(prov->uri); - if (net_buf_tailroom(buf) < len) { + if (net_buf_simple_tailroom(&adv->b) < len) { LOG_WRN("Too long URI to fit advertising data"); } else { - net_buf_add_mem(buf, prov->uri, len); - bt_mesh_adv_send(buf, NULL, NULL); + net_buf_simple_add_mem(&adv->b, prov->uri, len); + bt_mesh_adv_send(adv, NULL, NULL); } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } return 0; diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index c7bea0d29b08..4fef60d5c8db 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -14,7 +14,6 @@ #include "settings.h" #include "heartbeat.h" #include "friend.h" -#include "adv.h" #include "cfg.h" #include "od_priv_proxy.h" #include "priv_beacon.h" diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index fa6bb48703a1..268f883d8b87 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -21,7 +21,6 @@ #include "host/testing.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "lpn.h" diff --git a/subsys/bluetooth/mesh/delayable_msg.c b/subsys/bluetooth/mesh/delayable_msg.c new file mode 100644 index 000000000000..a1a247bb9c9b --- /dev/null +++ b/subsys/bluetooth/mesh/delayable_msg.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include + +#include "msg.h" +#include "access.h" +#include "net.h" + +#define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_mesh_delayable_msg); + +static void delayable_msg_handler(struct k_work *w); +static bool push_msg_from_delayable_msgs(void); + +static struct delayable_msg_chunk { + sys_snode_t node; + uint8_t data[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE]; +} delayable_msg_chunks[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT]; + +static struct delayable_msg_ctx { + sys_snode_t node; + sys_slist_t chunks; + struct bt_mesh_msg_ctx ctx; + uint16_t src_addr; + const struct bt_mesh_send_cb *cb; + void *cb_data; + uint32_t fired_time; + uint16_t len; +} delayable_msgs_ctx[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT]; + +static struct { + sys_slist_t busy_ctx; + sys_slist_t free_ctx; + sys_slist_t free_chunks; + struct k_work_delayable random_delay; +} access_delayable_msg = {.random_delay = Z_WORK_DELAYABLE_INITIALIZER(delayable_msg_handler)}; + +static void put_ctx_to_busy_list(struct delayable_msg_ctx *ctx) +{ + struct delayable_msg_ctx *curr_ctx; + sys_slist_t *list = &access_delayable_msg.busy_ctx; + sys_snode_t *head = sys_slist_peek_head(list); + sys_snode_t *curr = head; + sys_snode_t *prev = curr; + + if (!head) { + sys_slist_append(list, &ctx->node); + return; + } + + do { + curr_ctx = CONTAINER_OF(curr, struct delayable_msg_ctx, node); + if (ctx->fired_time < curr_ctx->fired_time) { + if (curr == head) { + sys_slist_prepend(list, &ctx->node); + } else { + sys_slist_insert(list, prev, &ctx->node); + } + return; + } + prev = curr; + } while ((curr = sys_slist_peek_next(curr))); + + sys_slist_append(list, &ctx->node); +} + +static struct delayable_msg_ctx *peek_pending_msg(void) +{ + struct delayable_msg_ctx *pending_msg = NULL; + sys_snode_t *node = sys_slist_peek_head(&access_delayable_msg.busy_ctx); + + if (node) { + pending_msg = CONTAINER_OF(node, struct delayable_msg_ctx, node); + } + + return pending_msg; +} + +static void reschedule_delayable_msg(struct delayable_msg_ctx *msg) +{ + uint32_t curr_time; + k_timeout_t delay = K_NO_WAIT; + struct delayable_msg_ctx *pending_msg; + + if (msg) { + put_ctx_to_busy_list(msg); + } + + pending_msg = peek_pending_msg(); + + if (!pending_msg) { + return; + } + + curr_time = k_uptime_get_32(); + if (curr_time < pending_msg->fired_time) { + delay = K_MSEC(pending_msg->fired_time - curr_time); + } + + k_work_reschedule(&access_delayable_msg.random_delay, delay); +} + +static int allocate_delayable_msg_chunks(struct delayable_msg_ctx *msg, int number) +{ + sys_snode_t *node; + + for (int i = 0; i < number; i++) { + node = sys_slist_get(&access_delayable_msg.free_chunks); + if (!node) { + LOG_WRN("Unable allocate %u chunks, allocated %u", number, i); + return i; + } + sys_slist_append(&msg->chunks, node); + } + + return number; +} + +static void release_delayable_msg_chunks(struct delayable_msg_ctx *msg) +{ + sys_snode_t *node; + + while ((node = sys_slist_get(&msg->chunks))) { + sys_slist_append(&access_delayable_msg.free_chunks, node); + } +} + +static struct delayable_msg_ctx *allocate_delayable_msg_ctx(void) +{ + struct delayable_msg_ctx *msg; + sys_snode_t *node; + + if (sys_slist_is_empty(&access_delayable_msg.free_ctx)) { + LOG_WRN("Purge pending delayable message."); + if (!push_msg_from_delayable_msgs()) { + return NULL; + } + } + + node = sys_slist_get(&access_delayable_msg.free_ctx); + msg = CONTAINER_OF(node, struct delayable_msg_ctx, node); + sys_slist_init(&msg->chunks); + + return msg; +} + +static void release_delayable_msg_ctx(struct delayable_msg_ctx *ctx) +{ + if (sys_slist_find_and_remove(&access_delayable_msg.busy_ctx, &ctx->node)) { + sys_slist_append(&access_delayable_msg.free_ctx, &ctx->node); + } +} + +static bool push_msg_from_delayable_msgs(void) +{ + sys_snode_t *node; + struct delayable_msg_chunk *chunk; + struct delayable_msg_ctx *msg = peek_pending_msg(); + uint16_t len; + int err; + + if (!msg) { + return false; + } + + len = msg->len; + + NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX); + + SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) { + uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, len); + + chunk = CONTAINER_OF(node, struct delayable_msg_chunk, node); + memcpy(net_buf_simple_add(&buf, tmp), chunk->data, tmp); + len -= tmp; + } + + msg->ctx.rnd_delay = false; + err = bt_mesh_access_send(&msg->ctx, &buf, msg->src_addr, msg->cb, msg->cb_data); + msg->ctx.rnd_delay = true; + + if (err == -EBUSY || err == -ENOBUFS) { + return false; + } + + release_delayable_msg_chunks(msg); + release_delayable_msg_ctx(msg); + + if (err && msg->cb && msg->cb->start) { + msg->cb->start(0, err, msg->cb_data); + } + + return true; +} + +static void delayable_msg_handler(struct k_work *w) +{ + if (!push_msg_from_delayable_msgs()) { + sys_snode_t *node = sys_slist_get(&access_delayable_msg.busy_ctx); + struct delayable_msg_ctx *pending_msg = + CONTAINER_OF(node, struct delayable_msg_ctx, node); + + pending_msg->fired_time += 10; + reschedule_delayable_msg(pending_msg); + } else { + reschedule_delayable_msg(NULL); + } +} + +int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, + uint16_t src_addr, const struct bt_mesh_send_cb *cb, void *cb_data) +{ + sys_snode_t *node; + struct delayable_msg_ctx *msg; + uint16_t random_delay; + int total_number = DIV_ROUND_UP(buf->size, CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE); + int allocated_number = 0; + uint16_t len = buf->len; + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + LOG_WRN("Refusing to allocate message context while suspended"); + return -ENODEV; + } + + if (total_number > CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT) { + return -EINVAL; + } + + msg = allocate_delayable_msg_ctx(); + if (!msg) { + LOG_WRN("No available free delayable message context."); + return -ENOMEM; + } + + do { + allocated_number += + allocate_delayable_msg_chunks(msg, total_number - allocated_number); + + if (total_number > allocated_number) { + LOG_DBG("Unable allocate %u chunks, allocated %u", total_number, + allocated_number); + if (!push_msg_from_delayable_msgs()) { + LOG_WRN("No available chunk memory."); + release_delayable_msg_chunks(msg); + release_delayable_msg_ctx(msg); + return -ENOMEM; + } + } + } while (total_number > allocated_number); + + SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) { + uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, buf->len); + + struct delayable_msg_chunk *chunk = + CONTAINER_OF(node, struct delayable_msg_chunk, node); + + memcpy(chunk->data, net_buf_simple_pull_mem(buf, tmp), tmp); + } + + bt_rand(&random_delay, sizeof(uint16_t)); + random_delay = 20 + random_delay % (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst) ? 30 : 480); + msg->fired_time = k_uptime_get_32() + random_delay; + msg->ctx = *ctx; + msg->src_addr = src_addr; + msg->cb = cb; + msg->cb_data = cb_data; + msg->len = len; + + reschedule_delayable_msg(msg); + + return 0; +} + +void bt_mesh_delayable_msg_init(void) +{ + sys_slist_init(&access_delayable_msg.busy_ctx); + sys_slist_init(&access_delayable_msg.free_ctx); + sys_slist_init(&access_delayable_msg.free_chunks); + + for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT; i++) { + sys_slist_append(&access_delayable_msg.free_ctx, &delayable_msgs_ctx[i].node); + } + + for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT; i++) { + sys_slist_append(&access_delayable_msg.free_chunks, &delayable_msg_chunks[i].node); + } +} + +void bt_mesh_delayable_msg_stop(void) +{ + sys_snode_t *node; + struct delayable_msg_ctx *ctx; + + k_work_cancel_delayable(&access_delayable_msg.random_delay); + + while ((node = sys_slist_peek_head(&access_delayable_msg.busy_ctx))) { + ctx = CONTAINER_OF(node, struct delayable_msg_ctx, node); + release_delayable_msg_chunks(ctx); + release_delayable_msg_ctx(ctx); + + if (ctx->cb && ctx->cb->start) { + ctx->cb->start(0, -ENODEV, ctx->cb_data); + } + } +} diff --git a/subsys/bluetooth/mesh/delayable_msg.h b/subsys/bluetooth/mesh/delayable_msg.h new file mode 100644 index 000000000000..1ab5dde2e76c --- /dev/null +++ b/subsys/bluetooth/mesh/delayable_msg.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ +#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ + +int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, + uint16_t src_addr, const struct bt_mesh_send_cb *cb, + void *cb_data); +void bt_mesh_delayable_msg_init(void); +void bt_mesh_delayable_msg_stop(void); + +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ */ diff --git a/subsys/bluetooth/mesh/friend.c b/subsys/bluetooth/mesh/friend.c index 73b75eadf4f9..6fbd9f81a687 100644 --- a/subsys/bluetooth/mesh/friend.c +++ b/subsys/bluetooth/mesh/friend.c @@ -13,7 +13,6 @@ #include #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "app_keys.h" @@ -1239,7 +1238,7 @@ static void friend_timeout(struct k_work *work) .start = buf_send_start, .end = buf_send_end, }; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint8_t md; if (!friend_is_allocated(frnd)) { @@ -1281,19 +1280,19 @@ static void friend_timeout(struct k_work *work) frnd->queue_size--; send_last: - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_FRIEND, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_FRIEND, FRIEND_XMIT, K_NO_WAIT); - if (!buf) { - LOG_ERR("Unable to allocate friend adv buffer"); + if (!adv) { + LOG_ERR("Unable to allocate friend adv"); return; } - net_buf_add_mem(buf, frnd->last->data, frnd->last->len); + net_buf_simple_add_mem(&adv->b, frnd->last->data, frnd->last->len); frnd->pending_req = 0U; frnd->pending_buf = 1U; - bt_mesh_adv_send(buf, &buf_sent_cb, frnd); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &buf_sent_cb, frnd); + bt_mesh_adv_unref(adv); } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) diff --git a/subsys/bluetooth/mesh/gatt_cli.c b/subsys/bluetooth/mesh/gatt_cli.c index bff9b567011d..7814f32f27fa 100644 --- a/subsys/bluetooth/mesh/gatt_cli.c +++ b/subsys/bluetooth/mesh/gatt_cli.c @@ -18,7 +18,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/health_srv.c b/subsys/bluetooth/mesh/health_srv.c index 8611e1004f63..3db3410aa34b 100644 --- a/subsys/bluetooth/mesh/health_srv.c +++ b/subsys/bluetooth/mesh/health_srv.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "transport.h" #include "access.h" diff --git a/subsys/bluetooth/mesh/lpn.c b/subsys/bluetooth/mesh/lpn.c index 2b655f729f31..f6f906b12fe9 100644 --- a/subsys/bluetooth/mesh/lpn.c +++ b/subsys/bluetooth/mesh/lpn.c @@ -13,7 +13,6 @@ #include #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index 2c78ea227de1..1b80233cec17 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -18,7 +18,6 @@ #include #include "test.h" -#include "adv.h" #include "prov.h" #include "provisioner.h" #include "net.h" @@ -360,6 +359,7 @@ void bt_mesh_reset(void) */ (void)k_work_cancel_delayable(&bt_mesh.ivu_timer); + bt_mesh_access_reset(); bt_mesh_model_reset(); bt_mesh_cfg_default_set(); bt_mesh_trans_reset(); @@ -460,6 +460,31 @@ int bt_mesh_suspend(void) bt_mesh_model_foreach(model_suspend, NULL); + bt_mesh_access_suspend(); + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + err = bt_mesh_pb_gatt_srv_disable(); + if (err && err != -EALREADY) { + LOG_WRN("Disabling PB-GATT failed (err %d)", err); + return err; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + err = bt_mesh_proxy_gatt_disable(); + if (err && err != -EALREADY) { + LOG_WRN("Disabling GATT proxy failed (err %d)", err); + return err; + } + } + + err = bt_mesh_adv_disable(); + if (err) { + atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + LOG_WRN("Disabling advertisers failed (err %d)", err); + return err; + } + return 0; } @@ -488,6 +513,33 @@ int bt_mesh_resume(void) return -EALREADY; } + if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { + bt_mesh_adv_init(); + } + + err = bt_mesh_adv_enable(); + if (err) { + atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + LOG_WRN("Re-enabling advertisers failed (err %d)", err); + return err; + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && bt_mesh_is_provisioned()) { + err = bt_mesh_proxy_gatt_enable(); + if (err) { + LOG_WRN("Re-enabling GATT proxy failed (err %d)", err); + return err; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && !bt_mesh_is_provisioned()) { + err = bt_mesh_pb_gatt_srv_enable(); + if (err) { + LOG_WRN("Re-enabling PB-GATT failed (err %d)", err); + return err; + } + } + err = bt_mesh_scan_enable(); if (err) { LOG_WRN("Re-enabling scanning failed (err %d)", err); @@ -504,7 +556,13 @@ int bt_mesh_resume(void) bt_mesh_model_foreach(model_resume, NULL); - return err; + err = bt_mesh_adv_gatt_send(); + if (err && (err != -ENOTSUP)) { + LOG_WRN("GATT send failed (err %d)", err); + return err; + } + + return 0; } int bt_mesh_init(const struct bt_mesh_prov *prov, @@ -541,6 +599,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, bt_mesh_cfg_default_set(); bt_mesh_net_init(); bt_mesh_trans_init(); + bt_mesh_access_init(); bt_mesh_hb_init(); bt_mesh_beacon_init(); bt_mesh_adv_init(); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 6a9f29b4064b..943a5e83c23e 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -526,19 +525,19 @@ static int net_loopback(const struct bt_mesh_net_tx *tx, const uint8_t *data, return 0; } -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data) { const struct bt_mesh_net_cred *cred; int err; LOG_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu", tx->src, tx->ctx->addr, - buf->len, net_buf_headroom(buf), net_buf_tailroom(buf)); - LOG_DBG("Payload len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + adv->b.len, net_buf_simple_headroom(&adv->b), net_buf_simple_tailroom(&adv->b)); + LOG_DBG("Payload len %u: %s", adv->b.len, bt_hex(adv->b.data, adv->b.len)); LOG_DBG("Seq 0x%06x", bt_mesh.seq); cred = net_tx_cred_get(tx); - err = net_header_encode(tx, cred->nid, &buf->b); + err = net_header_encode(tx, cred->nid, &adv->b); if (err) { goto done; } @@ -546,7 +545,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, /* Deliver to local network interface if necessary */ if (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_has_addr(tx->ctx->addr)) { - err = net_loopback(tx, buf->data, buf->len); + err = net_loopback(tx, adv->b.data, adv->b.len); /* Local unicast messages should not go out to network */ if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr) || @@ -569,28 +568,28 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, goto done; } - err = net_encrypt(&buf->b, cred, BT_MESH_NET_IVI_TX, BT_MESH_NONCE_NETWORK); + err = net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_TX, BT_MESH_NONCE_NETWORK); if (err) { goto done; } - BT_MESH_ADV(buf)->cb = cb; - BT_MESH_ADV(buf)->cb_data = cb_data; + adv->ctx.cb = cb; + adv->ctx.cb_data = cb_data; /* Deliver to GATT Proxy Clients if necessary. */ if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_relay(buf, tx->ctx->addr); + (void)bt_mesh_proxy_relay(adv, tx->ctx->addr); } /* Deliver to GATT Proxy Servers if necessary. */ if (IS_ENABLED(CONFIG_BT_MESH_PROXY_CLIENT)) { - (void)bt_mesh_proxy_cli_relay(buf); + (void)bt_mesh_proxy_cli_relay(adv); } - bt_mesh_adv_send(buf, cb, cb_data); + bt_mesh_adv_send(adv, cb, cb_data); done: - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return err; } @@ -684,7 +683,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, struct bt_mesh_net_rx *rx) { const struct bt_mesh_net_cred *cred; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint8_t transmit; if (rx->ctx.recv_ttl <= 1U) { @@ -711,10 +710,10 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, transmit = bt_mesh_net_transmit_get(); } - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY, transmit, K_NO_WAIT); - if (!buf) { - LOG_DBG("Out of relay buffers"); + if (!adv) { + LOG_DBG("Out of relay advs"); return; } @@ -722,23 +721,23 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, sbuf->data[1] &= 0x80; sbuf->data[1] |= rx->ctx.recv_ttl - 1U; - net_buf_add_mem(buf, sbuf->data, sbuf->len); + net_buf_simple_add_mem(&adv->b, sbuf->data, sbuf->len); cred = &rx->sub->keys[SUBNET_KEY_TX_IDX(rx->sub)].msg; - LOG_DBG("Relaying packet. TTL is now %u", TTL(buf->data)); + LOG_DBG("Relaying packet. TTL is now %u", TTL(adv->b.data)); /* Update NID if RX or RX was with friend credentials */ if (rx->friend_cred) { - buf->data[0] &= 0x80; /* Clear everything except IVI */ - buf->data[0] |= cred->nid; + adv->b.data[0] &= 0x80; /* Clear everything except IVI */ + adv->b.data[0] |= cred->nid; } /* We re-encrypt and obfuscate using the received IVI rather than * the normal TX IVI (which may be different) since the transport * layer nonce includes the IVI. */ - if (net_encrypt(&buf->b, cred, BT_MESH_NET_IVI_RX(rx), BT_MESH_NONCE_NETWORK)) { + if (net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_RX(rx), BT_MESH_NONCE_NETWORK)) { LOG_ERR("Re-encrypting failed"); goto done; } @@ -751,15 +750,15 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, (rx->friend_cred || bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED)) { - bt_mesh_proxy_relay(buf, rx->ctx.recv_dst); + bt_mesh_proxy_relay(adv, rx->ctx.recv_dst); } if (relay_to_adv(rx->net_if) || rx->friend_cred) { - bt_mesh_adv_send(buf, NULL, NULL); + bt_mesh_adv_send(adv, NULL, NULL); } done: - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } void bt_mesh_net_header_parse(struct net_buf_simple *buf, diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 04179a4dd491..28c21da3eaf2 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "adv.h" #include "subnet.h" #include @@ -291,7 +292,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update); int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, enum bt_mesh_nonce_type type); -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data); int bt_mesh_net_decode(struct net_buf_simple *in, enum bt_mesh_net_if net_if, diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index e273739ed72e..f723ff48c14b 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -11,7 +11,6 @@ #include #include "host/testing.h" #include "net.h" -#include "adv.h" #include "crypto.h" #include "beacon.h" #include "prov.h" @@ -101,8 +100,8 @@ struct pb_adv { /* Transaction timeout in seconds */ uint8_t timeout; - /* Pending outgoing buffer(s) */ - struct net_buf *buf[3]; + /* Pending outgoing adv(s) */ + struct bt_mesh_adv *adv[3]; prov_bearer_send_complete_t cb; @@ -170,24 +169,24 @@ static void free_segments(void) { int i; - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + for (i = 0; i < ARRAY_SIZE(link.tx.adv); i++) { + struct bt_mesh_adv *adv = link.tx.adv[i]; - if (!buf) { + if (!adv) { break; } - link.tx.buf[i] = NULL; + link.tx.adv[i] = NULL; /* Terminate active adv */ - if (BT_MESH_ADV(buf)->busy == 0U) { - bt_mesh_adv_buf_terminate(buf); + if (adv->ctx.busy == 0U) { + bt_mesh_adv_terminate(adv); } else { /* Mark as canceled */ - BT_MESH_ADV(buf)->busy = 0U; + adv->ctx.busy = 0U; } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } } @@ -200,7 +199,7 @@ static void prov_clear_tx(void) { LOG_DBG(""); - /* If this fails, the work handler will not find any buffers to send, + /* If this fails, the work handler will not find any advs to send, * and return without rescheduling. The work handler also checks the * LINK_ACTIVE flag, so if this call is part of reset_adv_link, it'll * exit early. @@ -254,19 +253,19 @@ static void close_link(enum prov_bearer_link_status reason) cb->link_closed(&bt_mesh_pb_adv, cb_data, reason); } -static struct net_buf *adv_buf_create(uint8_t retransmits) +static struct bt_mesh_adv *adv_create(uint8_t retransmits) { - struct net_buf *buf; + struct bt_mesh_adv *adv; - buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, + adv = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, BT_MESH_TRANSMIT(retransmits, 20), BUF_TIMEOUT); - if (!buf) { - LOG_ERR("Out of provisioning buffers"); + if (!adv) { + LOG_ERR("Out of provisioning advs"); return NULL; } - return buf; + return adv; } static void ack_complete(uint16_t duration, int err, void *user_data) @@ -328,7 +327,7 @@ static void gen_prov_ack_send(uint8_t xact_id) .start = ack_complete, }; const struct bt_mesh_send_cb *complete; - struct net_buf *buf; + struct bt_mesh_adv *adv; bool pending = atomic_test_and_set_bit(link.flags, ADV_ACK_PENDING); LOG_DBG("xact_id 0x%x", xact_id); @@ -338,8 +337,8 @@ static void gen_prov_ack_send(uint8_t xact_id) return; } - buf = adv_buf_create(RETRANSMITS_ACK); - if (!buf) { + adv = adv_create(RETRANSMITS_ACK); + if (!adv) { atomic_clear_bit(link.flags, ADV_ACK_PENDING); return; } @@ -351,12 +350,12 @@ static void gen_prov_ack_send(uint8_t xact_id) complete = &cb; } - net_buf_add_be32(buf, link.id); - net_buf_add_u8(buf, xact_id); - net_buf_add_u8(buf, GPC_ACK); + net_buf_simple_add_be32(&adv->b, link.id); + net_buf_simple_add_u8(&adv->b, xact_id); + net_buf_simple_add_u8(&adv->b, GPC_ACK); - bt_mesh_adv_send(buf, complete, NULL); - net_buf_unref(buf); + bt_mesh_adv_send(adv, complete, NULL); + bt_mesh_adv_unref(adv); } static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) @@ -431,7 +430,7 @@ static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf) { LOG_DBG("len %u", buf->len); - if (!link.tx.buf[0]) { + if (!link.tx.adv[0]) { return; } @@ -596,20 +595,20 @@ static void send_reliable(void) { int i; - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + for (i = 0; i < ARRAY_SIZE(link.tx.adv); i++) { + struct bt_mesh_adv *adv = link.tx.adv[i]; - if (!buf) { + if (!adv) { break; } - if (BT_MESH_ADV(buf)->busy) { + if (adv->ctx.busy) { continue; } - LOG_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + LOG_DBG("%u bytes: %s", adv->b.len, bt_hex(adv->b.data, adv->b.len)); - bt_mesh_adv_send(buf, NULL, NULL); + bt_mesh_adv_send(adv, NULL, NULL); } k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); @@ -633,30 +632,30 @@ static void prov_retransmit(struct k_work *work) send_reliable(); } -static struct net_buf *ctl_buf_create(uint8_t op, const void *data, uint8_t data_len, - uint8_t retransmits) +static struct bt_mesh_adv *ctl_adv_create(uint8_t op, const void *data, uint8_t data_len, + uint8_t retransmits) { - struct net_buf *buf; + struct bt_mesh_adv *adv; LOG_DBG("op 0x%02x data_len %u", op, data_len); - buf = adv_buf_create(retransmits); - if (!buf) { + adv = adv_create(retransmits); + if (!adv) { return NULL; } - net_buf_add_be32(buf, link.id); + net_buf_simple_add_be32(&adv->b, link.id); /* Transaction ID, always 0 for Bearer messages */ - net_buf_add_u8(buf, 0x00); - net_buf_add_u8(buf, GPC_CTL(op)); - net_buf_add_mem(buf, data, data_len); + net_buf_simple_add_u8(&adv->b, 0x00); + net_buf_simple_add_u8(&adv->b, GPC_CTL(op)); + net_buf_simple_add_mem(&adv->b, data, data_len); - return buf; + return adv; } -static int bearer_ctl_send(struct net_buf *buf) +static int bearer_ctl_send(struct bt_mesh_adv *adv) { - if (!buf) { + if (!adv) { return -ENOMEM; } @@ -664,23 +663,23 @@ static int bearer_ctl_send(struct net_buf *buf) k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); link.tx.start = k_uptime_get(); - link.tx.buf[0] = buf; + link.tx.adv[0] = adv; send_reliable(); return 0; } -static int bearer_ctl_send_unacked(struct net_buf *buf, void *user_data) +static int bearer_ctl_send_unacked(struct bt_mesh_adv *adv, void *user_data) { - if (!buf) { + if (!adv) { return -ENOMEM; } prov_clear_tx(); k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); - bt_mesh_adv_send(buf, &buf_sent_cb, user_data); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &buf_sent_cb, user_data); + bt_mesh_adv_unref(adv); return 0; } @@ -688,26 +687,26 @@ static int bearer_ctl_send_unacked(struct net_buf *buf, void *user_data) static int prov_send_adv(struct net_buf_simple *msg, prov_bearer_send_complete_t cb, void *cb_data) { - struct net_buf *start, *buf; + struct bt_mesh_adv *start, *adv; uint8_t seg_len, seg_id; prov_clear_tx(); k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); - start = adv_buf_create(RETRANSMITS_RELIABLE); + start = adv_create(RETRANSMITS_RELIABLE); if (!start) { return -ENOBUFS; } link.tx.id = next_transaction_id(link.tx.id); - net_buf_add_be32(start, link.id); - net_buf_add_u8(start, link.tx.id); + net_buf_simple_add_be32(&start->b, link.id); + net_buf_simple_add_u8(&start->b, link.tx.id); - net_buf_add_u8(start, GPC_START(last_seg(msg->len))); - net_buf_add_be16(start, msg->len); - net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len)); + net_buf_simple_add_u8(&start->b, GPC_START(last_seg(msg->len))); + net_buf_simple_add_be16(&start->b, msg->len); + net_buf_simple_add_u8(&start->b, bt_mesh_fcs_calc(msg->data, msg->len)); - link.tx.buf[0] = start; + link.tx.adv[0] = start; link.tx.cb = cb; link.tx.cb_data = cb_data; link.tx.start = k_uptime_get(); @@ -716,33 +715,33 @@ static int prov_send_adv(struct net_buf_simple *msg, seg_len = MIN(msg->len, START_PAYLOAD_MAX); LOG_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len)); - net_buf_add_mem(start, msg->data, seg_len); + net_buf_simple_add_mem(&start->b, msg->data, seg_len); net_buf_simple_pull(msg, seg_len); - buf = start; + adv = start; for (seg_id = 1U; msg->len > 0; seg_id++) { - if (seg_id >= ARRAY_SIZE(link.tx.buf)) { + if (seg_id >= ARRAY_SIZE(link.tx.adv)) { LOG_ERR("Too big message"); free_segments(); return -E2BIG; } - buf = adv_buf_create(RETRANSMITS_RELIABLE); - if (!buf) { + adv = adv_create(RETRANSMITS_RELIABLE); + if (!adv) { free_segments(); return -ENOBUFS; } - link.tx.buf[seg_id] = buf; + link.tx.adv[seg_id] = adv; seg_len = MIN(msg->len, CONT_PAYLOAD_MAX); LOG_DBG("seg %u len %u: %s", seg_id, seg_len, bt_hex(msg->data, seg_len)); - net_buf_add_be32(buf, link.id); - net_buf_add_u8(buf, link.tx.id); - net_buf_add_u8(buf, GPC_CONT(seg_id)); - net_buf_add_mem(buf, msg->data, seg_len); + net_buf_simple_add_be32(&adv->b, link.id); + net_buf_simple_add_u8(&adv->b, link.tx.id); + net_buf_simple_add_u8(&adv->b, GPC_CONT(seg_id)); + net_buf_simple_add_mem(&adv->b, msg->data, seg_len); net_buf_simple_pull(msg, seg_len); } @@ -776,7 +775,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) LOG_DBG("Resending link ack"); /* Ignore errors, message will be attempted again if we keep receiving link open: */ (void)bearer_ctl_send_unacked( - ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), + ctl_adv_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), (void *)PROV_BEARER_LINK_STATUS_SUCCESS); return; } @@ -791,7 +790,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) net_buf_simple_reset(link.rx.buf); err = bearer_ctl_send_unacked( - ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), + ctl_adv_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), (void *)PROV_BEARER_LINK_STATUS_SUCCESS); if (err) { reset_adv_link(); @@ -891,7 +890,7 @@ static int prov_link_open(const uint8_t uuid[16], uint8_t timeout, net_buf_simple_reset(link.rx.buf); - return bearer_ctl_send(ctl_buf_create(LINK_OPEN, uuid, 16, RETRANSMITS_RELIABLE)); + return bearer_ctl_send(ctl_adv_create(LINK_OPEN, uuid, 16, RETRANSMITS_RELIABLE)); } static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) @@ -936,7 +935,7 @@ static void prov_link_close(enum prov_bearer_link_status status) link.tx.timeout = CLOSING_TIMEOUT; /* Ignore errors, the link will time out eventually if this doesn't get sent */ bearer_ctl_send_unacked( - ctl_buf_create(LINK_CLOSE, &status, 1, RETRANSMITS_LINK_CLOSE), + ctl_adv_create(LINK_CLOSE, &status, 1, RETRANSMITS_LINK_CLOSE), (void *)status); } diff --git a/subsys/bluetooth/mesh/pb_gatt.c b/subsys/bluetooth/mesh/pb_gatt.c index f8acc8f6c5a7..849914f4b5f2 100644 --- a/subsys/bluetooth/mesh/pb_gatt.c +++ b/subsys/bluetooth/mesh/pb_gatt.c @@ -8,7 +8,6 @@ #include #include "net.h" #include "proxy.h" -#include "adv.h" #include "prov.h" #include "pb_gatt.h" #include "proxy_msg.h" diff --git a/subsys/bluetooth/mesh/pb_gatt_cli.c b/subsys/bluetooth/mesh/pb_gatt_cli.c index 9231cc0f0b15..bf7dc14029ac 100644 --- a/subsys/bluetooth/mesh/pb_gatt_cli.c +++ b/subsys/bluetooth/mesh/pb_gatt_cli.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/pb_gatt_srv.c b/subsys/bluetooth/mesh/pb_gatt_srv.c index f6d9298fc782..f4fdac53570a 100644 --- a/subsys/bluetooth/mesh/pb_gatt_srv.c +++ b/subsys/bluetooth/mesh/pb_gatt_srv.c @@ -17,7 +17,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index 5b5e62f17363..98be589fc226 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -5,7 +5,6 @@ */ #include #include "net.h" -#include "adv.h" #include #include "proxy.h" #include "foundation.h" diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/provisionee.c similarity index 98% rename from subsys/bluetooth/mesh/prov_device.c rename to subsys/bluetooth/mesh/provisionee.c index af890396ac7d..dcecb5838f05 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/provisionee.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -33,9 +32,9 @@ #include "settings.h" #include "rpr.h" -#define LOG_LEVEL CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL +#define LOG_LEVEL CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL #include -LOG_MODULE_REGISTER(bt_mesh_prov_device); +LOG_MODULE_REGISTER(bt_mesh_provisionee); static void reprovision_fail(void); @@ -697,8 +696,8 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } -#if defined(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) - if (CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL > 2) { +#if defined(CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL) + if (CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL > 2) { struct bt_uuid_128 uuid = { .uuid = { BT_UUID_TYPE_128 } }; sys_memcpy_swap(uuid.val, bt_mesh_prov->uuid, 16); diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index aba2449892fa..08b3f8bb8f17 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -21,7 +21,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -47,7 +46,7 @@ static struct { uint8_t attention_duration; uint8_t uuid[16]; uint8_t new_dev_key[16]; -} prov_device; +} provisionee; static void send_pub_key(void); static void prov_dh_key_gen(void); @@ -55,8 +54,8 @@ static void prov_dh_key_gen(void); static int reset_state(void) { if (!atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION) && - prov_device.node != NULL) { - bt_mesh_cdb_node_del(prov_device.node, false); + provisionee.node != NULL) { + bt_mesh_cdb_node_del(provisionee.node, false); } return bt_mesh_prov_reset_state(); @@ -87,9 +86,9 @@ static void send_invite(void) LOG_DBG(""); bt_mesh_prov_buf_init(&inv, PROV_INVITE); - net_buf_simple_add_u8(&inv, prov_device.attention_duration); + net_buf_simple_add_u8(&inv, provisionee.attention_duration); - memcpy(bt_mesh_prov_link.conf_inputs.invite, &prov_device.attention_duration, + memcpy(bt_mesh_prov_link.conf_inputs.invite, &provisionee.attention_duration, PDU_LEN_INVITE); if (bt_mesh_prov_send(&inv, NULL)) { @@ -247,8 +246,8 @@ static void prov_capabilities(const uint8_t *data) LOG_DBG("Input OOB Size: %u", caps.input_size); LOG_DBG("Input OOB Action: 0x%04x", caps.input_actions); - prov_device.elem_count = caps.elem_count; - if (prov_device.elem_count == 0) { + provisionee.elem_count = caps.elem_count; + if (provisionee.elem_count == 0) { LOG_ERR("Invalid number of elements"); prov_fail(PROV_ERR_NVAL_FMT); return; @@ -272,7 +271,7 @@ static void prov_capabilities(const uint8_t *data) if (atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION)) { if (!bt_mesh_prov_link.addr) { bt_mesh_prov_link.addr = bt_mesh_cdb_free_addr_get( - prov_device.elem_count); + provisionee.elem_count); if (!bt_mesh_prov_link.addr) { LOG_ERR("Failed allocating address for node"); prov_fail(PROV_ERR_ADDR); @@ -280,19 +279,19 @@ static void prov_capabilities(const uint8_t *data) } } } else { - prov_device.node = - bt_mesh_cdb_node_alloc(prov_device.uuid, + provisionee.node = + bt_mesh_cdb_node_alloc(provisionee.uuid, bt_mesh_prov_link.addr, - prov_device.elem_count, - prov_device.net_idx); - if (prov_device.node == NULL) { + provisionee.elem_count, + provisionee.net_idx); + if (provisionee.node == NULL) { LOG_ERR("Failed allocating node 0x%04x", bt_mesh_prov_link.addr); prov_fail(PROV_ERR_RESOURCES); return; } /* Address might change in the alloc call */ - bt_mesh_prov_link.addr = prov_device.node->addr; + bt_mesh_prov_link.addr = provisionee.node->addr; } memcpy(bt_mesh_prov_link.conf_inputs.capabilities, data, PDU_LEN_CAPABILITIES); @@ -518,16 +517,16 @@ static void send_prov_data(void) LOG_DBG("Nonce: %s", bt_hex(nonce, 13)); err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey, - bt_mesh_prov_link.prov_salt, prov_device.new_dev_key); + bt_mesh_prov_link.prov_salt, provisionee.new_dev_key); if (err) { LOG_ERR("Unable to generate device key"); prov_fail(PROV_ERR_UNEXP_ERR); goto session_key_destructor; } - sub = bt_mesh_cdb_subnet_get(prov_device.node->net_idx); + sub = bt_mesh_cdb_subnet_get(provisionee.node->net_idx); if (sub == NULL) { - LOG_ERR("No subnet with net_idx %u", prov_device.node->net_idx); + LOG_ERR("No subnet with net_idx %u", provisionee.node->net_idx); prov_fail(PROV_ERR_UNEXP_ERR); goto session_key_destructor; } @@ -541,14 +540,14 @@ static void send_prov_data(void) bt_mesh_prov_buf_init(&pdu, PROV_DATA); net_buf_simple_add_mem(&pdu, net_key, sizeof(net_key)); - net_buf_simple_add_be16(&pdu, prov_device.node->net_idx); + net_buf_simple_add_be16(&pdu, provisionee.node->net_idx); net_buf_simple_add_u8(&pdu, bt_mesh_cdb_subnet_flags(sub)); net_buf_simple_add_be32(&pdu, bt_mesh_cdb.iv_index); net_buf_simple_add_be16(&pdu, bt_mesh_prov_link.addr); net_buf_simple_add(&pdu, 8); /* For MIC */ LOG_DBG("net_idx %u, iv_index 0x%08x, addr 0x%04x", - prov_device.node->net_idx, bt_mesh.iv_index, + provisionee.node->net_idx, bt_mesh.iv_index, bt_mesh_prov_link.addr); err = bt_mesh_prov_encrypt(&session_key, nonce, &pdu.data[1], @@ -572,10 +571,10 @@ static void send_prov_data(void) static void prov_complete(const uint8_t *data) { - struct bt_mesh_cdb_node *node = prov_device.node; + struct bt_mesh_cdb_node *node = provisionee.node; LOG_DBG("key %s, net_idx %u, num_elem %u, addr 0x%04x", - bt_hex(&prov_device.new_dev_key, 16), node->net_idx, + bt_hex(&provisionee.new_dev_key, 16), node->net_idx, node->num_elem, node->addr); bt_mesh_prov_link.expect = PROV_NO_PDU; @@ -587,15 +586,15 @@ static void prov_complete(const uint8_t *data) static void prov_node_add(void) { LOG_DBG(""); - struct bt_mesh_cdb_node *node = prov_device.node; + struct bt_mesh_cdb_node *node = provisionee.node; int err; if (atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION)) { bt_mesh_cdb_node_update(node, bt_mesh_prov_link.addr, - prov_device.elem_count); + provisionee.elem_count); } - err = bt_mesh_cdb_node_key_import(node, prov_device.new_dev_key); + err = bt_mesh_cdb_node_key_import(node, provisionee.new_dev_key); if (err) { LOG_ERR("Failed to import node device key"); return; @@ -605,7 +604,7 @@ static void prov_node_add(void) bt_mesh_cdb_node_store(node); } - prov_device.node = NULL; + provisionee.node = NULL; if (bt_mesh_prov->node_added) { bt_mesh_prov->node_added(node->net_idx, node->uuid, node->addr, @@ -808,7 +807,7 @@ static int link_open(const uint8_t *uuid, const struct prov_bearer *bearer, } if (uuid) { - memcpy(prov_device.uuid, uuid, 16); + memcpy(provisionee.uuid, uuid, 16); struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } }; @@ -824,8 +823,8 @@ static int link_open(const uint8_t *uuid, const struct prov_bearer *bearer, bt_mesh_prov_link.addr = addr; bt_mesh_prov_link.bearer = bearer; bt_mesh_prov_link.role = &role_provisioner; - prov_device.net_idx = net_idx; - prov_device.attention_duration = attention_duration; + provisionee.net_idx = net_idx; + provisionee.attention_duration = attention_duration; err = bt_mesh_prov_link.bearer->link_open( uuid, timeout, bt_mesh_prov_bearer_cb_get(), bearer_cb_data); @@ -878,15 +877,15 @@ static int reprovision_local_client_server(uint16_t addr) } LOG_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x", - prov_device.node->net_idx, bt_mesh_cdb.iv_index, addr); + provisionee.node->net_idx, bt_mesh_cdb.iv_index, addr); atomic_set_bit(bt_mesh_prov_link.flags, REPROVISION); atomic_set_bit(bt_mesh_prov_link.flags, PROVISIONER); bt_mesh_prov_link.addr = addr; bt_mesh_prov_link.bearer = &pb_remote_cli; bt_mesh_prov_link.role = &role_provisioner; - prov_device.net_idx = prov_device.node->net_idx; - prov_device.attention_duration = 0; + provisionee.net_idx = provisionee.node->net_idx; + provisionee.attention_duration = 0; if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) && bt_mesh_prov->public_key_be && bt_mesh_prov->private_key_be) { @@ -909,13 +908,13 @@ static int reprovision_local_client_server(uint16_t addr) LOG_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, DH_KEY_SIZE)); err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey, - bt_mesh_prov_link.prov_salt, prov_device.new_dev_key); + bt_mesh_prov_link.prov_salt, provisionee.new_dev_key); if (err) { LOG_ERR("Unable to generate device key"); return err; } - bt_mesh_dev_key_cand(prov_device.new_dev_key); + bt_mesh_dev_key_cand(provisionee.new_dev_key); /* Mark the link that was never opened as closed. */ atomic_set_bit(bt_mesh_prov_link.flags, COMPLETE); bt_mesh_reprovision(addr); @@ -944,8 +943,8 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, ctx.refresh = BT_MESH_RPR_NODE_REFRESH_DEVKEY; } - prov_device.node = bt_mesh_cdb_node_get(srv->addr); - if (!prov_device.node) { + provisionee.node = bt_mesh_cdb_node_get(srv->addr); + if (!provisionee.node) { LOG_ERR("No CDB node for 0x%04x", srv->addr); return -ENOENT; } @@ -955,7 +954,7 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, return reprovision_local_client_server(addr); } - return link_open(NULL, &pb_remote_cli, prov_device.node->net_idx, addr, + return link_open(NULL, &pb_remote_cli, provisionee.node->net_idx, addr, 0, &ctx, 0); } #endif diff --git a/subsys/bluetooth/mesh/proxy.h b/subsys/bluetooth/mesh/proxy.h index a2f6bb45ff61..34a119c3df6f 100644 --- a/subsys/bluetooth/mesh/proxy.h +++ b/subsys/bluetooth/mesh/proxy.h @@ -34,6 +34,6 @@ int bt_mesh_proxy_adv_start(void); void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub, bool private); void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); -bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst); +bool bt_mesh_proxy_relay(struct bt_mesh_adv *adv, uint16_t dst); void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, uint16_t addr); uint8_t bt_mesh_proxy_srv_connected_cnt(void); diff --git a/subsys/bluetooth/mesh/proxy_cli.c b/subsys/bluetooth/mesh/proxy_cli.c index a0a25751b413..5dd6b02361f3 100644 --- a/subsys/bluetooth/mesh/proxy_cli.c +++ b/subsys/bluetooth/mesh/proxy_cli.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -79,7 +78,7 @@ static struct bt_mesh_proxy_server *find_proxy_srv_by_conn(struct bt_conn *conn) return NULL; } -bool bt_mesh_proxy_cli_relay(struct net_buf *buf) +bool bt_mesh_proxy_cli_relay(struct bt_mesh_adv *adv) { bool relayed = false; int i; @@ -91,7 +90,7 @@ bool bt_mesh_proxy_cli_relay(struct net_buf *buf) continue; } - if (bt_mesh_proxy_relay_send(server->role->conn, buf)) { + if (bt_mesh_proxy_relay_send(server->role->conn, adv)) { continue; } diff --git a/subsys/bluetooth/mesh/proxy_cli.h b/subsys/bluetooth/mesh/proxy_cli.h index 8c1fae10e84a..c0b69f4aaf61 100644 --- a/subsys/bluetooth/mesh/proxy_cli.h +++ b/subsys/bluetooth/mesh/proxy_cli.h @@ -8,6 +8,6 @@ void bt_mesh_proxy_cli_adv_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf); -bool bt_mesh_proxy_cli_relay(struct net_buf *buf); +bool bt_mesh_proxy_cli_relay(struct bt_mesh_adv *adv); bool bt_mesh_proxy_cli_is_connected(uint16_t net_idx); diff --git a/subsys/bluetooth/mesh/proxy_msg.c b/subsys/bluetooth/mesh/proxy_msg.c index 025909e0503b..b2fa113d4568 100644 --- a/subsys/bluetooth/mesh/proxy_msg.c +++ b/subsys/bluetooth/mesh/proxy_msg.c @@ -21,7 +21,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -196,12 +195,12 @@ int bt_mesh_proxy_msg_send(struct bt_conn *conn, uint8_t type, static void buf_send_end(struct bt_conn *conn, void *user_data) { - struct net_buf *buf = user_data; + struct bt_mesh_adv *adv = user_data; - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } -int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) +int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv) { int err; @@ -211,12 +210,12 @@ int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) * so we need to make a copy. */ net_buf_simple_reserve(&msg, 1); - net_buf_simple_add_mem(&msg, buf->data, buf->len); + net_buf_simple_add_mem(&msg, adv->b.data, adv->b.len); err = bt_mesh_proxy_msg_send(conn, BT_MESH_PROXY_NET_PDU, - &msg, buf_send_end, net_buf_ref(buf)); + &msg, buf_send_end, bt_mesh_adv_ref(adv)); - bt_mesh_adv_send_start(0, err, BT_MESH_ADV(buf)); + bt_mesh_adv_send_start(0, err, &adv->ctx); if (err) { LOG_ERR("Failed to send proxy message (err %d)", err); @@ -225,7 +224,7 @@ int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) * which is just opaque data to segment_and send) reference given * to segment_and_send() here. */ - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } return err; diff --git a/subsys/bluetooth/mesh/proxy_msg.h b/subsys/bluetooth/mesh/proxy_msg.h index 7d4bd51ae4f7..7ad4be7ae5d3 100644 --- a/subsys/bluetooth/mesh/proxy_msg.h +++ b/subsys/bluetooth/mesh/proxy_msg.h @@ -51,7 +51,7 @@ ssize_t bt_mesh_proxy_msg_recv(struct bt_conn *conn, int bt_mesh_proxy_msg_send(struct bt_conn *conn, uint8_t type, struct net_buf_simple *msg, bt_gatt_complete_func_t end, void *user_data); -int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf); +int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv); struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(struct bt_conn *conn, proxy_send_cb_t send, proxy_recv_cb_t recv); diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 571144ceaedd..a903d94ffa99 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -626,7 +625,7 @@ static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration) return 0; } -static bool advertise_subnet(struct bt_mesh_subnet *sub) +static bool is_sub_proxy_active(struct bt_mesh_subnet *sub) { if (sub->net_idx == BT_MESH_KEY_UNUSED) { return false; @@ -634,201 +633,252 @@ static bool advertise_subnet(struct bt_mesh_subnet *sub) return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - sub->solicited || + (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited) || #endif bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); } -static struct bt_mesh_subnet *next_sub(void) +static bool active_proxy_sub_cnt_cb(struct bt_mesh_subnet *sub, void *cb_data) { - struct bt_mesh_subnet *sub = NULL; + int *cnt = cb_data; - if (!beacon_sub) { - beacon_sub = bt_mesh_subnet_next(NULL); - if (!beacon_sub) { - /* No valid subnets */ - return NULL; - } + if (is_sub_proxy_active(sub)) { + (*cnt)++; } - sub = beacon_sub; - do { - if (advertise_subnet(sub)) { - beacon_sub = sub; - return sub; - } + /* Don't stop until we've visited all subnets. + * We're only using the "find" variant of the subnet iteration to get a context parameter. + */ + return false; +} + +static int active_proxy_sub_cnt_get(void) +{ + int cnt = 0; - sub = bt_mesh_subnet_next(sub); - } while (sub != beacon_sub); + (void)bt_mesh_subnet_find(active_proxy_sub_cnt_cb, &cnt); - /* No subnets to advertise on */ - return NULL; + return cnt; } -static bool sub_count_cb(struct bt_mesh_subnet *sub, void *cb_data) +static void proxy_adv_timeout_eval(struct bt_mesh_subnet *sub) { - int *count = cb_data; - - if (advertise_subnet(sub)) { - (*count)++; + int32_t time_passed; + + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + time_passed = k_uptime_get_32() - sub->node_id_start; + if (time_passed > (NODE_ID_TIMEOUT - MSEC_PER_SEC)) { + bt_mesh_proxy_identity_stop(sub); + LOG_DBG("Node ID stopped for subnet %d after %dms", sub->net_idx, + time_passed); + } } - /* Don't stop until we've visited all subnets. - * We're only using the "find" variant of the subnet iteration to get a context parameter. - */ - return false; +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + if (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited && sub->priv_net_id_sent) { + time_passed = k_uptime_get_32() - sub->priv_net_id_sent; + if (time_passed > ((MSEC_PER_SEC * bt_mesh_od_priv_proxy_get()) - MSEC_PER_SEC)) { + sub->priv_net_id_sent = 0; + sub->solicited = false; + LOG_DBG("Private Network ID stopped for subnet %d after %dms on " + "solicitation", + sub->net_idx, time_passed); + } + } +#endif } -static int sub_count(void) +enum proxy_adv_evt { + NET_ID, + PRIV_NET_ID, + NODE_ID, + PRIV_NODE_ID, + OD_PRIV_NET_ID, +}; + +struct proxy_adv_request { + int32_t duration; + enum proxy_adv_evt evt; +}; + +static bool proxy_adv_request_get(struct bt_mesh_subnet *sub, struct proxy_adv_request *request) { - int count = 0; + if (!sub) { + return false; + } - (void)bt_mesh_subnet_find(sub_count_cb, &count); + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + return false; + } - return count; -} + /** The priority for proxy adv is first solicitation, then Node Identity, + * and lastly Network ID. Network ID is prioritized last since, in many + * cases, another device can fulfill the same demand. Solicitation is + * prioritized first since legacy devices are dependent on this to + * connect to the network. + */ #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) -static void gatt_proxy_solicited(struct bt_mesh_subnet *sub) -{ - int64_t now = k_uptime_get(); - int64_t timeout = 0; - int32_t remaining; - - if (sub->priv_net_id_sent > 0) { - timeout = sub->priv_net_id_sent + - MSEC_PER_SEC * (int64_t) bt_mesh_od_priv_proxy_get(); - remaining = MIN(timeout - now, INT32_MAX); - } else { - remaining = MSEC_PER_SEC * bt_mesh_od_priv_proxy_get(); + if (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited) { + int32_t timeout = MSEC_PER_SEC * (int32_t)bt_mesh_od_priv_proxy_get(); + + request->evt = OD_PRIV_NET_ID; + request->duration = !sub->priv_net_id_sent + ? timeout + : timeout - (k_uptime_get_32() - sub->priv_net_id_sent); + return true; } +#endif - if ((timeout > 0 && now > timeout) || (remaining / MSEC_PER_SEC < 1)) { - LOG_DBG("Advertising Private Network ID timed out " - "after solicitation"); - sub->priv_net_id_sent = 0; - sub->solicited = false; - } else { - LOG_DBG("Advertising Private Network ID for %ds" - "(%d remaining)", - bt_mesh_od_priv_proxy_get(), - remaining / MSEC_PER_SEC); - priv_net_id_adv(sub, remaining); + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + request->duration = NODE_ID_TIMEOUT - (k_uptime_get_32() - sub->node_id_start); + request->evt = +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + sub->priv_beacon_ctx.node_id ? PRIV_NODE_ID : +#endif + NODE_ID; - if (!sub->priv_net_id_sent) { - sub->priv_net_id_sent = now; - } + return true; + } + + if (bt_mesh_priv_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { + request->evt = PRIV_NET_ID; + request->duration = PROXY_RANDOM_UPDATE_INTERVAL; + return true; } + + if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { + request->evt = NET_ID; + request->duration = SYS_FOREVER_MS; + return true; + } + + return false; } -#endif -static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) +static struct bt_mesh_subnet *adv_sub_get_next(struct bt_mesh_subnet *sub_start, + struct proxy_adv_request *request) { - int32_t remaining = SYS_FOREVER_MS; - int subnet_count; - int err = -EBUSY; - bool planned = false; + struct bt_mesh_subnet *sub_temp = bt_mesh_subnet_next(sub_start); + + do { + if (proxy_adv_request_get(sub_temp, request)) { + return sub_temp; + } + + sub_temp = bt_mesh_subnet_next(sub_temp); + } while (sub_temp != sub_start); + + return NULL; +} + +static struct { + int32_t start; + struct bt_mesh_subnet *sub; + struct proxy_adv_request request; +} sub_adv; + +static int gatt_proxy_advertise(void) +{ + int err; + + int32_t max_adv_duration; + int cnt; + struct bt_mesh_subnet *sub; + struct proxy_adv_request request; LOG_DBG(""); + /* Close proxy activity that has timed out on all subnets */ + bt_mesh_subnet_foreach(proxy_adv_timeout_eval); + if (!bt_mesh_proxy_has_avail_conn()) { LOG_DBG("Connectable advertising deferred (max connections)"); return -ENOMEM; } - sub = beacon_sub ? beacon_sub : bt_mesh_subnet_next(beacon_sub); - if (!sub) { - LOG_WRN("No subnets to advertise on"); + cnt = active_proxy_sub_cnt_get(); + if (!cnt) { + LOG_DBG("No subnets to advertise proxy on"); return -ENOENT; - } - - subnet_count = sub_count(); - LOG_DBG("sub_count %u", subnet_count); - if (subnet_count > 1) { - int32_t max_timeout; + } else if (cnt > 1) { + /** There is more than one subnet that requires proxy adv, + * and the adv resources must be shared. + */ /* We use NODE_ID_TIMEOUT as a starting point since it may * be less than 60 seconds. Divide this period into at least - * 6 slices, but make sure that a slice is at least one + * 6 slices, but make sure that a slice is more than one * second long (to avoid excessive rotation). */ - max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6); - max_timeout = MAX(max_timeout, 1 * MSEC_PER_SEC); - - if (remaining > max_timeout || remaining == SYS_FOREVER_MS) { - remaining = max_timeout; + max_adv_duration = NODE_ID_TIMEOUT / MAX(cnt, 6); + max_adv_duration = MAX(max_adv_duration, MSEC_PER_SEC + 20); + + /* Check if the previous subnet finished its allocated timeslot */ + if ((sub_adv.request.duration != SYS_FOREVER_MS) && + proxy_adv_request_get(sub_adv.sub, &request) && + (sub_adv.request.evt == request.evt)) { + int32_t time_passed = k_uptime_get_32() - sub_adv.start; + + if (time_passed < sub_adv.request.duration && + ((sub_adv.request.duration - time_passed) >= MSEC_PER_SEC)) { + sub = sub_adv.sub; + request.duration = sub_adv.request.duration - time_passed; + goto end; + } } } - for (int i = 0; i < subnet_count; i++) { - - if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { - uint32_t active = k_uptime_get_32() - sub->node_id_start; - bool priv_node_id = false; - - if (active < NODE_ID_TIMEOUT) { - remaining = MIN(remaining, NODE_ID_TIMEOUT - active); - LOG_DBG("Node ID active for %u ms, %d ms remaining", - active, remaining); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - priv_node_id = sub->priv_beacon_ctx.node_id; -#endif - if (priv_node_id) { - err = priv_node_id_adv(sub, remaining); - } else { - err = node_id_adv(sub, remaining); - } - planned = true; - } else { - bt_mesh_proxy_identity_stop(sub); - LOG_DBG("Node ID stopped"); - } - } + sub = adv_sub_get_next(sub_adv.sub, &request); + if (!sub) { + LOG_ERR("Could not find subnet to advertise"); + return -ENOENT; + } +end: + if (cnt > 1) { + request.duration = (request.duration == SYS_FOREVER_MS) + ? max_adv_duration + : MIN(request.duration, max_adv_duration); + } - /* MshPRTv1.1: section 7.2.2.2.1: - * "A node that does not support the Proxy feature or - * has the GATT Proxy state disabled shall not advertise with Network ID." - */ - if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { - if (IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS) && - (bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED)) { - /* MshPRTv1.1: 7.2.2.2.4: The Random - * field should be updated every 10 minutes. Limit advertising to - * 10 minutes to ensure regeneration of a new random value at least - * that often. - */ - if (remaining == SYS_FOREVER_MS || - remaining > PROXY_RANDOM_UPDATE_INTERVAL) { - remaining = PROXY_RANDOM_UPDATE_INTERVAL; - } - - err = priv_net_id_adv(sub, remaining); - planned = true; - } else if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { - err = net_id_adv(sub, remaining); - planned = true; - } + /* Save current state for next iteration */ + sub_adv.start = k_uptime_get_32(); + sub_adv.sub = sub; + sub_adv.request = request; + switch (request.evt) { + case NET_ID: + err = net_id_adv(sub, request.duration); + break; #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - else if (bt_mesh_od_priv_proxy_get() > 0 && - sub->solicited) { - gatt_proxy_solicited(sub); - } -#endif - } - - beacon_sub = bt_mesh_subnet_next(sub); - - if (planned) { - LOG_DBG("Advertising %d ms for net_idx 0x%04x", remaining, sub->net_idx); - return err; + case OD_PRIV_NET_ID: + if (!sub->priv_net_id_sent) { + sub->priv_net_id_sent = k_uptime_get(); } + /* Fall through */ +#endif + case PRIV_NET_ID: + err = priv_net_id_adv(sub, request.duration); + break; + case NODE_ID: + err = node_id_adv(sub, request.duration); + break; + case PRIV_NODE_ID: + err = priv_node_id_adv(sub, request.duration); + break; + default: + LOG_ERR("Unexpected proxy adv evt: %d", request.evt); + return -ENODEV; + } - sub = beacon_sub; + if (err) { + LOG_ERR("Advertising proxy failed (err: %d)", err); + return err; } - return 0; + LOG_DBG("Advertising %d ms for net_idx 0x%04x", request.duration, sub->net_idx); + return err; } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) @@ -925,6 +975,8 @@ static void svc_reg_work_handler(struct k_work *work) int bt_mesh_proxy_gatt_enable(void) { + int err; + LOG_DBG(""); if (!bt_mesh_is_provisioned()) { @@ -936,7 +988,13 @@ int bt_mesh_proxy_gatt_enable(void) } svc_reg_attempts = PROXY_SVC_REG_ATTEMPTS; - return k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT); + err = k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT); + if (err < 0) { + LOG_ERR("Enabling GATT proxy failed (err %d)", err); + return err; + } + + return 0; } void bt_mesh_proxy_gatt_disconnect(void) @@ -1022,12 +1080,12 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return false; } -bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst) +bool bt_mesh_proxy_relay(struct bt_mesh_adv *adv, uint16_t dst) { bool relayed = false; int i; - LOG_DBG("%u bytes to dst 0x%04x", buf->len, dst); + LOG_DBG("%u bytes to dst 0x%04x", adv->b.len, dst); for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; @@ -1040,7 +1098,7 @@ bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst) continue; } - if (bt_mesh_proxy_relay_send(client->cli->conn, buf)) { + if (bt_mesh_proxy_relay_send(client->cli->conn, adv)) { continue; } @@ -1153,7 +1211,7 @@ int bt_mesh_proxy_adv_start(void) return -ENOTSUP; } - return gatt_proxy_advertise(next_sub()); + return gatt_proxy_advertise(); } BT_CONN_CB_DEFINE(conn_callbacks) = { diff --git a/subsys/bluetooth/mesh/rpl.c b/subsys/bluetooth/mesh/rpl.c index b31135308542..df67ddf9d2e1 100644 --- a/subsys/bluetooth/mesh/rpl.c +++ b/subsys/bluetooth/mesh/rpl.c @@ -20,7 +20,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "settings.h" @@ -41,8 +40,9 @@ static ATOMIC_DEFINE(store, CONFIG_BT_MESH_CRPL); enum { PENDING_CLEAR, PENDING_RESET, + RPL_FLAGS_COUNT, }; -static atomic_t rpl_flags; +static ATOMIC_DEFINE(rpl_flags, RPL_FLAGS_COUNT); static inline int rpl_idx(const struct bt_mesh_rpl *rpl) { @@ -133,7 +133,7 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, /* Existing slot for given address */ if (rpl->src == rx->ctx.addr) { if (!rpl->old_iv && - atomic_test_bit(&rpl_flags, PENDING_RESET) && + atomic_test_bit(rpl_flags, PENDING_RESET) && !atomic_test_bit(store, i)) { /* Until rpl reset is finished, entry with old_iv == false and * without "store" bit set will be removed, therefore it can be @@ -178,7 +178,7 @@ void bt_mesh_rpl_clear(void) return; } - atomic_set_bit(&rpl_flags, PENDING_CLEAR); + atomic_set_bit(rpl_flags, PENDING_CLEAR); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } @@ -233,7 +233,7 @@ void bt_mesh_rpl_reset(void) } if (i != 0) { - atomic_set_bit(&rpl_flags, PENDING_RESET); + atomic_set_bit(rpl_flags, PENDING_RESET); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } } else { @@ -358,8 +358,8 @@ void bt_mesh_rpl_pending_store(uint16_t addr) bt_mesh_settings_store_cancel(BT_MESH_SETTINGS_RPL_PENDING); } - clr = atomic_test_and_clear_bit(&rpl_flags, PENDING_CLEAR); - rst = atomic_test_bit(&rpl_flags, PENDING_RESET); + clr = atomic_test_and_clear_bit(rpl_flags, PENDING_CLEAR); + rst = atomic_test_bit(rpl_flags, PENDING_RESET); for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { struct bt_mesh_rpl *rpl = &replay_list[i]; @@ -398,7 +398,7 @@ void bt_mesh_rpl_pending_store(uint16_t addr) } } - atomic_clear_bit(&rpl_flags, PENDING_RESET); + atomic_clear_bit(rpl_flags, PENDING_RESET); if (addr == BT_MESH_ADDR_ALL_NODES) { (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index 9813842a367d..e97df35f28fd 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -14,7 +14,6 @@ #include #include #include "access.h" -#include "adv.h" #include "prov.h" #include "crypto.h" #include "rpr.h" diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 771aad9b9460..8ec9c66481ac 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -88,7 +88,7 @@ static int mesh_commit(void) } if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) { - /* The Bluetooth mesh settings loader calls bt_mesh_start() immediately + /* The Bluetooth Mesh settings loader calls bt_mesh_start() immediately * after loading the settings. This is not intended to work before * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings * tree to be loaded after @ref bt_enable is completed, so this handler @@ -186,8 +186,7 @@ static void store_pending(struct k_work *work) { LOG_DBG(""); - if (IS_ENABLED(CONFIG_BT_MESH_RPL_STORAGE_MODE_SETTINGS) && - atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING)) { + if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING)) { bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES); } diff --git a/subsys/bluetooth/mesh/shell/Kconfig b/subsys/bluetooth/mesh/shell/Kconfig index 5e1e43f0057b..46671c3bfaa5 100644 --- a/subsys/bluetooth/mesh/shell/Kconfig +++ b/subsys/bluetooth/mesh/shell/Kconfig @@ -1,13 +1,13 @@ -# Bluetooth mesh shell configuration options +# Bluetooth Mesh shell configuration options # Copyright (c) 2022 Nordic Semiconductor # SPDX-License-Identifier: Apache-2.0 menuconfig BT_MESH_SHELL - bool "Bluetooth mesh shell" + bool "Bluetooth Mesh shell" select SHELL help - Activate shell module that provides Bluetooth mesh commands to + Activate shell module that provides Bluetooth Mesh commands to the console. if BT_MESH_SHELL @@ -24,7 +24,7 @@ config BT_MESH_SHELL_PROV_CTX_INSTANCE depends on BT_MESH_SHELL_PROV help This option enables the provisioning context instance in the - Bluetooth mesh shell module together with several provisioning + Bluetooth Mesh shell module together with several provisioning commands and target utility features. To use the provisioning context instance, use bt_mesh_shell_prov in the initialization of mesh. @@ -54,7 +54,7 @@ config BT_MESH_SHELL_HEALTH_SRV_INSTANCE depends on BT_MESH_SHELL_TEST help This option enables Health Server model instance in the - Bluetooth mesh shell module together with fault controlling + Bluetooth Mesh shell module together with fault controlling shell commands. To use the model instance, add bt_mesh_shell_health_srv to the device composition data. Use BT_MESH_SHELL_HEALTH_PUB_DEFINE to instantiate publication context. diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index a169bb164222..9a0e5ece5e3b 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -771,7 +771,7 @@ static int cmd_provision_gatt(const struct shell *sh, size_t argc, } #endif /* CONFIG_BT_MESH_PB_GATT_CLIENT */ -#if defined(CONFIG_BT_MESH_PROV_DEVICE) +#if defined(CONFIG_BT_MESH_PROVISIONEE) static int cmd_pb(bt_mesh_prov_bearer_t bearer, const struct shell *sh, size_t argc, char *argv[]) { @@ -822,7 +822,7 @@ static int cmd_pb_gatt(const struct shell *sh, size_t argc, char *argv[]) return cmd_pb(BT_MESH_PROV_GATT, sh, argc, argv); } #endif /* CONFIG_BT_MESH_PB_GATT */ -#endif /* CONFIG_BT_MESH_PROV_DEVICE */ +#endif /* CONFIG_BT_MESH_PROVISIONEE */ #if defined(CONFIG_BT_MESH_PROVISIONER) static int cmd_remote_pub_key_set(const struct shell *sh, size_t argc, char *argv[]) @@ -1681,14 +1681,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(comp-change, NULL, NULL, cmd_comp_change, 1, 0), /* Provisioning operations */ -#if defined(CONFIG_BT_MESH_PROV_DEVICE) +#if defined(CONFIG_BT_MESH_PROVISIONEE) #if defined(CONFIG_BT_MESH_PB_GATT) SHELL_CMD_ARG(pb-gatt, NULL, "", cmd_pb_gatt, 2, 0), #endif #if defined(CONFIG_BT_MESH_PB_ADV) SHELL_CMD_ARG(pb-adv, NULL, "", cmd_pb_adv, 2, 0), #endif -#endif /* CONFIG_BT_MESH_PROV_DEVICE */ +#endif /* CONFIG_BT_MESH_PROVISIONEE */ #if defined(CONFIG_BT_MESH_PROVISIONER) SHELL_CMD(auth-method, &auth_cmds, "Authentication methods", bt_mesh_shell_mdl_cmds_help), @@ -1814,5 +1814,5 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds, SHELL_SUBCMD_SET_END ); -SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth mesh shell commands", +SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth Mesh shell commands", bt_mesh_shell_mdl_cmds_help, 1, 1); diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index e2100fa42dbf..642abfd87f10 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -12,7 +12,6 @@ #include #include #include "access.h" -#include "adv.h" #include "cfg.h" #include "crypto.h" #include "mesh.h" diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 21c451bee738..b9f542a59237 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -6,7 +6,6 @@ #include -#include "adv.h" #include "net.h" #include "statistic.h" @@ -22,24 +21,24 @@ void bt_mesh_stat_reset(void) memset(&stat, 0, sizeof(struct bt_mesh_statistic)); } -void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) +void bt_mesh_stat_planned_count(struct bt_mesh_adv_ctx *ctx) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (ctx->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (ctx->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (ctx->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_planned++; } } -void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv_ctx *ctx) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (ctx->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (ctx->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (ctx->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_succeeded++; } } diff --git a/subsys/bluetooth/mesh/statistic.h b/subsys/bluetooth/mesh/statistic.h index fdb488f0d81b..4cd9187f45a3 100644 --- a/subsys/bluetooth/mesh/statistic.h +++ b/subsys/bluetooth/mesh/statistic.h @@ -7,8 +7,8 @@ #ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ #define ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ -void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv); -void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv); +void bt_mesh_stat_planned_count(struct bt_mesh_adv_ctx *ctx); +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv_ctx *ctx); void bt_mesh_stat_rx(enum bt_mesh_net_if net_if); #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ */ diff --git a/subsys/bluetooth/mesh/subnet.c b/subsys/bluetooth/mesh/subnet.c index ef90ff8f7259..695dd321b49a 100644 --- a/subsys/bluetooth/mesh/subnet.c +++ b/subsys/bluetooth/mesh/subnet.c @@ -22,7 +22,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "lpn.h" diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index 94c1f698e910..47e8492a901e 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -22,7 +22,6 @@ #include "host/testing.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "app_keys.h" @@ -122,26 +121,26 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, const struct bt_mesh_send_cb *cb, void *cb_data, const uint8_t *ctl_op) { - struct net_buf *buf; + struct bt_mesh_adv *adv; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); - if (!buf) { - LOG_ERR("Out of network buffers"); + if (!adv) { + LOG_ERR("Out of network advs"); return -ENOBUFS; } - net_buf_reserve(buf, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&adv->b, BT_MESH_NET_HDR_LEN); if (ctl_op) { - net_buf_add_u8(buf, TRANS_CTL_HDR(*ctl_op, 0)); + net_buf_simple_add_u8(&adv->b, TRANS_CTL_HDR(*ctl_op, 0)); } else if (BT_MESH_IS_DEV_KEY(tx->ctx->app_idx)) { - net_buf_add_u8(buf, UNSEG_HDR(0, 0)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(0, 0)); } else { - net_buf_add_u8(buf, UNSEG_HDR(1, tx->aid)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(1, tx->aid)); } - net_buf_add_mem(buf, sdu->data, sdu->len); + net_buf_simple_add_mem(&adv->b, sdu->data, sdu->len); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, @@ -149,7 +148,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, NULL, 1)) { if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { LOG_ERR("Not enough space in Friend Queue"); - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return -ENOBUFS; } else { LOG_WRN("No space in Friend Queue"); @@ -158,19 +157,19 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, } if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - NULL, 1, &buf->b) && + NULL, 1, &adv->b) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. */ - net_buf_unref(buf); + bt_mesh_adv_unref(adv); send_cb_finalize(cb, cb_data); return 0; } } send: - return bt_mesh_net_send(tx, buf, cb, cb_data); + return bt_mesh_net_send(tx, adv, cb, cb_data); } static inline uint8_t seg_len(bool ctl) @@ -405,7 +404,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) (uint16_t)(tx->seq_auth & TRANS_SEQ_ZERO_MASK), tx->attempts_left); while (tx->seg_o <= tx->seg_n) { - struct net_buf *seg; + struct bt_mesh_adv *seg; int err; if (!tx->seg[tx->seg_o]) { @@ -421,7 +420,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) goto end; } - net_buf_reserve(seg, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&seg->b, BT_MESH_NET_HDR_LEN); seg_tx_buf_build(tx, tx->seg_o, &seg->b); LOG_DBG("Sending %u/%u", tx->seg_o, tx->seg_n); diff --git a/subsys/bluetooth/mesh/transport_legacy.c b/subsys/bluetooth/mesh/transport_legacy.c index da0c1830f737..1a826db4ac4b 100644 --- a/subsys/bluetooth/mesh/transport_legacy.c +++ b/subsys/bluetooth/mesh/transport_legacy.c @@ -22,7 +22,6 @@ #include "host/testing.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "app_keys.h" @@ -129,26 +128,26 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, const struct bt_mesh_send_cb *cb, void *cb_data, const uint8_t *ctl_op) { - struct net_buf *buf; + struct bt_mesh_adv *adv; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, tx->xmit, BUF_TIMEOUT); - if (!buf) { - LOG_ERR("Out of network buffers"); + if (!adv) { + LOG_ERR("Out of network advs"); return -ENOBUFS; } - net_buf_reserve(buf, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&adv->b, BT_MESH_NET_HDR_LEN); if (ctl_op) { - net_buf_add_u8(buf, TRANS_CTL_HDR(*ctl_op, 0)); + net_buf_simple_add_u8(&adv->b, TRANS_CTL_HDR(*ctl_op, 0)); } else if (BT_MESH_IS_DEV_KEY(tx->ctx->app_idx)) { - net_buf_add_u8(buf, UNSEG_HDR(0, 0)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(0, 0)); } else { - net_buf_add_u8(buf, UNSEG_HDR(1, tx->aid)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(1, tx->aid)); } - net_buf_add_mem(buf, sdu->data, sdu->len); + net_buf_simple_add_mem(&adv->b, sdu->data, sdu->len); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, @@ -156,7 +155,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, NULL, 1)) { if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { LOG_ERR("Not enough space in Friend Queue"); - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return -ENOBUFS; } @@ -165,19 +164,19 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, } if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - NULL, 1, &buf->b) && + NULL, 1, &adv->b) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. */ - net_buf_unref(buf); + bt_mesh_adv_unref(adv); send_cb_finalize(cb, cb_data); return 0; } } send: - return bt_mesh_net_send(tx, buf, cb, cb_data); + return bt_mesh_net_send(tx, adv, cb, cb_data); } static inline uint8_t seg_len(bool ctl) @@ -392,7 +391,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) tx->attempts); while (tx->seg_o <= tx->seg_n) { - struct net_buf *seg; + struct bt_mesh_adv *seg; int err; if (!tx->seg[tx->seg_o]) { @@ -408,7 +407,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) goto end; } - net_buf_reserve(seg, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&seg->b, BT_MESH_NET_HDR_LEN); seg_tx_buf_build(tx, tx->seg_o, &seg->b); LOG_DBG("Sending %u/%u", tx->seg_o, tx->seg_n); diff --git a/subsys/bluetooth/mesh/va.c b/subsys/bluetooth/mesh/va.c index 6db9194da479..b69c22f40e9b 100644 --- a/subsys/bluetooth/mesh/va.c +++ b/subsys/bluetooth/mesh/va.c @@ -306,6 +306,10 @@ void bt_mesh_va_clear(void) { int i; + if (CONFIG_BT_MESH_LABEL_COUNT == 0) { + return; + } + for (i = 0; i < ARRAY_SIZE(virtual_addrs); i++) { if (virtual_addrs[i].ref) { virtual_addrs[i].ref = 0U; diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index 3f1af44de6f6..4e0111fa7571 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -99,10 +99,14 @@ static const char *phy2str(uint8_t phy) { switch (phy) { case 0: return "No packets"; - case BT_GAP_LE_PHY_1M: return "LE 1M"; - case BT_GAP_LE_PHY_2M: return "LE 2M"; - case BT_GAP_LE_PHY_CODED: return "LE Coded"; - default: return "Unknown"; + case BT_GAP_LE_PHY_1M: + return "LE 1M"; + case BT_GAP_LE_PHY_2M: + return "LE 2M"; + case BT_GAP_LE_PHY_CODED: + return "LE Coded"; + default: + return "Unknown"; } } #endif @@ -123,6 +127,67 @@ static void print_le_addr(const char *desc, const bt_addr_le_t *addr) } #endif /* CONFIG_BT_CONN || (CONFIG_BT_BROADCASTER && CONFIG_BT_EXT_ADV) */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +static const char *tx_power_flag2str(int8_t flag) +{ + switch (flag) { + case 0: + return "Neither Max nor Min Tx Power"; + case 1: + return "Tx Power Level is at minimum"; + case 2: + return "Tx Power Level is at maximum"; + /* Current Tx Power Level is the only available one*/ + case 3: + return "Tx Power Level is at minimum & maximum."; + default: + return "Unknown"; + } +} + +static const char *tx_power_report_reason2str(uint8_t reason) +{ + switch (reason) { + case BT_HCI_LE_TX_POWER_REPORT_REASON_LOCAL_CHANGED: + return "Local Tx Power changed"; + case BT_HCI_LE_TX_POWER_REPORT_REASON_REMOTE_CHANGED: + return "Remote Tx Power changed"; + case BT_HCI_LE_TX_POWER_REPORT_REASON_READ_REMOTE_COMPLETED: + return "Completed to read remote Tx Power"; + default: + return "Unknown"; + } +} + +static const char *tx_pwr_ctrl_phy2str(enum bt_conn_le_tx_power_phy phy) +{ + switch (phy) { + case BT_CONN_LE_TX_POWER_PHY_NONE: + return "None"; + case BT_CONN_LE_TX_POWER_PHY_1M: + return "LE 1M"; + case BT_CONN_LE_TX_POWER_PHY_2M: + return "LE 2M"; + case BT_CONN_LE_TX_POWER_PHY_CODED_S8: + return "LE Coded S8"; + case BT_CONN_LE_TX_POWER_PHY_CODED_S2: + return "LE Coded S2"; + default: + return "Unknown"; + } +} + +static const char *enabled2str(bool enabled) +{ + if (enabled) { + return "Enabled"; + } else { + return "Disabled"; + } +} + +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + #if defined(CONFIG_BT_CENTRAL) static int cmd_scan_off(const struct shell *sh); static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[]); @@ -809,6 +874,19 @@ void le_phy_updated(struct bt_conn *conn, } #endif +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void tx_power_report(struct bt_conn *conn, + const struct bt_conn_le_tx_power_report *report) +{ + shell_print(ctx_shell, "Tx Power Report: Reason: %s, PHY: %s, Tx Power Level: %d", + tx_power_report_reason2str(report->reason), tx_pwr_ctrl_phy2str(report->phy), + report->tx_power_level); + shell_print(ctx_shell, "Tx Power Level Flag Info: %s, Delta: %d", + tx_power_flag2str(report->tx_power_level_flag), report->delta); +} +#endif + + static struct bt_conn_cb conn_callbacks = { .connected = connected, .disconnected = disconnected, @@ -829,6 +907,9 @@ static struct bt_conn_cb conn_callbacks = { #if defined(CONFIG_BT_USER_PHY_UPDATE) .le_phy_updated = le_phy_updated, #endif +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + .tx_power_report = tx_power_report, +#endif }; #endif /* CONFIG_BT_CONN */ @@ -2608,6 +2689,102 @@ static int cmd_per_adv_set_info_transfer(const struct shell *sh, size_t argc, } #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER && CONFIG_BT_PER_ADV */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +static int cmd_read_remote_tx_power(const struct shell *sh, size_t argc, char *argv[]) +{ + if (argc < 3) { + int err = 0; + enum bt_conn_le_tx_power_phy phy = strtoul(argv[1], NULL, 16); + + err = bt_conn_le_get_remote_tx_power_level(default_conn, phy); + + if (!err) { + shell_print(sh, "Read Remote TX Power for PHY %s", + tx_pwr_ctrl_phy2str(phy)); + } else { + shell_print(sh, "error %d", err); + } + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + return 0; +} + +static int cmd_read_local_tx_power(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + if (argc < 3) { + struct bt_conn_le_tx_power tx_power_level; + + tx_power_level.phy = strtoul(argv[1], NULL, 16); + + int8_t unachievable_current_level = -100; + /* Arbitrary, these are output parameters.*/ + tx_power_level.current_level = unachievable_current_level; + tx_power_level.max_level = 6; + + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + err = bt_conn_le_get_tx_power_level(default_conn, &tx_power_level); + if (err) { + shell_print(sh, "Commad returned error error %d", err); + return err; + } + if (tx_power_level.current_level == unachievable_current_level) { + shell_print(sh, "We received no current tx power level."); + return -EIO; + } + shell_print(sh, "Read local TX Power: current level: %d, PHY: %s, Max Level: %d", + tx_power_level.current_level, + tx_pwr_ctrl_phy2str((enum bt_conn_le_tx_power_phy)tx_power_level.phy), + tx_power_level.max_level); + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + return err; +} + +static int cmd_set_power_report_enable(const struct shell *sh, size_t argc, char *argv[]) +{ + if (argc < 4) { + int err = 0; + bool local_enable = 0; + bool remote_enable = 0; + + if (*argv[1] == '1') { + local_enable = 1; + } + if (*argv[2] == '1') { + remote_enable = 1; + } + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + err = bt_conn_le_set_tx_power_report_enable(default_conn, local_enable, + remote_enable); + if (!err) { + shell_print(sh, "Tx Power Report: local: %s, remote: %s", + enabled2str(local_enable), enabled2str(remote_enable)); + } else { + shell_print(sh, "error %d", err); + } + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + return 0; +} + +#endif + + #if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CENTRAL) static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[]) @@ -4015,6 +4192,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds, cmd_default_handler), SHELL_CMD_ARG(scan-verbose-output, NULL, "", cmd_scan_verbose_output, 2, 0), #endif /* CONFIG_BT_OBSERVER */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + SHELL_CMD_ARG(read-remote-tx-power, NULL, HELP_NONE, cmd_read_remote_tx_power, 2, 0), + SHELL_CMD_ARG(read-local-tx-power, NULL, HELP_NONE, cmd_read_local_tx_power, 2, 0), + SHELL_CMD_ARG(set-power-report-enable, NULL, HELP_NONE, cmd_set_power_report_enable, 3, 0), +#endif #if defined(CONFIG_BT_BROADCASTER) SHELL_CMD_ARG(advertise, NULL, " [mode: discov, non_discov] " diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index 3058f402d730..c4c75bb48c47 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1054,7 +1054,12 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ + .storage_dev = (void *) \ + COND_CODE_1(USE_PARTITION_MANAGER, \ + (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ + (FIXED_PARTITION_ID(littlefs_storage)), \ + (FIXED_PARTITION_ID(storage)))), \ + (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/fs/nvs/Kconfig b/subsys/fs/nvs/Kconfig index de4f282ee98a..df0329a7c419 100644 --- a/subsys/fs/nvs/Kconfig +++ b/subsys/fs/nvs/Kconfig @@ -27,6 +27,15 @@ config NVS_LOOKUP_CACHE_SIZE Number of entries in Non-volatile Storage lookup cache. It is recommended that it be a power of 2. +config NVS_LOOKUP_CACHE_FOR_SETTINGS + bool "Non-volatile Storage lookup cache optimized for settings" + depends on NVS_LOOKUP_CACHE + help + Use the lookup cache hash function that results in the least number of + collissions and, in turn, the best NVS performance provided that the NVS + is used as the settings backend only. This option should NOT be enabled + if the NVS is also written to directly, outside the settings layer. + module = NVS module-str = nvs source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 8c4575700a8d..14a4db5e3471 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -13,6 +13,11 @@ #include #include "nvs_priv.h" +#ifdef CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS +#include +#include +#endif + #include LOG_MODULE_REGISTER(fs_nvs, CONFIG_NVS_LOG_LEVEL); @@ -21,6 +26,45 @@ static int nvs_ate_valid(struct nvs_fs *fs, const struct nvs_ate *entry); #ifdef CONFIG_NVS_LOOKUP_CACHE +#ifdef CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS + +static inline size_t nvs_lookup_cache_pos(uint16_t id) +{ + /* + * 1. The NVS settings backend uses up to (NVS_NAME_ID_OFFSET - 1) NVS IDs to + store keys and equal number of NVS IDs to store values. + * 2. For each key-value pair, the value is stored at NVS ID greater by exactly + * NVS_NAME_ID_OFFSET than NVS ID that holds the key. + * 3. The backend tries to minimize the range of NVS IDs used to store keys. + * That is, NVS IDs are allocated sequentially, and freed NVS IDs are reused + * before allocating new ones. + * + * Therefore, to assure the least number of collisions in the lookup cache, + * the least significant bit of the hash indicates whether the given NVS ID + * represents a key or a value, and remaining bits of the hash are set to + * the ordinal number of the key-value pair. Consequently, the hash function + * provides the following mapping: + * + * 1st settings key => hash 0 + * 1st settings value => hash 1 + * 2nd settings key => hash 2 + * 2nd settings value => hash 3 + * ... + */ + BUILD_ASSERT(IS_POWER_OF_TWO(NVS_NAMECNT_ID), "NVS_NAMECNT_ID is not power of 2"); + BUILD_ASSERT(IS_POWER_OF_TWO(NVS_NAME_ID_OFFSET), "NVS_NAME_ID_OFFSET is not power of 2"); + + uint16_t key_value_bit; + uint16_t key_value_ord; + + key_value_bit = (id >> LOG2(NVS_NAME_ID_OFFSET)) & 1; + key_value_ord = id & (NVS_NAME_ID_OFFSET - 1); + + return ((key_value_ord << 1) | key_value_bit) % CONFIG_NVS_LOOKUP_CACHE_SIZE; +} + +#else /* CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS */ + static inline size_t nvs_lookup_cache_pos(uint16_t id) { uint16_t hash; @@ -36,6 +80,8 @@ static inline size_t nvs_lookup_cache_pos(uint16_t id) return hash % CONFIG_NVS_LOOKUP_CACHE_SIZE; } +#endif /* CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS */ + static int nvs_lookup_cache_rebuild(struct nvs_fs *fs) { int rc; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index a74e46b85207..9996e1d74d9b 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,8 +13,35 @@ extern "C" { #endif +#if CONFIG_PARTITION_MANAGER_ENABLED + +#include "pm_config.h" + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) +#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE +#else +/* The current image is a child image in a different domain than the image + * which defined the required values. To reach the values of the parent domain + * we use the 'PM__' variant of the define. + */ +#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ + +#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ + +#else + +#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) +#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) + +#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 diff --git a/subsys/llext/CMakeLists.txt b/subsys/llext/CMakeLists.txt index ac54f3172c37..b129dc7f9431 100644 --- a/subsys/llext/CMakeLists.txt +++ b/subsys/llext/CMakeLists.txt @@ -1,6 +1,5 @@ if(CONFIG_LLEXT) zephyr_library() - zephyr_library_sources(llext.c) - zephyr_library_sources(buf_loader.c) + zephyr_library_sources(llext.c llext_export.c buf_loader.c) zephyr_library_sources_ifdef(CONFIG_LLEXT_SHELL shell.c) endif() diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index 9fec16cb2306..b1210b8f2e8f 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -27,6 +27,12 @@ config LLEXT_SHELL_MAX_SIZE help When loading llext with shell it is stored in a temporary buffer of this size +config LLEXT_STORAGE_WRITABLE + bool "llext storage is writable" + help + Select if LLEXT storage is writable, i.e. if extensions are stored in + RAM and can be modified in place + module = LLEXT module-str = llext source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 3d99c8af4fae..8dd5801bc955 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -21,25 +21,6 @@ K_HEAP_DEFINE(llext_heap, CONFIG_LLEXT_HEAP_SIZE * 1024); static const char ELF_MAGIC[] = {0x7f, 'E', 'L', 'F'}; -static inline int llext_read(struct llext_loader *l, void *buf, size_t len) -{ - return l->read(l, buf, len); -} - -static inline int llext_seek(struct llext_loader *l, size_t pos) -{ - return l->seek(l, pos); -} - -static inline void *llext_peek(struct llext_loader *l, size_t pos) -{ - if (l->peek) { - return l->peek(l, pos); - } - - return NULL; -} - static sys_slist_t _llext_list = SYS_SLIST_STATIC_INIT(&_llext_list); sys_slist_t *llext_list(void) @@ -261,7 +242,8 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext, return 0; } - if (ldr->sects[sect_idx].sh_type != SHT_NOBITS) { + if (ldr->sects[sect_idx].sh_type != SHT_NOBITS && + IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) { ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[sect_idx].sh_offset); if (ext->mem[mem_idx]) { ext->mem_on_heap[mem_idx] = false; @@ -446,6 +428,105 @@ static int llext_copy_symbols(struct llext_loader *ldr, struct llext *ext) return 0; } +/* + * Find the section, containing the supplied offset and return file offset for + * that value + */ +static size_t llext_file_offset(struct llext_loader *ldr, size_t offset) +{ + unsigned int i; + + for (i = 0; i < LLEXT_SECT_COUNT; i++) + if (ldr->sects[i].sh_addr <= offset && + ldr->sects[i].sh_addr + ldr->sects[i].sh_size > offset) + return offset - ldr->sects[i].sh_addr + ldr->sects[i].sh_offset; + + return offset; +} + +static void llext_link_plt(struct llext_loader *ldr, struct llext *ext, elf_shdr_t *shdr) +{ + unsigned int sh_cnt = shdr->sh_size / shdr->sh_entsize; + /* + * CPU address where the .text section is stored, we use .text just as a + * reference point + */ + uint8_t *text = ext->mem[LLEXT_MEM_TEXT]; + + LOG_DBG("Found %p in PLT %u size %u cnt %u text %p", + (void *)llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr->sh_name), + shdr->sh_type, shdr->sh_entsize, sh_cnt, (void *)text); + + const elf_shdr_t *sym_shdr = ldr->sects + LLEXT_SECT_SYMTAB; + unsigned int sym_cnt = sym_shdr->sh_size / sym_shdr->sh_entsize; + + for (unsigned int i = 0; i < sh_cnt; i++) { + elf_rela_t rela; + + int ret = llext_seek(ldr, shdr->sh_offset + i * shdr->sh_entsize); + + if (!ret) { + ret = llext_read(ldr, &rela, sizeof(rela)); + } + + if (ret < 0) { + LOG_ERR("PLT: failed to read RELA #%u, trying to continue", i); + continue; + } + + /* Index in the symbol table */ + unsigned int j = ELF32_R_SYM(rela.r_info); + + if (j >= sym_cnt) { + LOG_WRN("PLT: idx %u >= %u", j, sym_cnt); + continue; + } + + elf_sym_t sym_tbl; + + ret = llext_seek(ldr, sym_shdr->sh_offset + j * sizeof(elf_sym_t)); + if (!ret) { + ret = llext_read(ldr, &sym_tbl, sizeof(sym_tbl)); + } + + if (ret < 0) { + LOG_ERR("PLT: failed to read symbol table #%u RELA #%u, trying to continue", + j, i); + continue; + } + + uint32_t stt = ELF_ST_TYPE(sym_tbl.st_info); + const char *name = llext_string(ldr, ext, LLEXT_MEM_STRTAB, sym_tbl.st_name); + /* + * Both r_offset and sh_addr are addresses for which the extension + * has been built. + */ + size_t got_offset = llext_file_offset(ldr, rela.r_offset) - + ldr->sects[LLEXT_SECT_TEXT].sh_offset; + + if (stt == STT_NOTYPE && sym_tbl.st_shndx == SHN_UNDEF && name[0] != '\0') { + const void *link_addr = llext_find_sym(NULL, name); + + if (!link_addr) { + LOG_WRN("PLT: cannot find idx %u name %s", j, name); + continue; + } + + if (!rela.r_offset) { + LOG_WRN("PLT: zero offset idx %u name %s", j, name); + continue; + } + + LOG_DBG("symbol %s offset %#x r-offset %#x .text offset %#x", + name, got_offset, + rela.r_offset, ldr->sects[LLEXT_SECT_TEXT].sh_offset); + + /* Resolve the symbol */ + *(const void **)(text + got_offset) = link_addr; + } + } +} + __weak void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval) { } @@ -486,12 +567,19 @@ static int llext_link(struct llext_loader *ldr, struct llext *ext) if (strcmp(name, ".rel.text") == 0 || strcmp(name, ".rela.text") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_TEXT]; - } else if (strcmp(name, ".rel.bss") == 0) { + } else if (strcmp(name, ".rel.bss") == 0 || + strcmp(name, ".rela.bss") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_BSS]; - } else if (strcmp(name, ".rel.rodata") == 0) { + } else if (strcmp(name, ".rel.rodata") == 0 || + strcmp(name, ".rela.rodata") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_RODATA]; - } else if (strcmp(name, ".rel.data") == 0) { + } else if (strcmp(name, ".rel.data") == 0 || + strcmp(name, ".rela.data") == 0) { loc = (uintptr_t)ext->mem[LLEXT_MEM_DATA]; + } else if (strcmp(name, ".rela.plt") == 0 || + strcmp(name, ".rela.dyn") == 0) { + llext_link_plt(ldr, ext, &shdr); + continue; } LOG_DBG("relocation section %s (%d) linked to section %d has %d relocations", @@ -583,7 +671,7 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) memset(ldr->sects, 0, sizeof(ldr->sects)); ldr->sect_cnt = 0; - size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(uint32_t); + size_t sect_map_sz = ldr->hdr.e_shnum * sizeof(ldr->sect_map[0]); ldr->sect_map = k_heap_alloc(&llext_heap, sect_map_sz, K_NO_WAIT); if (!ldr->sect_map) { @@ -591,7 +679,8 @@ static int do_llext_load(struct llext_loader *ldr, struct llext *ext) ret = -ENOMEM; goto out; } - memset(ldr->sect_map, 0, ldr->hdr.e_shnum*sizeof(uint32_t)); + memset(ldr->sect_map, 0, sect_map_sz); + ldr->sect_cnt = ldr->hdr.e_shnum; ext->mem_size += sect_map_sz; @@ -704,10 +793,6 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext) } memset(*ext, 0, sizeof(struct llext)); - for (int i = 0; i < LLEXT_MEM_COUNT; i++) { - (*ext)->mem[i] = NULL; - } - ldr->hdr = ehdr; ret = do_llext_load(ldr, *ext); break; diff --git a/subsys/llext/llext_export.c b/subsys/llext/llext_export.c new file mode 100644 index 000000000000..0ec7fe4ac0a0 --- /dev/null +++ b/subsys/llext/llext_export.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memset); diff --git a/subsys/logging/log_msg.c b/subsys/logging/log_msg.c index 8023cefbf8c2..da9dffdc62ed 100644 --- a/subsys/logging/log_msg.c +++ b/subsys/logging/log_msg.c @@ -10,6 +10,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(log); BUILD_ASSERT(sizeof(struct log_msg_desc) == sizeof(uint32_t), @@ -270,6 +271,7 @@ void z_impl_z_log_msg_static_create(const void *source, z_log_msg_finalize(msg, source, out_desc, data); } +EXPORT_SYSCALL(z_log_msg_static_create); #ifdef CONFIG_USERSPACE static inline void z_vrfy_z_log_msg_static_create(const void *source, diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index 39d4a4ca8ce0..ad088eca0677 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -16,3 +16,11 @@ add_subdirectory(transport) add_subdirectory_ifdef(CONFIG_SMP_CLIENT smp_client) zephyr_library_link_libraries(mgmt_mcumgr) + +if (CONFIG_BOOT_IMAGE_ACCESS_HOOKS) + zephyr_include_directories( + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/include + ) + zephyr_library_sources(bootutil_hooks/nrf53_hooks.c) +endif() diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index 49bd17f46691..1c6a3a2a5162 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -6,6 +6,7 @@ menuconfig MCUMGR bool "mcumgr Support" depends on NET_BUF depends on ZCBOR + imply BOOT_IMAGE_ACCESS_HOOKS if (SOC_NRF5340_CPUAPP_QKAA && MCUMGR_GRP_IMG) help This option enables the mcumgr management library. diff --git a/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c new file mode 100644 index 000000000000..9971a4e08431 --- /dev/null +++ b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "bootutil/bootutil_public.h" + +int boot_read_swap_state_primary_slot_hook(int image_index, + struct boot_swap_state *state) +{ + if (image_index == 1) { + /* Pretend that primary slot of image 1 unpopulated */ + state->magic = BOOT_MAGIC_UNSET; + state->swap_type = BOOT_SWAP_TYPE_NONE; + state->image_num = image_index; + state->copy_done = BOOT_FLAG_UNSET; + state->image_ok = BOOT_FLAG_UNSET; + + /* Prevent bootutil from trying to obtain true info */ + return 0; + } + + return BOOT_HOOK_REGULAR; +} diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 300948d5c88c..305cad41c445 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -33,6 +33,23 @@ #include #endif +#if USE_PARTITION_MANAGER +#include + +#ifdef PM_MCUBOOT_SECONDARY_PAD_SIZE +BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); +#endif + +#if CONFIG_BUILD_WITH_TFM + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE + PM_TFM_SIZE) +#else + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE) +#endif + +#define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ + (FIXED_PARTITION_OFFSET(label) == (PM_ADDRESS - PM_ADDRESS_OFFSET)) + +#else /* ! USE_PARTITION_MANAGER */ #ifndef CONFIG_FLASH_LOAD_OFFSET #error MCUmgr requires application to be built with CONFIG_FLASH_LOAD_OFFSET set \ to be able to figure out application running slot. @@ -40,6 +57,7 @@ #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ (FIXED_PARTITION_OFFSET(label) == CONFIG_FLASH_LOAD_OFFSET) +#endif /* USE_PARTITION_MANAGER */ BUILD_ASSERT(sizeof(struct image_header) == IMAGE_HEADER_SIZE, "struct image_header not required size"); diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 0968694c6147..61515c146550 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -290,13 +290,14 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type) return_slot = other_slot; } } +out: + #else if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &over) < 0) { return_slot = other_slot; } #endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */ -out: if (type != NULL) { *type = lt; } diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index e72e614d54cb..05686a663eb2 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -24,6 +24,7 @@ source "subsys/net/Kconfig.template.log_config.net" config NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE int "Size of the stack allocated for the conn_mgr_monitor thread" + default 8192 if WPA_SUPP default 512 help Sets the stack size which will be used by the connection manager for connectivity monitoring. diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index b9493b894a7b..3a93e5020d40 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -45,7 +45,6 @@ zephyr_library_sources_ifdef(CONFIG_NET_ROUTE route.c) zephyr_library_sources_ifdef(CONFIG_NET_STATISTICS net_stats.c) zephyr_library_sources_ifdef(CONFIG_NET_TCP tcp.c) zephyr_library_sources_ifdef(CONFIG_NET_TEST_PROTOCOL tp.c) -zephyr_library_sources_ifdef(CONFIG_NET_TRICKLE trickle.c) zephyr_library_sources_ifdef(CONFIG_NET_UDP udp.c) zephyr_library_sources_ifdef(CONFIG_NET_PROMISCUOUS_MODE promiscuous.c) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index fffa028b628f..a5a6b7ba01ec 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -758,20 +758,6 @@ config NET_SLIP_TAP communicate via the SLIP driver. See net-tools project at https://github.com/zephyrproject-rtos/net-tools for more details. -config NET_TRICKLE - bool "Trickle library" - help - Normally this is enabled automatically if needed, - so say 'n' if unsure. - -if NET_TRICKLE -module = NET_TRICKLE -module-dep = NET_LOG -module-str = Log level for Trickle algorithm -module-help = Enables Trickle library output debug messages -source "subsys/net/Kconfig.template.log_config.net" -endif # NET_TRICKLE - endif # NET_RAW_MODE config NET_PKT_RX_COUNT diff --git a/subsys/net/ip/dhcpv4.h b/subsys/net/ip/dhcpv4.h index a274e3a6aeae..712d361ac80d 100644 --- a/subsys/net/ip/dhcpv4.h +++ b/subsys/net/ip/dhcpv4.h @@ -62,6 +62,7 @@ struct dhcp_msg { #define DHCPV4_OPTIONS_REQ_LIST 55 #define DHCPV4_OPTIONS_RENEWAL 58 #define DHCPV4_OPTIONS_REBINDING 59 +#define DHCPV4_OPTIONS_CLIENT_ID 61 #define DHCPV4_OPTIONS_END 255 /* Useful size macros */ @@ -142,4 +143,14 @@ static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt) #endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */ +#if defined(CONFIG_NET_DHCPV4_SERVER) + +void net_dhcpv4_server_init(void); + +#else + +#define net_dhcpv4_server_init() + +#endif /* CONFIG_NET_DHCPV4_SERVER */ + #endif /* __INTERNAL_DHCPV4_H */ diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index baa8cd695c50..3187b40a66be 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -495,6 +495,8 @@ static inline int services_init(void) return status; } + net_dhcpv4_server_init(); + dns_init_resolver(); websocket_init(); diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 00c9c74495d8..1a8199ad62cd 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -3532,6 +3532,27 @@ static inline int z_vrfy_net_if_ipv4_addr_lookup_by_index( #include #endif +struct in_addr net_if_ipv4_get_netmask(struct net_if *iface) +{ + struct in_addr netmask = { 0 }; + + net_if_lock(iface); + + if (net_if_config_ipv4_get(iface, NULL) < 0) { + goto out; + } + + if (!iface->config.ip.ipv4) { + goto out; + } + + netmask = iface->config.ip.ipv4->netmask; +out: + net_if_unlock(iface); + + return netmask; +} + void net_if_ipv4_set_netmask(struct net_if *iface, const struct in_addr *netmask) { diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 39a06ed64a0f..6be7255b19b5 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -457,11 +457,11 @@ static void arp_gratuitous(struct net_if *iface, } } -static void arp_update(struct net_if *iface, - struct in_addr *src, - struct net_eth_addr *hwaddr, - bool gratuitous, - bool force) +void net_arp_update(struct net_if *iface, + struct in_addr *src, + struct net_eth_addr *hwaddr, + bool gratuitous, + bool force) { struct arp_entry *entry; struct net_pkt *pkt; @@ -647,10 +647,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, /* If the IP address is in our cache, * then update it here. */ - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - true, false); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + true, false); break; } } @@ -689,10 +689,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, net_sprint_ll_addr((uint8_t *)&arp_hdr->src_hwaddr, arp_hdr->hwlen)); - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - false, true); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + false, true); dst_hw_addr = &arp_hdr->src_hwaddr; } else { @@ -711,10 +711,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, case NET_ARP_REPLY: if (net_ipv4_is_my_addr((struct in_addr *)arp_hdr->dst_ipaddr)) { - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - false, false); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + false, false); } break; diff --git a/subsys/net/l2/ethernet/arp.h b/subsys/net/l2/ethernet/arp.h index 28cafe5f20ab..46589cbc1f72 100644 --- a/subsys/net/l2/ethernet/arp.h +++ b/subsys/net/l2/ethernet/arp.h @@ -67,6 +67,9 @@ int net_arp_foreach(net_arp_cb_t cb, void *user_data); void net_arp_clear_cache(struct net_if *iface); void net_arp_init(void); +void net_arp_update(struct net_if *iface, struct in_addr *src, + struct net_eth_addr *hwaddr, bool gratuitous, + bool force); /** * @} @@ -83,6 +86,7 @@ void net_arp_init(void); #define net_arp_foreach(...) 0 #define net_arp_init(...) #define net_arp_clear_pending(...) 0 +#define net_arp_update(...) #endif /* CONFIG_NET_ARP */ diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index 2be3c5f28206..8e73e8bcd433 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -1197,6 +1197,20 @@ int net_eth_promisc_mode(struct net_if *iface, bool enable) } #endif/* CONFIG_NET_PROMISCUOUS_MODE */ +int net_eth_txinjection_mode(struct net_if *iface, bool enable) +{ + struct ethernet_req_params params; + + if (!(net_eth_get_hw_capabilities(iface) & ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + params.txinjection_mode = enable; + + return net_mgmt(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE, iface, + ¶ms, sizeof(struct ethernet_req_params)); +} + void ethernet_init(struct net_if *iface) { struct ethernet_context *ctx = net_if_l2_data(iface); diff --git a/subsys/net/l2/ethernet/ethernet_mgmt.c b/subsys/net/l2/ethernet/ethernet_mgmt.c index e7fcae8ac99a..899aa7a9516d 100644 --- a/subsys/net/l2/ethernet/ethernet_mgmt.c +++ b/subsys/net/l2/ethernet/ethernet_mgmt.c @@ -192,6 +192,21 @@ static int ethernet_set_config(uint32_t mgmt_request, config.promisc_mode = params->promisc_mode; type = ETHERNET_CONFIG_TYPE_PROMISC_MODE; + } else if (mgmt_request == NET_REQUEST_ETHERNET_SET_T1S_PARAM) { + if (net_if_is_up(iface)) { + return -EACCES; + } + + memcpy(&config.t1s_param, ¶ms->t1s_param, + sizeof(struct ethernet_t1s_param)); + type = ETHERNET_CONFIG_TYPE_T1S_PARAM; + } else if (mgmt_request == NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE) { + if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + config.txinjection_mode = params->txinjection_mode; + type = ETHERNET_CONFIG_TYPE_TXINJECTION_MODE; } else { return -EINVAL; } @@ -226,6 +241,12 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXTIME_PARAM, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_PROMISC_MODE, ethernet_set_config); +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_T1S_PARAM, + ethernet_set_config); + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE, + ethernet_set_config); + static int ethernet_get_config(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) @@ -419,6 +440,19 @@ static int ethernet_get_config(uint32_t mgmt_request, config.txtime_param.enable_txtime; break; } + } else if (mgmt_request == NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE) { + if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + type = ETHERNET_CONFIG_TYPE_TXINJECTION_MODE; + + ret = api->get_config(dev, type, &config); + if (ret) { + return ret; + } + + params->txinjection_mode = config.txinjection_mode; } else { return -EINVAL; } @@ -444,6 +478,9 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBU_PARAM, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXTIME_PARAM, ethernet_get_config); +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE, + ethernet_get_config); + void ethernet_mgmt_raise_carrier_on_event(struct net_if *iface) { net_mgmt_event_notify(NET_EVENT_ETHERNET_CARRIER_ON, iface); diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index 98113975797f..aa7e03b82048 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -324,21 +324,15 @@ config OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE config OPENTHREAD_CRYPTO_PSA bool "ARM PSA crypto API" depends on MBEDTLS_PSA_CRYPTO_C || BUILD_WITH_TFM - select OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE + select OPENTHREAD_PLATFORM_KEY_REF select OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE help Enable crypto backend library implementation based on ARM PSA crypto API instead of the default, using mbedTLS. -config OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE - bool "Cryptographic key reference support" - help - Enable usage of cryptographic key references instead of literal keys - This requires a crypto backend library that supports key references. - config OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE bool "Make MAC keys exportable" - depends on OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE + depends on OPENTHREAD_PLATFORM_KEY_REF help Enable the creation of exportable MAC keys in the OpenThread Key Manager. diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 134448aa57f4..2816be56d746 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -64,6 +64,14 @@ config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL There are approximately 100 channels allocated across the three supported bands. The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. +config WIFI_SHELL_MAX_AP_STA + int "Maximum number of APs and STAs that can be managed in Wi-Fi shell" + range 1 5 + default 1 + help + This option defines the maximum number of APs and STAs that can be managed + in Wi-Fi shell. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 6eb8a6682c20..2cfe8e25d89a 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -274,6 +274,7 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, (params->ssid_length > WIFI_SSID_MAX_LEN) || (params->ssid_length == 0U) || ((params->security == WIFI_SECURITY_TYPE_PSK || + params->security == WIFI_SECURITY_TYPE_WPA_PSK || params->security == WIFI_SECURITY_TYPE_PSK_SHA256) && ((params->psk_length < 8) || (params->psk_length > 64) || (params->psk_length == 0U) || !params->psk)) || @@ -409,6 +410,30 @@ static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable); +static int wifi_ap_sta_disconnect(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + uint8_t *mac = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_sta_disconnect == NULL) { + return -ENOTSUP; + } + + if (!data || len != sizeof(uint8_t) * WIFI_MAC_ADDR_LEN) { + return -EINVAL; + } + + return wifi_mgmt_api->ap_sta_disconnect(dev, mac); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect); + static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { @@ -706,3 +731,43 @@ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, iface, &cnx_status, sizeof(struct wifi_status)); } + +void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface, + enum wifi_ap_status status) +{ + struct wifi_status cnx_status = { + .status = status, + }; + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT, + iface, &cnx_status, + sizeof(enum wifi_ap_status)); +} + +void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface, + enum wifi_ap_status status) +{ + struct wifi_status cnx_status = { + .status = status, + }; + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT, + iface, &cnx_status, + sizeof(enum wifi_ap_status)); +} + +void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info) +{ + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED, + iface, sta_info, + sizeof(struct wifi_ap_sta_info)); +} + +void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, + struct wifi_ap_sta_info *sta_info) +{ + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED, + iface, sta_info, + sizeof(struct wifi_ap_sta_info)); +} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ed85b015971d..2b131d4e0fbe 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include #include #include @@ -24,26 +25,31 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include "net_private.h" #define WIFI_SHELL_MODULE "wifi" +#define WIFI_SHELL_MGMT_EVENTS_COMMON (NET_EVENT_WIFI_SCAN_DONE |\ + NET_EVENT_WIFI_CONNECT_RESULT |\ + NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_TWT |\ + NET_EVENT_WIFI_RAW_SCAN_RESULT |\ + NET_EVENT_WIFI_AP_ENABLE_RESULT |\ + NET_EVENT_WIFI_AP_DISABLE_RESULT |\ + NET_EVENT_WIFI_AP_STA_CONNECTED |\ + NET_EVENT_WIFI_AP_STA_DISCONNECTED) + #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY -#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT | \ - NET_EVENT_WIFI_SCAN_DONE | \ - NET_EVENT_WIFI_CONNECT_RESULT | \ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT) +#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON) #else -#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | \ - NET_EVENT_WIFI_SCAN_DONE | \ - NET_EVENT_WIFI_CONNECT_RESULT | \ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT | \ - NET_EVENT_WIFI_RAW_SCAN_RESULT) +#define WIFI_SHELL_MGMT_EVENTS (WIFI_SHELL_MGMT_EVENTS_COMMON |\ + NET_EVENT_WIFI_SCAN_RESULT) #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ +#define MAX_BANDS_STR_LEN 64 + static struct { const struct shell *sh; @@ -61,6 +67,14 @@ static struct { static uint32_t scan_result; static struct net_mgmt_event_callback wifi_shell_mgmt_cb; +static struct wifi_reg_chan_info chan_info[MAX_REG_CHAN_NUM]; + +static K_MUTEX_DEFINE(wifi_ap_sta_list_lock); +struct wifi_ap_sta_node { + bool valid; + struct wifi_ap_sta_info sta_info; +}; +static struct wifi_ap_sta_node sta_list[CONFIG_WIFI_SHELL_MAX_AP_STA]; #define print(sh, level, fmt, ...) \ do { \ @@ -124,7 +138,6 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) wifi_mfp_txt(entry->mfp)); } -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS static int wifi_freq_to_channel(int frequency) { int channel = 0; @@ -146,6 +159,7 @@ static int wifi_freq_to_channel(int frequency) return channel; } +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS static enum wifi_frequency_bands wifi_freq_to_band(int frequency) { enum wifi_frequency_bands band = WIFI_FREQ_BAND_2_4_GHZ; @@ -279,8 +293,13 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) (const struct wifi_twt_params *)cb->info; if (resp->operation == WIFI_TWT_TEARDOWN) { - print(context.sh, SHELL_NORMAL, "TWT teardown received for flow ID %d\n", - resp->flow_id); + if (resp->teardown_status == WIFI_TWT_TEARDOWN_SUCCESS) { + print(context.sh, SHELL_NORMAL, "TWT teardown succeeded for flow ID %d\n", + resp->flow_id); + } else { + print(context.sh, SHELL_NORMAL, "TWT teardown failed for flow ID %d\n", + resp->flow_id); + } return; } @@ -302,6 +321,87 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) } } +static void handle_wifi_ap_enable_result(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = + (const struct wifi_status *)cb->info; + + if (status->status) { + print(context.sh, SHELL_WARNING, + "AP enable request failed (%d)\n", status->status); + } else { + print(context.sh, SHELL_NORMAL, "AP enabled\n"); + } +} + +static void handle_wifi_ap_disable_result(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = + (const struct wifi_status *)cb->info; + + if (status->status) { + print(context.sh, SHELL_WARNING, + "AP disable request failed (%d)\n", status->status); + } else { + print(context.sh, SHELL_NORMAL, "AP disabled\n"); + } + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + memset(&sta_list, 0, sizeof(sta_list)); + k_mutex_unlock(&wifi_ap_sta_list_lock); +} + +static void handle_wifi_ap_sta_connected(struct net_mgmt_event_callback *cb) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + int i; + + print(context.sh, SHELL_NORMAL, "Station connected: %s\n", + net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, sizeof(mac_string_buf))); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + if (!sta_list[i].valid) { + sta_list[i].sta_info = *sta_info; + sta_list[i].valid = true; + break; + } + } + if (i == CONFIG_WIFI_SHELL_MAX_AP_STA) { + print(context.sh, SHELL_WARNING, "No space to store station info: " + "Increase CONFIG_WIFI_SHELL_MAX_AP_STA\n"); + } + k_mutex_unlock(&wifi_ap_sta_list_lock); +} + +static void handle_wifi_ap_sta_disconnected(struct net_mgmt_event_callback *cb) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + print(context.sh, SHELL_NORMAL, "Station disconnected: %s\n", + net_sprint_ll_addr_buf(sta_info->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, sizeof(mac_string_buf))); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + if (!sta_list[i].valid) { + continue; + } + + if (!memcmp(sta_list[i].sta_info.mac, sta_info->mac, + WIFI_MAC_ADDR_LEN)) { + sta_list[i].valid = false; + break; + } + } + k_mutex_unlock(&wifi_ap_sta_list_lock); +} + static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { @@ -326,18 +426,33 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, handle_wifi_raw_scan_result(cb); break; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + case NET_EVENT_WIFI_AP_ENABLE_RESULT: + handle_wifi_ap_enable_result(cb); + break; + case NET_EVENT_WIFI_AP_DISABLE_RESULT: + handle_wifi_ap_disable_result(cb); + break; + case NET_EVENT_WIFI_AP_STA_CONNECTED: + handle_wifi_ap_sta_connected(cb); + break; + case NET_EVENT_WIFI_AP_STA_DISCONNECTED: + handle_wifi_ap_sta_disconnected(cb); + break; default: break; } } static int __wifi_args_to_params(size_t argc, char *argv[], - struct wifi_connect_req_params *params) + struct wifi_connect_req_params *params, + enum wifi_iface_mode iface_mode) { char *endptr; int idx = 1; if (argc < 1) { + print(context.sh, SHELL_WARNING, + "SSID not specified\n"); return -EINVAL; } @@ -350,20 +465,91 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->ssid = argv[0]; params->ssid_length = strlen(params->ssid); if (params->ssid_length > WIFI_SSID_MAX_LEN) { + print(context.sh, SHELL_WARNING, + "SSID too long (max %d characters)\n", + WIFI_SSID_MAX_LEN); return -EINVAL; } - /* Channel (optional) */ + /* Channel (optional: STA, mandatory: AP) */ if ((idx < argc) && (strlen(argv[idx]) <= 3)) { - params->channel = strtol(argv[idx], &endptr, 10); + uint8_t band; + long channel = strtol(argv[idx], &endptr, 10); + const uint8_t all_bands[] = {WIFI_FREQ_BAND_2_4_GHZ, + WIFI_FREQ_BAND_5_GHZ, + WIFI_FREQ_BAND_6_GHZ}; + bool found = false; + char bands_str[MAX_BANDS_STR_LEN] = {0}; + size_t offset = 0; + if (*endptr != '\0') { + print(context.sh, SHELL_ERROR, + "Failed to parse channel: %s: endp: %s, err: %s\n", + argv[idx], + endptr, + strerror(errno)); return -EINVAL; } - if (params->channel == 0U) { - params->channel = WIFI_CHANNEL_ANY; + if (iface_mode == WIFI_MODE_INFRA) { + if (channel < 0) { + /* Negative channel means band */ + switch (-channel) { + case 2: + params->band = WIFI_FREQ_BAND_2_4_GHZ; + break; + case 5: + params->band = WIFI_FREQ_BAND_5_GHZ; + break; + case 6: + params->band = WIFI_FREQ_BAND_6_GHZ; + break; + default: + print(context.sh, SHELL_ERROR, + "Invalid band: %ld\n", channel); + return -EINVAL; + } + } + } else { + if (channel < 0) { + print(context.sh, SHELL_ERROR, + "Invalid channel: %ld\n", channel); + return -EINVAL; + } } + if (channel > 0) { + for (band = 0; band < ARRAY_SIZE(all_bands); band++) { + offset += snprintf(bands_str + offset, + sizeof(bands_str) - offset, + "%s%s", + band ? "," : "", + wifi_band_txt(all_bands[band])); + if (offset >= sizeof(bands_str)) { + print(context.sh, SHELL_ERROR, + "Failed to parse channel: %s: " + "band string too long\n", + argv[idx]); + return -EINVAL; + } + + if (wifi_utils_validate_chan(all_bands[band], + channel)) { + found = true; + break; + } + } + + if (!found) { + print(context.sh, SHELL_ERROR, + "Invalid channel: %ld, checked bands: %s\n", + channel, + bands_str); + return -EINVAL; + } + + params->channel = channel; + } idx++; } @@ -389,6 +575,14 @@ static int __wifi_args_to_params(size_t argc, char *argv[], if (idx < argc) { unsigned int mfp = strtol(argv[idx], &endptr, 10); + if (security == WIFI_SECURITY_TYPE_NONE || + security == WIFI_SECURITY_TYPE_WPA_PSK) { + print(context.sh, SHELL_ERROR, + "MFP not supported for security type %s\n", + wifi_security_txt(security)); + return -EINVAL; + } + if (mfp <= WIFI_MFP_REQUIRED) { params->mfp = mfp; } @@ -401,6 +595,10 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->psk_length > WIFI_PSK_MAX_LEN) || (params->security == WIFI_SECURITY_TYPE_SAE && params->psk_length > WIFI_SAE_PSWD_MAX_LEN)) { + print(context.sh, SHELL_ERROR, + "Invalid PSK length (%d) for security type %s\n", + params->psk_length, + wifi_security_txt(params->security)); return -EINVAL; } } @@ -415,13 +613,13 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc, struct net_if *iface = net_if_get_first_wifi(); struct wifi_connect_req_params cnx_params = { 0 }; - if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params)) { + context.sh = sh; + if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params, WIFI_MODE_INFRA)) { shell_help(sh); return -ENOEXEC; } context.connecting = true; - context.sh = sh; if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params, sizeof(struct wifi_connect_req_params))) { @@ -496,9 +694,9 @@ static int wifi_scan_args_to_params(const struct shell *sh, state = getopt_state_get(); switch (opt) { case 't': - if (!strcmp(optarg, "passive")) { + if (!strncasecmp(optarg, "passive", 7)) { params->scan_type = WIFI_SCAN_TYPE_PASSIVE; - } else if (!strcmp(optarg, "active")) { + } else if (!strncasecmp(optarg, "active", 6)) { params->scan_type = WIFI_SCAN_TYPE_ACTIVE; } else { shell_fprintf(sh, SHELL_ERROR, "Invalid scan type %s\n", optarg); @@ -647,7 +845,7 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) wifi_mode_txt(status.iface_mode)); shell_fprintf(sh, SHELL_NORMAL, "Link Mode: %s\n", wifi_link_mode_txt(status.link_mode)); - shell_fprintf(sh, SHELL_NORMAL, "SSID: %-32s\n", status.ssid); + shell_fprintf(sh, SHELL_NORMAL, "SSID: %.32s\n", status.ssid); shell_fprintf(sh, SHELL_NORMAL, "BSSID: %s\n", net_sprint_ll_addr_buf(status.bssid, WIFI_MAC_ADDR_LEN, mac_string_buf, @@ -660,7 +858,9 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) wifi_security_txt(status.security)); shell_fprintf(sh, SHELL_NORMAL, "MFP: %s\n", wifi_mfp_txt(status.mfp)); - shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); + if (status.iface_mode == WIFI_MODE_INFRA) { + shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); + } shell_fprintf(sh, SHELL_NORMAL, "Beacon Interval: %d\n", status.beacon_interval); shell_fprintf(sh, SHELL_NORMAL, "DTIM: %d\n", status.dtim_period); shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", @@ -775,14 +975,17 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) config.twt_flows[i].trigger, config.twt_flows[i].twt_wake_interval, config.twt_flows[i].twt_interval); + shell_fprintf(context.sh, SHELL_NORMAL, + "TWT Wake ahead duration : %d us\n", + config.twt_flows[i].twt_wake_ahead_duration); } } return 0; } - if (!strncmp(argv[1], "on", 2)) { + if (!strncasecmp(argv[1], "on", 2)) { params.enabled = WIFI_PS_ENABLED; - } else if (!strncmp(argv[1], "off", 3)) { + } else if (!strncasecmp(argv[1], "off", 3)) { params.enabled = WIFI_PS_DISABLED; } else { shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); @@ -811,9 +1014,9 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) context.sh = sh; - if (!strncmp(argv[1], "legacy", 6)) { + if (!strncasecmp(argv[1], "legacy", 6)) { params.mode = WIFI_PS_MODE_LEGACY; - } else if (!strncmp(argv[1], "wmm", 3)) { + } else if (!strncasecmp(argv[1], "WMM", 3)) { params.mode = WIFI_PS_MODE_WMM; } else { shell_fprintf(sh, SHELL_WARNING, "Invalid PS mode\n"); @@ -933,7 +1136,7 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, context.sh = sh; - if (argc != 11) { + if (argc != 12) { shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); shell_help(sh); return -ENOEXEC; @@ -993,6 +1196,11 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, } params.setup.twt_interval = (uint64_t)value; + if (!parse_number(sh, &value, argv[idx++], 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { + return -EINVAL; + } + params.setup.twt_wake_ahead_duration = (uint32_t)value; + if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s with %s failed. reason : %s\n", wifi_twt_operation_txt(params.operation), @@ -1098,12 +1306,13 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, static struct wifi_connect_req_params cnx_params; int ret; - if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params)) { + context.sh = sh; + if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params, WIFI_MODE_AP)) { shell_help(sh); return -ENOEXEC; } - context.sh = sh; + k_mutex_init(&wifi_ap_sta_list_lock); ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, iface, &cnx_params, sizeof(struct wifi_connect_req_params)); @@ -1112,7 +1321,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode enabled\n"); + shell_fprintf(sh, SHELL_NORMAL, "AP mode enable requested\n"); return 0; } @@ -1129,20 +1338,91 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode disabled\n"); + shell_fprintf(sh, SHELL_NORMAL, "AP mode disable requested\n"); + return 0; +} + +static int cmd_wifi_ap_stations(const struct shell *sh, size_t argc, + char *argv[]) +{ + size_t id = 1; + + ARG_UNUSED(argv); + ARG_UNUSED(argc); + + shell_fprintf(sh, SHELL_NORMAL, "AP stations:\n"); + shell_fprintf(sh, SHELL_NORMAL, "============\n"); + + k_mutex_lock(&wifi_ap_sta_list_lock, K_FOREVER); + for (int i = 0; i < CONFIG_WIFI_SHELL_MAX_AP_STA; i++) { + struct wifi_ap_sta_info *sta; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + if (!sta_list[i].valid) { + continue; + } + + sta = &sta_list[i].sta_info; + + shell_fprintf(sh, SHELL_NORMAL, "Station %zu:\n", id++); + shell_fprintf(sh, SHELL_NORMAL, "==========\n"); + shell_fprintf(sh, SHELL_NORMAL, "MAC: %s\n", + net_sprint_ll_addr_buf(sta->mac, + WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf))); + shell_fprintf(sh, SHELL_NORMAL, "Link mode: %s\n", + wifi_link_mode_txt(sta->link_mode)); + shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", + sta->twt_capable ? "Supported" : "Not supported"); + } + + if (id == 1) { + shell_fprintf(sh, SHELL_NORMAL, "No stations connected\n"); + } + k_mutex_unlock(&wifi_ap_sta_list_lock); return 0; } +static int cmd_wifi_ap_sta_disconnect(const struct shell *sh, size_t argc, + char *argv[]) +{ + struct net_if *iface = net_if_get_first_wifi(); + uint8_t mac[6]; + int ret; + + if (argc != 2) { + shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + shell_help(sh); + return -ENOEXEC; + } + + if (net_bytes_from_str(mac, sizeof(mac), argv[1]) < 0) { + shell_fprintf(sh, SHELL_WARNING, "Invalid MAC address\n"); + return -ENOEXEC; + } + + ret = net_mgmt(NET_REQUEST_WIFI_AP_STA_DISCONNECT, iface, mac, sizeof(mac)); + if (ret) { + shell_fprintf(sh, SHELL_WARNING, "AP station disconnect failed: %s\n", + strerror(-ret)); + return -ENOEXEC; + } + + shell_fprintf(sh, SHELL_NORMAL, "AP station disconnect requested\n"); + return 0; +} static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_reg_domain regd = {0}; - int ret; + int ret, chan_idx = 0; if (argc == 1) { + (®d)->chan_info = &chan_info[0]; regd.oper = WIFI_MGMT_GET; } else if (argc >= 2 && argc <= 3) { regd.oper = WIFI_MGMT_SET; @@ -1187,6 +1467,19 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, if (regd.oper == WIFI_MGMT_GET) { shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi Regulatory domain is: %c%c\n", regd.country_code[0], regd.country_code[1]); + shell_fprintf(sh, SHELL_NORMAL, + "\t
\t\t" + "\t\t\n"); + for (chan_idx = 0; chan_idx < regd.num_channels; chan_idx++) { + shell_fprintf(sh, SHELL_NORMAL, + " %d\t\t\t\%d\t\t\t\%s\t\t\t%d\t\t\t%s\t\t\t\t%s\n", + wifi_freq_to_channel(chan_info[chan_idx].center_frequency), + chan_info[chan_idx].center_frequency, + chan_info[chan_idx].supported ? "y" : "n", + chan_info[chan_idx].max_power, + chan_info[chan_idx].passive_only ? "y" : "n", + chan_info[chan_idx].dfs ? "y" : "n"); + } } else { shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi Regulatory domain set to: %c%c\n", regd.country_code[0], regd.country_code[1]); @@ -1241,9 +1534,9 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar context.sh = sh; - if (!strncmp(argv[1], "dtim", 4)) { + if (!strncasecmp(argv[1], "dtim", 4)) { params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM; - } else if (!strncmp(argv[1], "listen_interval", 15)) { + } else if (!strncasecmp(argv[1], "listen_interval", 15)) { params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL; } else { shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); @@ -1275,11 +1568,9 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, {"sta", no_argument, 0, 's'}, {"monitor", no_argument, 0, 'm'}, - {"TX-injection", no_argument, 0, 't'}, - {"promiscuous", no_argument, 0, 'p'}, {"ap", no_argument, 0, 'a'}, {"softap", no_argument, 0, 'k'}, {"get", no_argument, 0, 'g'}, @@ -1294,12 +1585,6 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, case 'm': mode->mode |= WIFI_MONITOR_MODE; break; - case 't': - mode->mode |= WIFI_TX_INJECTION_MODE; - break; - case 'p': - mode->mode |= WIFI_PROMISCUOUS_MODE; - break; case 'a': mode->mode |= WIFI_AP_MODE; break; @@ -1385,7 +1670,7 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, {"channel", required_argument, 0, 'c'}, {"get", no_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, @@ -1491,8 +1776,8 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, int opt; int option_index = 0; - static struct option long_options[] = {{"if_index", optional_argument, 0, 'i'}, - {"capture_len", optional_argument, 0, 'b'}, + static struct option long_options[] = {{"if-index", optional_argument, 0, 'i'}, + {"capture-len", optional_argument, 0, 'b'}, {"all", no_argument, 0, 'a'}, {"mgmt", no_argument, 0, 'm'}, {"ctrl", no_argument, 0, 'c'}, @@ -1598,143 +1883,168 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg } SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, - SHELL_CMD(disable, NULL, - "Disable Access Point mode", - cmd_wifi_ap_disable), - SHELL_CMD(enable, NULL, " [channel] [PSK]", - cmd_wifi_ap_enable), + SHELL_CMD_ARG(disable, NULL, + "Disable Access Point mode.\n", + cmd_wifi_ap_disable, + 1, 0), + SHELL_CMD_ARG(enable, NULL, + "\"\"\n" + "\n" + "[PSK: valid only for secure SSIDs]\n" + "[Security type: valid only for secure SSIDs]\n" + "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" + "[MFP (optional: needs security type to be specified)]\n" + ": 0:Disable, 1:Optional, 2:Required.\n", + cmd_wifi_ap_enable, + 3, 3), + SHELL_CMD_ARG(stations, NULL, + "List stations connected to the AP", + cmd_wifi_ap_stations, + 1, 0), + SHELL_CMD_ARG(disconnect, NULL, + "Disconnect a station from the AP\n" + "\n", + cmd_wifi_ap_sta_disconnect, + 2, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, - SHELL_CMD(quick_setup, NULL, " Start a TWT flow with defaults:\n" - " \n", - cmd_wifi_twt_setup_quick), - SHELL_CMD(setup, NULL, " Start a TWT flow:\n" + SHELL_CMD_ARG(quick_setup, NULL, " Start a TWT flow with defaults:\n" + " .\n", + cmd_wifi_twt_setup_quick, + 3, 0), + SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " - " \n", - cmd_wifi_twt_setup), - SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" + " .\n" + ": 0us-2^31us>\n", + cmd_wifi_twt_setup, + 12, 0), + SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " \n", - cmd_wifi_twt_teardown), - SHELL_CMD(teardown_all, NULL, " Teardown all TWT flows\n", - cmd_wifi_twt_teardown_all), + " .\n", + cmd_wifi_twt_teardown, + 5, 0), + SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows.\n", + cmd_wifi_twt_teardown_all, + 1, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, - SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands", NULL), - SHELL_CMD(connect, NULL, + SHELL_CMD(ap, &wifi_cmd_ap, "Access Point mode commands.\n", NULL), + SHELL_CMD_ARG(connect, NULL, "Connect to a Wi-Fi AP\n" "\"\"\n" - "\n" - "\n" - "\n" - "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" - "\n" - ": 0:Disable, 1:Optional, 2:Required", - cmd_wifi_connect), - SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", - cmd_wifi_disconnect), - SHELL_CMD(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", - cmd_wifi_ps), + "[channel number/band: > 0:Channel, 0:any channel,\n" + "< 0:band (-2:2.4GHz, -5:5GHz, -6:6GHz]\n" + "[PSK: valid only for secure SSIDs]\n" + "[Security type: valid only for secure SSIDs]\n" + "0:None, 1:WPA2-PSK, 2:WPA2-PSK-256, 3:SAE, 4:WAPI, 5:EAP, 6:WEP, 7: WPA-PSK\n" + "[MFP (optional: needs security type to be specified)]\n" + ": 0:Disable, 1:Optional, 2:Required.\n", + cmd_wifi_connect, + 2, 4), + SHELL_CMD_ARG(disconnect, NULL, "Disconnect from the Wi-Fi AP.\n", + cmd_wifi_disconnect, + 1, 0), + SHELL_CMD_ARG(ps, NULL, "Configure or display Wi-Fi power save state\n" + "[on/off].\n", + cmd_wifi_ps, + 1, 1), SHELL_CMD_ARG(ps_mode, NULL, - "\n" - "", + ".\n", cmd_wifi_ps_mode, 2, 0), - SHELL_CMD(scan, NULL, + SHELL_CMD_ARG(scan, NULL, "Scan for Wi-Fi APs\n" - "OPTIONAL PARAMETERS:\n" - "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" - "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" - "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" - "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" - "[-s, --ssid : SSID to scan for. Can be provided multiple times.\n" - "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" - "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" - "[-h, --help] : Print out the help for the scan command.", - cmd_wifi_scan), - SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), - SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), - SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), - SHELL_CMD(reg_domain, NULL, + "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active\n" + "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz\n" + "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms\n" + "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms\n" + "[-s, --ssid] : SSID to scan for. Can be provided multiple times\n" + "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535\n" + "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6_5:36 or 2:1,6-11,14_5:36,163-177,52. Care should be taken to ensure that configured channels don't exceed CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL\n" + "[-h, --help] : Print out the help for the scan command.\n", + cmd_wifi_scan, + 1, 8), + SHELL_CMD_ARG(statistics, NULL, "Wi-Fi interface statistics.\n", cmd_wifi_stats, 1, 0), + SHELL_CMD_ARG(status, NULL, "Status of the Wi-Fi interface.\n", cmd_wifi_status, 1, 0), + SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows.\n", NULL), + SHELL_CMD_ARG(reg_domain, NULL, "Set or Get Wi-Fi regulatory domain\n" - "Usage: wifi reg_domain [ISO/IEC 3166-1 alpha2] [-f]\n" - "-f: Force to use this regulatory hint over any other regulatory hints\n" - "Note: This may cause regulatory compliance issues, use it at your own risk.", - cmd_wifi_reg_domain), - SHELL_CMD(mode, NULL, "mode operational setting\n" + "[ISO/IEC 3166-1 alpha2]: Regulatory domain\n" + "[-f]: Force to use this regulatory hint over any other regulatory hints\n" + "Note: This may cause regulatory compliance issues, use it at your own risk.\n", + cmd_wifi_reg_domain, + 1, 2), + SHELL_CMD_ARG(mode, NULL, "mode operational setting\n" "This command may be used to set the Wi-Fi device into a specific mode of operation\n" - "parameters:" - "[-i : Interface index - optional argument\n" - "[-s : Station mode.\n" - "[-m : Monitor mode.\n" - "[-p : Promiscuous mode.\n" - "[-t : TX-Injection mode.\n" - "[-a : AP mode.\n" - "[-k : Softap mode.\n" - "[-h : Help.\n" - "[-g : Get current mode for a specific interface index.\n" + "[-i, --if-index ] : Interface index\n" + "[-s, --sta] : Station mode\n" + "[-m, --monitor] : Monitor mode\n" + "[-a, --ap] : AP mode\n" + "[-k, --softap] : Softap mode\n" + "[-h, --help] : Help\n" + "[-g, --get] : Get current mode for a specific interface index\n" "Usage: Get operation example for interface index 1\n" "wifi mode -g -i1\n" "Set operation example for interface index 1 - set station+promiscuous\n" - "wifi mode -i1 -sp\n", - cmd_wifi_mode), - SHELL_CMD(packet_filter, NULL, "mode filter setting\n" + "wifi mode -i1 -sp.\n", + cmd_wifi_mode, + 1, 9), + SHELL_CMD_ARG(packet_filter, NULL, "mode filter setting\n" "This command is used to set packet filter setting when\n" - "monitor, TX-Injection and promiscuous mode is enabled.\n" + "monitor, TX-Injection and promiscuous mode is enabled\n" "The different packet filter modes are control, management, data and enable all filters\n" - "parameters:" - "[-i : Interface index - optional argument.\n" - "[-a : Enable all packet filter modes\n" - "[-m : Enable management packets to allowed up the stack.\n" - "[-c : Enable control packets to be allowed up the stack.\n" - "[-d : Enable Data packets to be allowed up the stack.\n" - "[-g : Get current filter settings for a specific interface index.\n" - "<-b : Capture length buffer size for each packet to be captured - optional argument.\n" - "<-h : Help.\n" + "[-i, --if-index ] : Interface index\n" + "[-a, --all] : Enable all packet filter modes\n" + "[-m, --mgmt] : Enable management packets to allowed up the stack\n" + "[-c, --ctrl] : Enable control packets to be allowed up the stack\n" + "[-d, --data] : Enable Data packets to be allowed up the stack\n" + "[-g, --get] : Get current filter settings for a specific interface index\n" + "[-b, --capture-len ] : Capture length buffer size for each packet to be captured\n" + "[-h, --help] : Help\n" "Usage: Get operation example for interface index 1\n" "wifi packet_filter -g -i1\n" "Set operation example for interface index 1 - set data+management frame filter\n" - "wifi packet_filter -i1 -md\n", - cmd_wifi_packet_filter), - SHELL_CMD(channel, NULL, "wifi channel setting\n" + "wifi packet_filter -i1 -md.\n", + cmd_wifi_packet_filter, + 1, 8), + SHELL_CMD_ARG(channel, NULL, "wifi channel setting\n" "This command is used to set the channel when\n" - "monitor or TX-Injection mode is enabled.\n" + "monitor or TX-Injection mode is enabled\n" "Currently 20 MHz is only supported and no BW parameter is provided\n" - "parameters:" - "[-i : Interface index - optional argument.\n" - "[-c : Set a specific channel number to the lower layer.\n" - "[-g : Get current set channel number from the lower layer.\n" - "[-h : Help.\n" + "[-i, --if-index ] : Interface index\n" + "[-c, --channel ] : Set a specific channel number to the lower layer\n" + "[-g, --get] : Get current set channel number from the lower layer\n" + "[-h, --help] : Help\n" "Usage: Get operation example for interface index 1\n" "wifi channel -g -i1\n" "Set operation example for interface index 1 (setting channel 5)\n" - "wifi -i1 -c5\n", - cmd_wifi_channel), + "wifi -i1 -c5.\n", + cmd_wifi_channel, + 1, 4), SHELL_CMD_ARG(ps_timeout, NULL, - " - PS inactivity timer(in ms)", + " - PS inactivity timer(in ms).\n", cmd_wifi_ps_timeout, 2, 0), SHELL_CMD_ARG(ps_listen_interval, NULL, - " - Listen interval in the range of <0-65535>", + " - Listen interval in the range of <0-65535>.\n", cmd_wifi_listen_interval, 2, 0), SHELL_CMD_ARG(ps_wakeup_mode, NULL, - " : Set PS wake up mode to DTIM interval\n" - " : Set PS wake up mode to listen interval", + ".\n", cmd_wifi_ps_wakeup_mode, 2, 0), diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 52d25d905667..bd47205e4f96 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -44,7 +44,7 @@ static enum wifi_frequency_bands wifi_utils_map_band_str_to_idx(char *band_str) } -static bool wifi_utils_validate_chan_2g(uint16_t chan) +bool wifi_utils_validate_chan_2g(uint16_t chan) { if ((chan >= 1) && (chan <= 14)) { return true; @@ -54,7 +54,7 @@ static bool wifi_utils_validate_chan_2g(uint16_t chan) } -static bool wifi_utils_validate_chan_5g(uint16_t chan) +bool wifi_utils_validate_chan_5g(uint16_t chan) { uint16_t i; @@ -68,7 +68,7 @@ static bool wifi_utils_validate_chan_5g(uint16_t chan) } -static bool wifi_utils_validate_chan_6g(uint16_t chan) +bool wifi_utils_validate_chan_6g(uint16_t chan) { if (((chan >= 1) && (chan <= 233) && (!((chan - 1)%4))) || (chan == 2)) { @@ -79,7 +79,7 @@ static bool wifi_utils_validate_chan_6g(uint16_t chan) } -static bool wifi_utils_validate_chan(uint8_t band, +bool wifi_utils_validate_chan(uint8_t band, uint16_t chan) { bool result = false; @@ -368,7 +368,7 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, memset(chan_str, 0, sizeof(chan_str)); if (chan_start) { - if ((chan_idx + (chan_val - chan_start)) >= max_channels) { + if ((chan_idx + (chan_val - chan_start)) > max_channels) { NET_ERR("Too many channels specified (%d)", max_channels); return -EINVAL; } diff --git a/subsys/net/lib/CMakeLists.txt b/subsys/net/lib/CMakeLists.txt index 756adb413419..e3319f6cd8d3 100644 --- a/subsys/net/lib/CMakeLists.txt +++ b/subsys/net/lib/CMakeLists.txt @@ -14,6 +14,8 @@ add_subdirectory_ifdef(CONFIG_TLS_CREDENTIALS tls_credentials) add_subdirectory_ifdef(CONFIG_NET_CAPTURE capture) add_subdirectory_ifdef(CONFIG_NET_ZPERF zperf) add_subdirectory_ifdef(CONFIG_NET_SHELL shell) +add_subdirectory_ifdef(CONFIG_NET_TRICKLE trickle) +add_subdirectory_ifdef(CONFIG_NET_DHCPV4_SERVER dhcpv4) if (CONFIG_DNS_RESOLVER OR CONFIG_MDNS_RESPONDER diff --git a/subsys/net/lib/Kconfig b/subsys/net/lib/Kconfig index 5df4a445885a..6cfa0445241b 100644 --- a/subsys/net/lib/Kconfig +++ b/subsys/net/lib/Kconfig @@ -39,6 +39,10 @@ menu "Network additional services" source "subsys/net/lib/capture/Kconfig" +source "subsys/net/lib/dhcpv4/Kconfig" + +source "subsys/net/lib/trickle/Kconfig" + source "subsys/net/lib/zperf/Kconfig" endmenu diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 8e62983ea729..63396bb05187 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -82,6 +82,13 @@ config COAP_MAX_RETRANSMIT default 4 range 1 10 +config COAP_BACKOFF_PERCENT + int "Retransmission backoff factor for ACK timeout described as percentage" + default 200 + help + Factor described as percentage to extend CoAP ACK timeout for retransmissions. + A value of 200 means a factor of 2.0. + config COAP_URI_WILDCARD bool "Wildcards in CoAP resource path" default y @@ -89,12 +96,6 @@ config COAP_URI_WILDCARD This option enables MQTT-style wildcards in path. Disable it if resource path may contain plus or hash symbol. -config COAP_OBSERVER_EVENTS - bool "CoAP resource observer events" - help - This option enables to register a callback function to CoAP resources - that will be called when adding/removing observers. - config COAP_KEEP_USER_DATA bool "Keeping user data in the CoAP packet" help @@ -201,12 +202,6 @@ config COAP_SERVICE_PENDING_MESSAGES help Maximum number of pending CoAP messages to retransmit per active service. -config COAP_SERVICE_PENDING_RETRANSMITS - int "CoAP retransmit count" - default 2 - help - Maximum number of retries to send a pending message. - config COAP_SERVICE_OBSERVERS int "CoAP service observers" default 3 diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 9fe62730b472..d22ee29bea77 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL); #include #include #include +#include #define COAP_PATH_ELEM_DELIM '/' #define COAP_PATH_ELEM_QUERY '?' @@ -53,6 +54,12 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL); /* The CoAP message ID that is incremented each time coap_next_id() is called. */ static uint16_t message_id; +static struct coap_transmission_parameters coap_transmission_params = { + .max_retransmission = CONFIG_COAP_MAX_RETRANSMIT, + .ack_timeout = CONFIG_COAP_INIT_ACK_TIMEOUT_MS, + .coap_backoff_percent = CONFIG_COAP_BACKOFF_PERCENT +}; + static int insert_option(struct coap_packet *cpkt, uint16_t code, const uint8_t *value, uint16_t len); @@ -1546,7 +1553,7 @@ size_t coap_next_block(const struct coap_packet *cpkt, int coap_pending_init(struct coap_pending *pending, const struct coap_packet *request, const struct sockaddr *addr, - uint8_t retries) + const struct coap_transmission_parameters *params) { memset(pending, 0, sizeof(*pending)); @@ -1554,10 +1561,16 @@ int coap_pending_init(struct coap_pending *pending, memcpy(&pending->addr, addr, sizeof(*addr)); + if (params) { + pending->params = *params; + } else { + pending->params = coap_transmission_params; + } + pending->data = request->data; pending->len = request->offset; pending->t0 = k_uptime_get(); - pending->retries = retries; + pending->retries = pending->params.max_retransmission; return 0; } @@ -1669,12 +1682,12 @@ struct coap_pending *coap_pending_next_to_expire( return found; } -static uint32_t init_ack_timeout(void) +static uint32_t init_ack_timeout(const struct coap_transmission_parameters *params) { #if defined(CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT) - const uint32_t max_ack = CONFIG_COAP_INIT_ACK_TIMEOUT_MS * + const uint32_t max_ack = params->ack_timeout * CONFIG_COAP_ACK_RANDOM_PERCENT / 100; - const uint32_t min_ack = CONFIG_COAP_INIT_ACK_TIMEOUT_MS; + const uint32_t min_ack = params->ack_timeout; /* Randomly generated initial ACK timeout * ACK_TIMEOUT < INIT_ACK_TIMEOUT < ACK_TIMEOUT * ACK_RANDOM_FACTOR @@ -1682,7 +1695,7 @@ static uint32_t init_ack_timeout(void) */ return min_ack + (sys_rand32_get() % (max_ack - min_ack)); #else - return CONFIG_COAP_INIT_ACK_TIMEOUT_MS; + return params->ack_timeout; #endif /* defined(CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT) */ } @@ -1690,8 +1703,7 @@ bool coap_pending_cycle(struct coap_pending *pending) { if (pending->timeout == 0) { /* Initial transmission. */ - pending->timeout = init_ack_timeout(); - + pending->timeout = init_ack_timeout(&pending->params); return true; } @@ -1700,7 +1712,7 @@ bool coap_pending_cycle(struct coap_pending *pending) } pending->t0 += pending->timeout; - pending->timeout = pending->timeout << 1; + pending->timeout = pending->timeout * pending->params.coap_backoff_percent / 100; pending->retries--; return true; @@ -1722,6 +1734,19 @@ void coap_pendings_clear(struct coap_pending *pendings, size_t len) } } +size_t coap_pendings_count(struct coap_pending *pendings, size_t len) +{ + struct coap_pending *p = pendings; + size_t c = 0; + + for (size_t i = 0; i < len && p; i++, p++) { + if (p->timeout) { + c++; + } + } + return c; +} + /* Reordering according to RFC7641 section 3.4 but without timestamp comparison */ static inline bool is_newer(int v1, int v2) { @@ -1844,6 +1869,25 @@ void coap_observer_init(struct coap_observer *observer, net_ipaddr_copy(&observer->addr, addr); } +static inline void coap_observer_raise_event(struct coap_resource *resource, + struct coap_observer *observer, + uint32_t mgmt_event) +{ +#ifdef CONFIG_NET_MGMT_EVENT_INFO + const struct net_event_coap_observer net_event = { + .resource = resource, + .observer = observer, + }; + + net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event)); +#else + ARG_UNUSED(resource); + ARG_UNUSED(observer); + + net_mgmt_event_notify(mgmt_event, NULL); +#endif +} + bool coap_register_observer(struct coap_resource *resource, struct coap_observer *observer) { @@ -1856,11 +1900,7 @@ bool coap_register_observer(struct coap_resource *resource, resource->age = 2; } -#ifdef CONFIG_COAP_OBSERVER_EVENTS - if (resource->observer_event_handler) { - resource->observer_event_handler(resource, observer, COAP_OBSERVER_ADDED); - } -#endif + coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_ADDED); return first; } @@ -1872,11 +1912,8 @@ bool coap_remove_observer(struct coap_resource *resource, return false; } -#ifdef CONFIG_COAP_OBSERVER_EVENTS - if (resource->observer_event_handler) { - resource->observer_event_handler(resource, observer, COAP_OBSERVER_REMOVED); - } -#endif + coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_REMOVED); + return true; } @@ -1993,3 +2030,13 @@ uint16_t coap_next_id(void) { return message_id++; } + +struct coap_transmission_parameters coap_get_transmission_parameters(void) +{ + return coap_transmission_params; +} + +void coap_set_transmission_parameters(const struct coap_transmission_parameters *params) +{ + coap_transmission_params = *params; +} diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index a947b15ae8e3..4bdf387a2429 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -16,7 +16,6 @@ LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); #define COAP_VERSION 1 #define COAP_SEPARATE_TIMEOUT 6000 #define COAP_PERIODIC_TIMEOUT 500 -#define DEFAULT_RETRY_AMOUNT 5 #define BLOCK1_OPTION_SIZE 4 #define PAYLOAD_MARKER_SIZE 1 @@ -60,7 +59,6 @@ static void reset_internal_request(struct coap_client_internal_request *request) { request->offset = 0; request->last_id = 0; - request->retry_count = 0; reset_block_contexts(request); } @@ -277,7 +275,7 @@ static int coap_client_init_request(struct coap_client *client, } int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries) + struct coap_client_request *req, struct coap_transmission_parameters *params) { int ret; @@ -352,14 +350,8 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr /* only TYPE_CON messages need pending tracking */ if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { - if (retries == -1) { - internal_req->retry_count = DEFAULT_RETRY_AMOUNT; - } else { - internal_req->retry_count = retries; - } - ret = coap_pending_init(&internal_req->pending, &internal_req->request, - &client->address, internal_req->retry_count); + &client->address, params); if (ret < 0) { LOG_ERR("Failed to initialize pending struct"); @@ -692,9 +684,11 @@ static int handle_response(struct coap_client *client, const struct coap_packet } if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { + struct coap_transmission_parameters params = + internal_req->pending.params; ret = coap_pending_init(&internal_req->pending, &internal_req->request, &client->address, - internal_req->retry_count); + ¶ms); if (ret < 0) { LOG_ERR("Error creating pending"); k_mutex_unlock(&client->send_mutex); @@ -793,8 +787,9 @@ static int handle_response(struct coap_client *client, const struct coap_packet goto fail; } + struct coap_transmission_parameters params = internal_req->pending.params; ret = coap_pending_init(&internal_req->pending, &internal_req->request, - &client->address, internal_req->retry_count); + &client->address, ¶ms); if (ret < 0) { LOG_ERR("Error creating pending"); k_mutex_unlock(&client->send_mutex); diff --git a/subsys/net/lib/coap/coap_server.c b/subsys/net/lib/coap/coap_server.c index 4b4f1719f46f..28d5b8de47f6 100644 --- a/subsys/net/lib/coap/coap_server.c +++ b/subsys/net/lib/coap/coap_server.c @@ -14,6 +14,7 @@ LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); #include #include #include +#include #include #ifdef CONFIG_ARCH_POSIX #include @@ -214,12 +215,25 @@ static int coap_server_process(int sock_fd) goto unlock; } - ret = coap_service_send(service, &response, &client_addr, client_addr_len); + ret = coap_service_send(service, &response, &client_addr, client_addr_len, NULL); } else { ret = coap_handle_request_len(&request, service->res_begin, COAP_SERVICE_RESOURCE_COUNT(service), options, opt_num, &client_addr, client_addr_len); + /* Translate errors to response codes */ + switch (ret) { + case -ENOENT: + ret = COAP_RESPONSE_CODE_NOT_FOUND; + break; + case -ENOTSUP: + ret = COAP_RESPONSE_CODE_BAD_REQUEST; + break; + case -EPERM: + ret = COAP_RESPONSE_CODE_NOT_ALLOWED; + break; + } + /* Shortcut for replying a code without a body */ if (ret > 0 && type == COAP_TYPE_CON) { /* Minimal sized ack buffer */ @@ -232,7 +246,7 @@ static int coap_server_process(int sock_fd) goto unlock; } - ret = coap_service_send(service, &ack, &client_addr, client_addr_len); + ret = coap_service_send(service, &ack, &client_addr, client_addr_len, NULL); } } @@ -332,6 +346,21 @@ static inline bool coap_service_in_section(const struct coap_service *service) STRUCT_SECTION_END(coap_service) > service; } +static inline void coap_service_raise_event(const struct coap_service *service, uint32_t mgmt_event) +{ +#if defined(CONFIG_NET_MGMT_EVENT_INFO) + const struct net_event_coap_service net_event = { + .service = service, + }; + + net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event)); +#else + ARG_UNUSED(service); + + net_mgmt_event_notify(mgmt_event, NULL); +#endif +} + int coap_service_start(const struct coap_service *service) { int ret; @@ -433,6 +462,8 @@ int coap_service_start(const struct coap_service *service) coap_server_update_services(); + coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STARTED); + return ret; close: @@ -456,22 +487,42 @@ int coap_service_stop(const struct coap_service *service) k_mutex_lock(&lock, K_FOREVER); if (service->data->sock_fd < 0) { - ret = -EALREADY; - goto end; + k_mutex_unlock(&lock); + return -EALREADY; } /* Closing a socket will trigger a poll event */ ret = zsock_close(service->data->sock_fd); service->data->sock_fd = -1; -end: + k_mutex_unlock(&lock); + + coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STOPPED); + + return ret; +} + +int coap_service_is_running(const struct coap_service *service) +{ + int ret; + + if (!coap_service_in_section(service)) { + __ASSERT_NO_MSG(false); + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + ret = (service->data->sock_fd < 0) ? 0 : 1; + k_mutex_unlock(&lock); return ret; } int coap_service_send(const struct coap_service *service, const struct coap_packet *cpkt, - const struct sockaddr *addr, socklen_t addr_len) + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params) { int ret; @@ -500,8 +551,7 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack goto send; } - ret = coap_pending_init(pending, cpkt, addr, - CONFIG_COAP_SERVICE_PENDING_RETRANSMITS); + ret = coap_pending_init(pending, cpkt, addr, params); if (ret < 0) { LOG_WRN("Failed to init pending message for %s (%d)", service->name, ret); goto send; @@ -536,12 +586,13 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack } int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt, - const struct sockaddr *addr, socklen_t addr_len) + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params) { /* Find owning service */ COAP_SERVICE_FOREACH(svc) { if (COAP_SERVICE_HAS_RESOURCE(svc, resource)) { - return coap_service_send(svc, cpkt, addr, addr_len); + return coap_service_send(svc, cpkt, addr, addr_len, params); } } @@ -694,9 +745,6 @@ static void coap_server_thread(void *p1, void *p2, void *p3) } COAP_SERVICE_FOREACH(svc) { - /* Init all file descriptors to -1 */ - svc->data->sock_fd = -1; - if (svc->flags & COAP_SERVICE_AUTOSTART) { ret = coap_service_start(svc); if (ret < 0) { diff --git a/subsys/net/lib/dhcpv4/CMakeLists.txt b/subsys/net/lib/dhcpv4/CMakeLists.txt new file mode 100644 index 000000000000..348b6c99bb7b --- /dev/null +++ b/subsys/net/lib/dhcpv4/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) + +zephyr_library_sources( + dhcpv4_server.c + ) diff --git a/subsys/net/lib/dhcpv4/Kconfig b/subsys/net/lib/dhcpv4/Kconfig new file mode 100644 index 000000000000..801d536a5a1d --- /dev/null +++ b/subsys/net/lib/dhcpv4/Kconfig @@ -0,0 +1,46 @@ +# DHCPv4 server implementation for Zephyr + +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +config NET_DHCPV4_SERVER + bool "DHCPv4 server" + depends on NET_IPV4 && NET_UDP + select NET_SOCKETS + select NET_SOCKETS_SERVICE + +if NET_DHCPV4_SERVER + +module = NET_DHCPV4_SERVER +module-dep = NET_LOG +module-str = Log level for DHCPv4 server +module-help = Enables DHCPv4 server output debug messages +source "subsys/net/Kconfig.template.log_config.net" + +config NET_DHCPV4_SERVER_INSTANCES + int "Maximum number of DHCPv4 server instances" + default 1 + help + Maximum number of DHCPv4 server instances supported by the system. + Each network interface that wants to act as a DHCPv4 server requires + a separate instance. + +config NET_DHCPV4_SERVER_ADDR_COUNT + int "Number of IPv4 addresses that can be assigned by the server" + default 4 + help + Maximum number of IPv4 addresses that can be assigned by the DHCPv4 + server instance. The base IPv4 address in the address pool is provided + at runtime, during server initialization. Consecutive addresses in the + pool have the lowest address octet incremented. + +config NET_DHCPV4_SERVER_ADDR_LEASE_TIME + int "Lease time for IPv4 addresses assigned by the server (seconds)" + default 86400 + help + Lease time in seconds for IPv4 addresses assigned by the server. + The lease time determines when the IPv4 address lease expires if the + client does not renew it. + +endif # NET_DHCPV4_SERVER diff --git a/subsys/net/lib/dhcpv4/dhcpv4_server.c b/subsys/net/lib/dhcpv4/dhcpv4_server.c new file mode 100644 index 000000000000..714d036dddef --- /dev/null +++ b/subsys/net/lib/dhcpv4/dhcpv4_server.c @@ -0,0 +1,1439 @@ +/** @file + * @brief DHCPv4 server implementation + */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(net_dhcpv4_server, CONFIG_NET_DHCPV4_SERVER_LOG_LEVEL); + +#include "dhcpv4.h" +#include "net_private.h" +#include "../../l2/ethernet/arp.h" + +#define DHCPV4_OPTIONS_MSG_TYPE_SIZE 3 +#define DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE 6 +#define DHCPV4_OPTIONS_SERVER_ID_SIZE 6 +#define DHCPV4_OPTIONS_SUBNET_MASK_SIZE 6 +#define DHCPV4_OPTIONS_CLIENT_ID_MIN_SIZE 2 + +#define ADDRESS_RESERVED_TIMEOUT K_SECONDS(5) + +/* RFC 1497 [17] */ +static const uint8_t magic_cookie[4] = { 0x63, 0x82, 0x53, 0x63 }; + +struct dhcpv4_server_ctx { + struct net_if *iface; + int sock; + struct k_work_delayable timeout_work; + struct dhcpv4_addr_slot addr_pool[CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT]; + struct in_addr server_addr; + struct in_addr netmask; +}; + +static struct dhcpv4_server_ctx server_ctx[CONFIG_NET_DHCPV4_SERVER_INSTANCES]; +static struct zsock_pollfd fds[CONFIG_NET_DHCPV4_SERVER_INSTANCES]; +static K_MUTEX_DEFINE(server_lock); + +#define DHCPV4_MAX_PARAMETERS_REQUEST_LEN 16 + +struct dhcpv4_parameter_request_list { + uint8_t list[DHCPV4_MAX_PARAMETERS_REQUEST_LEN]; + uint8_t count; +}; + +static void dhcpv4_server_timeout_recalc(struct dhcpv4_server_ctx *ctx) +{ + k_timepoint_t next = sys_timepoint_calc(K_FOREVER); + k_timeout_t timeout; + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED) { + if (sys_timepoint_cmp(slot->expiry, next) < 0) { + next = slot->expiry; + } + } + } + + timeout = sys_timepoint_timeout(next); + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + LOG_DBG("No more addresses, canceling timer"); + k_work_cancel_delayable(&ctx->timeout_work); + } else { + k_work_reschedule(&ctx->timeout_work, timeout); + } +} + +/* Option parsing. */ + +static uint8_t *dhcpv4_find_option(uint8_t *data, size_t datalen, + uint8_t *optlen, uint8_t opt_code) +{ + uint8_t *opt = NULL; + + while (datalen > 0) { + uint8_t code; + uint8_t len; + + code = *data; + + /* Two special cases (fixed sized options) */ + if (code == 0) { + data++; + datalen--; + continue; + } + + if (code == DHCPV4_OPTIONS_END) { + break; + } + + /* Length field should now follow. */ + if (datalen < 2) { + break; + } + + len = *(data + 1); + + if (datalen < len + 2) { + break; + } + + if (code == opt_code) { + /* Found the option. */ + opt = data + 2; + *optlen = len; + break; + } + + data += len + 2; + datalen -= len + 2; + } + + return opt; +} + +static int dhcpv4_find_message_type_option(uint8_t *data, size_t datalen, + uint8_t *msgtype) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_MSG_TYPE); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != 1) { + return -EINVAL; + } + + *msgtype = *opt; + + return 0; +} + +static int dhcpv4_find_server_id_option(uint8_t *data, size_t datalen, + struct in_addr *server_id) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_SERVER_ID); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(struct in_addr)) { + return -EINVAL; + } + + memcpy(server_id, opt, sizeof(struct in_addr)); + + return 0; +} + +static int dhcpv4_find_client_id_option(uint8_t *data, size_t datalen, + uint8_t *client_id, uint8_t *len) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_CLIENT_ID); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen < DHCPV4_OPTIONS_CLIENT_ID_MIN_SIZE) { + return -EINVAL; + } + + if (optlen > *len) { + LOG_ERR("Not enough memory for DHCPv4 client identifier."); + return -ENOMEM; + } + + memcpy(client_id, opt, optlen); + *len = optlen; + + return 0; +} + +static int dhcpv4_find_requested_ip_option(uint8_t *data, size_t datalen, + struct in_addr *requested_ip) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_REQ_IPADDR); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(struct in_addr)) { + return -EINVAL; + } + + memcpy(requested_ip, opt, sizeof(struct in_addr)); + + return 0; +} + +static int dhcpv4_find_ip_lease_time_option(uint8_t *data, size_t datalen, + uint32_t *lease_time) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_LEASE_TIME); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(uint32_t)) { + return -EINVAL; + } + + *lease_time = sys_get_be32(opt); + + return 0; +} + +static int dhcpv4_find_parameter_request_list_option( + uint8_t *data, size_t datalen, + struct dhcpv4_parameter_request_list *params) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_REQ_LIST); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen > sizeof(params->list)) { + /* Best effort here, copy as much as we can. */ + optlen = sizeof(params->list); + } + + memcpy(params->list, opt, optlen); + params->count = optlen; + + return 0; +} + +/* Option encoding. */ + +static uint8_t *dhcpv4_encode_magic_cookie(uint8_t *buf, size_t *buflen) +{ + if (buf == NULL || *buflen < SIZE_OF_MAGIC_COOKIE) { + return NULL; + } + + memcpy(buf, magic_cookie, SIZE_OF_MAGIC_COOKIE); + + *buflen -= SIZE_OF_MAGIC_COOKIE; + + return buf + SIZE_OF_MAGIC_COOKIE; +} + +static uint8_t *dhcpv4_encode_ip_lease_time_option(uint8_t *buf, size_t *buflen, + uint32_t lease_time) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_LEASE_TIME; + buf[1] = sizeof(lease_time); + sys_put_be32(lease_time, &buf[2]); + + *buflen -= DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE; + + return buf + DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE; +} + +static uint8_t *dhcpv4_encode_message_type_option(uint8_t *buf, size_t *buflen, + uint8_t msgtype) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_MSG_TYPE_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_MSG_TYPE; + buf[1] = 1; + buf[2] = msgtype; + + *buflen -= DHCPV4_OPTIONS_MSG_TYPE_SIZE; + + return buf + DHCPV4_OPTIONS_MSG_TYPE_SIZE; +} + +static uint8_t *dhcpv4_encode_server_id_option(uint8_t *buf, size_t *buflen, + struct in_addr *server_id) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_SERVER_ID_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_SERVER_ID; + buf[1] = sizeof(struct in_addr); + memcpy(&buf[2], server_id->s4_addr, sizeof(struct in_addr)); + + *buflen -= DHCPV4_OPTIONS_SERVER_ID_SIZE; + + return buf + DHCPV4_OPTIONS_SERVER_ID_SIZE; +} + +static uint8_t *dhcpv4_encode_subnet_mask_option(uint8_t *buf, size_t *buflen, + struct in_addr *mask) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_SUBNET_MASK_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_SUBNET_MASK; + buf[1] = sizeof(struct in_addr); + memcpy(&buf[2], mask->s4_addr, sizeof(struct in_addr)); + + *buflen -= DHCPV4_OPTIONS_SUBNET_MASK_SIZE; + + return buf + DHCPV4_OPTIONS_SUBNET_MASK_SIZE; +} + +static uint8_t *dhcpv4_encode_end_option(uint8_t *buf, size_t *buflen) +{ + if (buf == NULL || *buflen < 1) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_END; + + *buflen -= 1; + + return buf + 1; +} + +/* Response handlers. */ + +static uint8_t *dhcpv4_encode_header(uint8_t *buf, size_t *buflen, + struct dhcp_msg *msg, + struct in_addr *yiaddr) +{ + struct dhcp_msg *reply_msg = (struct dhcp_msg *)buf; + + if (buf == NULL || *buflen < sizeof(struct dhcp_msg)) { + return NULL; + } + + reply_msg->op = DHCPV4_MSG_BOOT_REPLY; + reply_msg->htype = msg->htype; + reply_msg->hlen = msg->hlen; + reply_msg->hops = 0; + reply_msg->xid = msg->xid; + reply_msg->secs = 0; + reply_msg->flags = msg->flags; + memcpy(reply_msg->ciaddr, msg->ciaddr, sizeof(reply_msg->ciaddr)); + if (yiaddr != NULL) { + memcpy(reply_msg->yiaddr, yiaddr, sizeof(struct in_addr)); + } else { + memset(reply_msg->yiaddr, 0, sizeof(reply_msg->ciaddr)); + } + memset(reply_msg->siaddr, 0, sizeof(reply_msg->siaddr)); + memcpy(reply_msg->giaddr, msg->giaddr, sizeof(reply_msg->giaddr)); + memcpy(reply_msg->chaddr, msg->chaddr, sizeof(reply_msg->chaddr)); + + *buflen -= sizeof(struct dhcp_msg); + + return buf + sizeof(struct dhcp_msg); +} + +static uint8_t *dhcpv4_encode_string(uint8_t *buf, size_t *buflen, char *str, + size_t max_len) +{ + if (buf == NULL || *buflen < max_len) { + return NULL; + } + + memset(buf, 0, max_len); + + if (str == NULL) { + goto out; + } + + strncpy(buf, str, max_len - 1); + + out: + *buflen -= max_len; + + return buf + max_len; +} + +static uint8_t *dhcpv4_encode_sname(uint8_t *buf, size_t *buflen, char *sname) +{ + return dhcpv4_encode_string(buf, buflen, sname, SIZE_OF_SNAME); +} + +static uint8_t *dhcpv4_encode_file(uint8_t *buf, size_t *buflen, char *file) +{ + return dhcpv4_encode_string(buf, buflen, file, SIZE_OF_FILE); +} + +static uint8_t *dhcpv4_encode_requested_params( + uint8_t *buf, size_t *buflen, + struct dhcpv4_server_ctx *ctx, + struct dhcpv4_parameter_request_list *params) +{ + for (uint8_t i = 0; i < params->count; i++) { + switch (params->list[i]) { + case DHCPV4_OPTIONS_SUBNET_MASK: + buf = dhcpv4_encode_subnet_mask_option( + buf, buflen, &ctx->netmask); + if (buf == NULL) { + goto out; + } + break; + + /* Others - just ignore. */ + default: + break; + } + } + +out: + return buf; +} + +static int dhcpv4_send(struct dhcpv4_server_ctx *ctx, enum net_dhcpv4_msg_type type, + uint8_t *reply, size_t len, struct dhcp_msg *msg, + struct in_addr *yiaddr) +{ + struct sockaddr_in dst_addr = { + .sin_family = AF_INET, + .sin_port = htons(DHCPV4_CLIENT_PORT), + }; + struct in_addr giaddr; /* Relay agent address */ + struct in_addr ciaddr; /* Client address */ + int ret; + + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + + /* Select destination address as described in ch. 4.1. */ + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* If the 'giaddr' field in a DHCP message from a client is + * non-zero, the server sends any return messages to the + * 'DHCP server' port on the BOOTP relay agent whose address + * appears in 'giaddr'. + */ + dst_addr.sin_addr = giaddr; + dst_addr.sin_port = htons(DHCPV4_SERVER_PORT); + } else if (type == NET_DHCPV4_MSG_TYPE_NAK) { + /* In all cases, when 'giaddr' is zero, the server broadcasts + * any DHCPNAK messages to 0xffffffff. + */ + dst_addr.sin_addr = *net_ipv4_broadcast_address(); + } else if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* If the 'giaddr' field is zero and the 'ciaddr' field is + * nonzero, then the server unicasts DHCPOFFER and DHCPACK + * messages to the address in 'ciaddr'. + */ + dst_addr.sin_addr = ciaddr; + } else if (ntohs(msg->flags) & DHCPV4_MSG_BROADCAST) { + /* If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast + * bit is set, then the server broadcasts DHCPOFFER and DHCPACK + * messages to 0xffffffff. + */ + dst_addr.sin_addr = *net_ipv4_broadcast_address(); + } else if (yiaddr != NULL) { + /* If the broadcast bit is not set and 'giaddr' is zero and + * 'ciaddr' is zero, then the server unicasts DHCPOFFER and + * DHCPACK messages to the client's hardware address and 'yiaddr' + * address. + */ + struct net_eth_addr hwaddr; + + memcpy(&hwaddr, msg->chaddr, sizeof(hwaddr)); + net_arp_update(ctx->iface, yiaddr, &hwaddr, false, true); + dst_addr.sin_addr = *yiaddr; + } else { + NET_ERR("Unspecified destination address."); + return -EDESTADDRREQ; + } + + ret = zsock_sendto(ctx->sock, reply, len, 0, (struct sockaddr *)&dst_addr, + sizeof(dst_addr)); + if (ret < 0) { + return -errno; + } + + return 0; +} + +static int dhcpv4_send_offer(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg, + struct in_addr *addr, uint32_t lease_time, + struct dhcpv4_parameter_request_list *params) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, addr); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + buf = dhcpv4_encode_ip_lease_time_option(buf, &buflen, lease_time); + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_OFFER); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_requested_params(buf, &buflen, ctx, params); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "Offer"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_OFFER, reply, reply_len, + msg, addr); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "Offer", ret); + return ret; + } + + return 0; +} + +static int dhcpv4_send_ack(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg, + struct in_addr *addr, uint32_t lease_time, + struct dhcpv4_parameter_request_list *params, + bool inform) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, inform ? NULL : addr); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + if (!inform) { + buf = dhcpv4_encode_ip_lease_time_option(buf, &buflen, lease_time); + } + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_ACK); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_requested_params(buf, &buflen, ctx, params); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "ACK"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_ACK, reply, reply_len, msg, + addr); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "ACK", ret); + return ret; + } + + return 0; +} + +static int dhcpv4_send_nak(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, NULL); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_NAK); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "NAK"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_NAK, reply, reply_len, msg, + NULL); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "NAK", ret); + return ret; + } + + return 0; +} + +/* Message handlers. */ + +static int dhcpv4_get_client_id(struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen, struct dhcpv4_client_id *client_id) +{ + int ret; + + client_id->len = sizeof(client_id->buf); + + ret = dhcpv4_find_client_id_option(options, optlen, client_id->buf, + &client_id->len); + if (ret == 0) { + return 0; + } + + /* No Client Id option or too long to use, fallback to hardware address. */ + if (msg->hlen > sizeof(msg->chaddr)) { + LOG_ERR("Malformed chaddr length."); + return -EINVAL; + } + + client_id->buf[0] = msg->htype; + client_id->buf[1] = msg->hlen; + memcpy(client_id->buf + 2, msg->chaddr, msg->hlen); + client_id->len = msg->hlen + 2; + + return 0; +} + +static uint32_t dhcpv4_get_lease_time(uint8_t *options, uint8_t optlen) +{ + uint32_t lease_time; + + if (dhcpv4_find_ip_lease_time_option(options, optlen, + &lease_time) == 0) { + return lease_time; + } + + return CONFIG_NET_DHCPV4_SERVER_ADDR_LEASE_TIME; +} + +static void dhcpv4_handle_discover(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + struct dhcpv4_addr_slot *selected = NULL; + struct dhcpv4_client_id client_id; + int ret; + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + return; + } + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + + /* Address pool and address selection algorithm as + * described in 4.3.1 + */ + + /* 1. Check for current bindings */ + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if ((slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0) { + /* Got match in current bindings. */ + selected = slot; + break; + } + } + + /* 2. Skipped, for now expired/released entries are forgotten. */ + + /* 3. Check Requested IP Address option. */ + if (selected == NULL) { + struct in_addr requested_ip; + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret == 0) { + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = + &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, + &requested_ip) && + slot->state == DHCPV4_SERVER_ADDR_FREE) { + /* Requested address is free. */ + selected = slot; + break; + } + } + } + } + + /* 4. Allocate new address from pool, if available. */ + if (selected == NULL) { + struct in_addr giaddr; + + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* Only addresses in local subnet supproted for now. */ + return; + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_FREE) { + /* Requested address is free. */ + selected = slot; + break; + } + } + } + + if (selected == NULL) { + LOG_ERR("No free address found in address pool"); + } else { + uint32_t lease_time = dhcpv4_get_lease_time(options, optlen); + + if (dhcpv4_send_offer(ctx, msg, &selected->addr, lease_time, + ¶ms) < 0) { + return; + } + + LOG_DBG("DHCPv4 processing Discover - reserved %s", + net_sprint_ipv4_addr(&selected->addr)); + + selected->state = DHCPV4_SERVER_ADDR_RESERVED; + selected->client_id.len = client_id.len; + memcpy(selected->client_id.buf, client_id.buf, client_id.len); + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc(ADDRESS_RESERVED_TIMEOUT); + dhcpv4_server_timeout_recalc(ctx); + } +} + +static void dhcpv4_handle_request(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + struct dhcpv4_addr_slot *selected = NULL; + struct dhcpv4_client_id client_id; + struct in_addr requested_ip, server_id, ciaddr, giaddr; + int ret; + + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* Only addresses in local subnet supported for now. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret == 0) { + /* Server ID present, Request generated during SELECTING. */ + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret < 0) { + /* Requested IP missing, ignore. */ + return; + } + + if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* ciaddr MUST be zero */ + return; + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &requested_ip) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + slot->state == DHCPV4_SERVER_ADDR_RESERVED) { + selected = slot; + break; + } + } + + if (selected == NULL) { + LOG_ERR("No valid slot found for DHCPv4 Request"); + } else { + uint32_t lease_time = dhcpv4_get_lease_time(options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &selected->addr, lease_time, + ¶ms, false) < 0) { + return; + } + + LOG_DBG("DHCPv4 processing Request - allocated %s", + net_sprint_ipv4_addr(&selected->addr)); + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + selected->state = DHCPV4_SERVER_ADDR_ALLOCATED; + dhcpv4_server_timeout_recalc(ctx); + } + + return; + } + + /* No server ID option - check requested address. */ + ret = dhcpv4_find_requested_ip_option(options, optlen, &requested_ip); + if (ret == 0) { + /* Requested IP present, Request generated during INIT-REBOOT. */ + if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* ciaddr MUST be zero */ + return; + } + + if (!net_if_ipv4_addr_mask_cmp(ctx->iface, &requested_ip)) { + /* Wrong subnet. */ + dhcpv4_send_nak(ctx, msg); + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + selected = slot; + break; + } + } + + if (selected != NULL) { + if (net_ipv4_addr_cmp(&selected->addr, &requested_ip)) { + uint32_t lease_time = dhcpv4_get_lease_time( + options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &selected->addr, + lease_time, ¶ms, + false) < 0) { + return; + } + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + dhcpv4_server_timeout_recalc(ctx); + } else { + dhcpv4_send_nak(ctx, msg); + } + } + + /* No notion of the client, remain silent. */ + return; + } + + /* Neither server ID or requested IP set, Request generated during + * RENEWING or REBINDING. + */ + + if (!net_if_ipv4_addr_mask_cmp(ctx->iface, &ciaddr)) { + /* Wrong subnet. */ + dhcpv4_send_nak(ctx, msg); + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &ciaddr)) { + selected = slot; + break; + } + } + + if (selected != NULL) { + if (selected->state == DHCPV4_SERVER_ADDR_ALLOCATED && + selected->client_id.len == client_id.len && + memcmp(selected->client_id.buf, client_id.buf, + client_id.len) == 0) { + uint32_t lease_time = dhcpv4_get_lease_time( + options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &ciaddr, lease_time, + ¶ms, false) < 0) { + return; + } + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + dhcpv4_server_timeout_recalc(ctx); + } else { + dhcpv4_send_nak(ctx, msg); + } + } +} + +static void dhcpv4_handle_decline(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_client_id client_id; + struct in_addr requested_ip, server_id; + int ret; + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret < 0) { + /* No server ID, ignore. */ + return; + } + + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret < 0) { + /* Requested IP missing, ignore. */ + return; + } + + LOG_ERR("Received DHCPv4 Decline for %s (address already in use)", + net_sprint_ipv4_addr(&requested_ip)); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &requested_ip) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + slot->state = DHCPV4_SERVER_ADDR_DECLINED; + slot->expiry = sys_timepoint_calc(K_FOREVER); + dhcpv4_server_timeout_recalc(ctx); + break; + } + } +} + +static void dhcpv4_handle_release(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_client_id client_id; + struct in_addr ciaddr, server_id; + int ret; + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret < 0) { + /* No server ID, ignore. */ + return; + } + + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &ciaddr) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + LOG_DBG("DHCPv4 processing Release - %s", + net_sprint_ipv4_addr(&slot->addr)); + + slot->state = DHCPV4_SERVER_ADDR_FREE; + slot->expiry = sys_timepoint_calc(K_FOREVER); + dhcpv4_server_timeout_recalc(ctx); + break; + } + } +} + +static void dhcpv4_handle_inform(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + (void)dhcpv4_send_ack(ctx, msg, (struct in_addr *)msg->ciaddr, 0, + ¶ms, true); +} + +/* Server core. */ + +static void dhcpv4_server_timeout(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct dhcpv4_server_ctx *ctx = + CONTAINER_OF(dwork, struct dhcpv4_server_ctx, timeout_work); + + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED) { + if (sys_timepoint_expired(slot->expiry)) { + LOG_DBG("Address %s expired", + net_sprint_ipv4_addr(&slot->addr)); + slot->state = DHCPV4_SERVER_ADDR_FREE; + } + } + } + + dhcpv4_server_timeout_recalc(ctx); + + k_mutex_unlock(&server_lock); +} + +static void dhcpv4_process_data(struct dhcpv4_server_ctx *ctx, uint8_t *data, + size_t datalen) +{ + struct dhcp_msg *msg; + uint8_t msgtype; + int ret; + + if (datalen < sizeof(struct dhcp_msg)) { + LOG_DBG("DHCPv4 server malformed message"); + return; + } + + msg = (struct dhcp_msg *)data; + + if (msg->op != DHCPV4_MSG_BOOT_REQUEST) { + /* Silently drop messages other than BOOTREQUEST */ + return; + } + + data += sizeof(struct dhcp_msg); + datalen -= sizeof(struct dhcp_msg); + + /* Skip server hostname/filename/option cookie */ + if (datalen < (SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE)) { + return; + } + + data += SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE; + datalen -= SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE; + + /* Search options for DHCP message type. */ + ret = dhcpv4_find_message_type_option(data, datalen, &msgtype); + if (ret < 0) { + LOG_ERR("No message type option"); + return; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + switch (msgtype) { + case NET_DHCPV4_MSG_TYPE_DISCOVER: + dhcpv4_handle_discover(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_REQUEST: + dhcpv4_handle_request(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_DECLINE: + dhcpv4_handle_decline(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_RELEASE: + dhcpv4_handle_release(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_INFORM: + dhcpv4_handle_inform(ctx, msg, data, datalen); + break; + + case NET_DHCPV4_MSG_TYPE_OFFER: + case NET_DHCPV4_MSG_TYPE_ACK: + case NET_DHCPV4_MSG_TYPE_NAK: + default: + /* Ignore server initiated and unknown message types. */ + break; + } + + k_mutex_unlock(&server_lock); +} + +static void dhcpv4_server_cb(struct k_work *work) +{ + struct net_socket_service_event *evt = + CONTAINER_OF(work, struct net_socket_service_event, work); + struct dhcpv4_server_ctx *ctx = NULL; + uint8_t recv_buf[NET_IPV4_MTU]; + int ret; + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].sock == evt->event.fd) { + ctx = &server_ctx[i]; + break; + } + } + + if (ctx == NULL) { + LOG_ERR("No DHCPv4 server context found for given FD."); + return; + } + + if (evt->event.revents & ZSOCK_POLLERR) { + LOG_ERR("DHCPv4 server poll revents error"); + net_dhcpv4_server_stop(ctx->iface); + return; + } + + if (!(evt->event.revents & ZSOCK_POLLIN)) { + return; + } + + ret = zsock_recvfrom(evt->event.fd, recv_buf, sizeof(recv_buf), + ZSOCK_MSG_DONTWAIT, NULL, 0); + if (ret < 0) { + if (errno == EAGAIN) { + return; + } + + LOG_ERR("DHCPv4 server recv error, %d", errno); + net_dhcpv4_server_stop(ctx->iface); + return; + } + + dhcpv4_process_data(ctx, recv_buf, ret); +} + +NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(dhcpv4_server, NULL, dhcpv4_server_cb, + CONFIG_NET_DHCPV4_SERVER_INSTANCES); + +int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr = INADDR_ANY_INIT, + .sin_port = htons(DHCPV4_SERVER_PORT), + }; + struct ifreq ifreq = { 0 }; + int ret, sock = -1, slot = -1; + const struct in_addr *server_addr; + struct in_addr netmask; + + if (iface == NULL || base_addr == NULL) { + return -EINVAL; + } + + if (!net_if_ipv4_addr_mask_cmp(iface, base_addr)) { + LOG_ERR("Address pool does not belong to the interface subnet."); + return -EINVAL; + } + + server_addr = net_if_ipv4_select_src_addr(iface, base_addr); + if (server_addr == NULL) { + LOG_ERR("Failed to obtain a valid server address."); + return -EINVAL; + } + + netmask = net_if_ipv4_get_netmask(iface); + if (net_ipv4_is_addr_unspecified(&netmask)) { + LOG_ERR("Failed to obtain subnet mask."); + return -EINVAL; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface != NULL) { + if (server_ctx[i].iface == iface) { + LOG_ERR("DHCPv4 server instance already running."); + ret = -EALREADY; + goto error; + } + } else { + if (slot < 0) { + slot = i; + } + } + } + + if (slot < 0) { + LOG_ERR("No free DHCPv4 server intance."); + ret = -ENOMEM; + goto error; + } + + ret = net_if_get_name(iface, ifreq.ifr_name, sizeof(ifreq.ifr_name)); + if (ret < 0) { + LOG_ERR("Failed to obtain interface name."); + goto error; + } + + sock = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + ret = errno; + LOG_ERR("Failed to create DHCPv4 server socket, %d", ret); + goto error; + } + + ret = zsock_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, + sizeof(ifreq)); + if (ret < 0) { + ret = errno; + LOG_ERR("Failed to bind DHCPv4 server socket with interface, %d", + ret); + goto error; + } + + ret = zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + ret = errno; + LOG_ERR("Failed to bind DHCPv4 server socket, %d", ret); + goto error; + } + + fds[slot].fd = sock; + fds[slot].events = ZSOCK_POLLIN; + + server_ctx[slot].iface = iface; + server_ctx[slot].sock = sock; + server_ctx[slot].server_addr = *server_addr; + server_ctx[slot].netmask = netmask; + + k_work_init_delayable(&server_ctx[slot].timeout_work, + dhcpv4_server_timeout); + + LOG_DBG("Started DHCPv4 server, address pool:"); + for (int i = 0; i < ARRAY_SIZE(server_ctx[slot].addr_pool); i++) { + server_ctx[slot].addr_pool[i].state = DHCPV4_SERVER_ADDR_FREE; + server_ctx[slot].addr_pool[i].addr.s_addr = + htonl(ntohl(base_addr->s_addr) + i); + + LOG_DBG("\t%2d: %s", i, + net_sprint_ipv4_addr( + &server_ctx[slot].addr_pool[i].addr)); + } + + ret = net_socket_service_register(&dhcpv4_server, fds, ARRAY_SIZE(fds), + NULL); + if (ret < 0) { + LOG_ERR("Failed to register socket service, %d", ret); + memset(&server_ctx[slot], 0, sizeof(server_ctx[slot])); + fds[slot].fd = -1; + goto error; + } + + k_mutex_unlock(&server_lock); + + return 0; + +error: + if (sock >= 0) { + (void)zsock_close(sock); + } + + k_mutex_unlock(&server_lock); + + return ret; +} + +int net_dhcpv4_server_stop(struct net_if *iface) +{ + struct k_work_sync sync; + int slot = -1; + int ret = 0; + bool service_stop = true; + + if (iface == NULL) { + return -EINVAL; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface == iface) { + slot = i; + break; + } + } + + if (slot < 0) { + ret = -ENOENT; + goto out; + } + + fds[slot].fd = -1; + (void)zsock_close(server_ctx[slot].sock); + + k_work_cancel_delayable_sync(&server_ctx[slot].timeout_work, &sync); + + memset(&server_ctx[slot], 0, sizeof(server_ctx[slot])); + + for (int i = 0; i < ARRAY_SIZE(fds); i++) { + if (fds[i].fd >= 0) { + service_stop = false; + break; + } + } + + if (service_stop) { + ret = net_socket_service_unregister(&dhcpv4_server); + } else { + ret = net_socket_service_register(&dhcpv4_server, fds, + ARRAY_SIZE(fds), NULL); + } + +out: + k_mutex_unlock(&server_lock); + + return ret; +} + +static void dhcpv4_server_foreach_lease_on_ctx(struct dhcpv4_server_ctx *ctx, + net_dhcpv4_lease_cb_t cb, + void *user_data) +{ + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *addr = &ctx->addr_pool[i]; + + if (addr->state != DHCPV4_SERVER_ADDR_FREE) { + cb(ctx->iface, addr, user_data); + } + } +} + +int net_dhcpv4_server_foreach_lease(struct net_if *iface, + net_dhcpv4_lease_cb_t cb, + void *user_data) +{ + int slot = -1; + int ret = 0; + + k_mutex_lock(&server_lock, K_FOREVER); + + if (iface == NULL) { + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface != NULL) { + dhcpv4_server_foreach_lease_on_ctx( + &server_ctx[i], cb, user_data); + } + } + + return 0; + } + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface == iface) { + slot = i; + break; + } + } + + if (slot < 0) { + ret = -ENOENT; + goto out; + } + + dhcpv4_server_foreach_lease_on_ctx(&server_ctx[slot], cb, user_data); + +out: + k_mutex_unlock(&server_lock); + + return ret; +} + +void net_dhcpv4_server_init(void) +{ + for (int i = 0; i < ARRAY_SIZE(fds); i++) { + fds[i].fd = -1; + } +} diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index dd3c0c45618f..1e5a7ac8f6af 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -392,6 +392,13 @@ config LWM2M_COMPOSITE_PATH_LIST_SIZE help Define path list size for Composite Read and send operation. +config LWM2M_DEVICE_ERROR_CODE_SETTINGS + bool "Use settings to store error codes across device resets" + depends on SETTINGS + help + Store the device error code list in settings. Ensures error list can + be transferred to LwM2M server even if the device is reset. + config LWM2M_DEVICE_PWRSRC_MAX int "Maximum # of device power source records" default 5 diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 45d3822bdbb2..e08bb4ca17ea 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -197,6 +197,11 @@ int lwm2m_socket_suspend(struct lwm2m_ctx *client_ctx) lwm2m_close_socket(client_ctx); /* store back the socket handle */ client_ctx->sock_fd = socket_temp_id; + + if (client_ctx->set_socket_state) { + client_ctx->set_socket_state(client_ctx->sock_fd, + LWM2M_SOCKET_STATE_NO_DATA); + } } return ret; @@ -581,14 +586,24 @@ void lwm2m_socket_del(struct lwm2m_ctx *ctx) lwm2m_engine_wake_up(); } -static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) +/* Generate notify messages. Return timestamp of next Notify event */ +static int64_t check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) { struct observe_node *obs; int rc; + int64_t next = INT64_MAX; lwm2m_registry_lock(); SYS_SLIST_FOR_EACH_CONTAINER(&ctx->observer, obs, node) { - if (!obs->event_timestamp || timestamp < obs->event_timestamp) { + if (!obs->event_timestamp) { + continue; + } + + if (obs->event_timestamp < next) { + next = obs->event_timestamp; + } + + if (timestamp < obs->event_timestamp) { continue; } /* Check That There is not pending process*/ @@ -604,6 +619,7 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) obs->event_timestamp = engine_observe_shedule_next_event(obs, ctx->srv_obj_inst, timestamp); obs->last_timestamp = timestamp; + if (!rc) { /* create at most one notification */ goto cleanup; @@ -611,6 +627,51 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) } cleanup: lwm2m_registry_unlock(); + return next; +} + +/** + * @brief Check TX queue states as well as number or pending CoAP transmissions. + * + * If all queues are empty and there is no packet we are currently transmitting and no + * CoAP responses (pendings) we are waiting, inform the application by a callback + * that socket is in state LWM2M_SOCKET_STATE_NO_DATA. + * Otherwise, before sending a packet, depending on the state of the queues, inform with + * one of the ONGOING, ONE_RESPONSE or LAST indicators. + * + * @param ctx Client context. + * @param ongoing_tx Current packet to be transmitted or NULL. + */ +static void hint_socket_state(struct lwm2m_ctx *ctx, struct lwm2m_message *ongoing_tx) +{ + if (!ctx->set_socket_state) { + return; + } + +#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) + bool empty = sys_slist_is_empty(&ctx->pending_sends) && + sys_slist_is_empty(&ctx->queued_messages); +#else + bool empty = sys_slist_is_empty(&ctx->pending_sends); +#endif + size_t pendings = coap_pendings_count(ctx->pendings, ARRAY_SIZE(ctx->pendings)); + + if (ongoing_tx) { + /* Check if more than current TX is in pendings list*/ + if (pendings > 1) { + empty = false; + } + + if (!empty) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONGOING); + } else if (ongoing_tx->type == COAP_TYPE_CON) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONE_RESPONSE); + } else { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_LAST); + } + } else if (empty && pendings == 0) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_NO_DATA); + } } static int socket_recv_message(struct lwm2m_ctx *client_ctx) @@ -647,10 +708,10 @@ static int socket_recv_message(struct lwm2m_ctx *client_ctx) return 0; } -static int socket_send_message(struct lwm2m_ctx *client_ctx) +static int socket_send_message(struct lwm2m_ctx *ctx) { int rc; - sys_snode_t *msg_node = sys_slist_get(&client_ctx->pending_sends); + sys_snode_t *msg_node = sys_slist_get(&ctx->pending_sends); struct lwm2m_message *msg; if (!msg_node) { @@ -667,11 +728,15 @@ static int socket_send_message(struct lwm2m_ctx *client_ctx) coap_pending_cycle(msg->pending); } + hint_socket_state(ctx, msg); + rc = zsock_send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0); if (rc < 0) { LOG_ERR("Failed to send packet, err %d", errno); rc = -errno; + } else { + engine_update_tx_time(); } if (msg->type != COAP_TYPE_CON) { @@ -704,7 +769,7 @@ static void socket_loop(void *p1, void *p2, void *p3) int i, rc; int64_t now, next; - int64_t timeout, next_retransmit; + int64_t timeout, next_tx; bool rd_client_paused; while (1) { @@ -741,12 +806,15 @@ static void socket_loop(void *p1, void *p2, void *p3) if (!sys_slist_is_empty(&sock_ctx[i]->pending_sends)) { continue; } - next_retransmit = retransmit_request(sock_ctx[i], now); - if (next_retransmit < next) { - next = next_retransmit; + next_tx = retransmit_request(sock_ctx[i], now); + if (next_tx < next) { + next = next_tx; } if (lwm2m_rd_client_is_registred(sock_ctx[i])) { - check_notifications(sock_ctx[i], now); + next_tx = check_notifications(sock_ctx[i], now); + if (next_tx < next) { + next = next_tx; + } } } @@ -799,6 +867,8 @@ static void socket_loop(void *p1, void *p2, void *p3) break; } } + + hint_socket_state(sock_ctx[i], NULL); } if (sock_fds[i].revents & ZSOCK_POLLOUT) { @@ -1189,6 +1259,12 @@ int lwm2m_engine_pause(void) suspend_engine_thread = true; lwm2m_engine_wake_up(); + /* Check if pause requested within a engine thread, a callback for example. */ + if (engine_thread_id == k_current_get()) { + LOG_DBG("Pause requested"); + return 0; + } + while (active_engine_thread) { k_msleep(10); } @@ -1205,10 +1281,7 @@ int lwm2m_engine_resume(void) k_thread_resume(engine_thread_id); lwm2m_engine_wake_up(); - while (!active_engine_thread) { - k_msleep(10); - } - LOG_INF("LWM2M engine thread resume"); + return 0; } diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index 2306fced197c..81b28395662c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -30,6 +30,7 @@ /* length of time in milliseconds to wait for buffer allocations */ #define BUF_ALLOC_TIMEOUT K_SECONDS(1) + /** * @brief Validates that writing is a legal operation on the field given by the object in * @p obj_inst and the resource id in @p msg. Returns the field to obj_field (if it exists). @@ -133,6 +134,14 @@ int lwm2m_engine_call_now(k_work_handler_t service); */ int lwm2m_security_inst_id_to_index(uint16_t obj_inst_id); +/** + * @brief Returns the object instance id of the security having ssid given by @p short_id. + * + * @param[in] short_id ssid of the security object + * @return Object instance id or negative in case not found + */ +int lwm2m_security_short_id_to_inst(uint16_t short_id); + /** * @brief Returns the object instance id of the security object instance at @p index * in the security object list. @@ -142,45 +151,6 @@ int lwm2m_security_inst_id_to_index(uint16_t obj_inst_id); */ int lwm2m_security_index_to_inst_id(int index); -/** - * @brief Returns the default minimum period for an observation set for the server - * with object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object instance - * @return int32_t pmin value - */ -int32_t lwm2m_server_get_pmin(uint16_t obj_inst_id); - -/** - * @brief Returns the default maximum period for an observation set for the server - * with object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object instance - * @return int32_t pmax value - */ -int32_t lwm2m_server_get_pmax(uint16_t obj_inst_id); - -/** - * @brief Returns the Short Server ID of the server object instance with - * object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object - * @return SSID or negative in case not found - */ -int lwm2m_server_get_ssid(uint16_t obj_inst_id); - -/** - * @brief Returns the object instance id of the server having ssid given by @p short_id. - * - * @param[in] short_id ssid of the server object - * @return Object instance id or negative in case not found - */ -int lwm2m_server_short_id_to_inst(uint16_t short_id); - -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) -bool lwm2m_server_get_mute_send(uint16_t obj_inst_id); -#endif - #if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT) /** * @brief Sets the update state (as specified in LWM2M SPEC E.6 regarding the firmware update) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 6d006b4603e6..480c64372e84 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -45,6 +45,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_engine.h" #include "lwm2m_object.h" #include "lwm2m_obj_access_control.h" +#include "lwm2m_obj_server.h" +#include "lwm2m_obj_gateway.h" #include "lwm2m_rw_link_format.h" #include "lwm2m_rw_oma_tlv.h" #include "lwm2m_rw_plain_text.h" @@ -478,7 +480,7 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx) } /* utility functions */ -static int coap_options_to_path(struct coap_option *opt, int options_count, +int coap_options_to_path(struct coap_option *opt, int options_count, struct lwm2m_obj_path *path) { uint16_t len, @@ -653,8 +655,7 @@ int lwm2m_init_message(struct lwm2m_message *msg) goto cleanup; } - r = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, - CONFIG_COAP_MAX_RETRANSMIT); + r = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, NULL); if (r < 0) { LOG_ERR("Unable to initialize a pending " "retransmission (err:%d).", @@ -2268,6 +2269,15 @@ static int handle_request(struct coap_packet *request, struct lwm2m_message *msg msg->token = token; } + if (IS_ENABLED(CONFIG_LWM2M_GATEWAY_OBJ_SUPPORT)) { + r = lwm2m_gw_handle_req(msg); + if (r == 0) { + return 0; + } else if (r != -ENOENT) { + goto error; + } + } + /* parse the URL path into components */ r = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options, ARRAY_SIZE(options)); if (r < 0) { @@ -2593,8 +2603,7 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) return -ENOMEM; } - ret = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, - CONFIG_COAP_MAX_RETRANSMIT); + ret = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, NULL); if (ret < 0) { LOG_ERR("Unable to initialize a pending " "retransmission (err:%d).", diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index c41fbbac0eee..3ac014b5db8b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.h +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.h @@ -39,6 +39,8 @@ #define NUM_OUTPUT_BLOCK_CONTEXT CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT #endif +int coap_options_to_path(struct coap_option *opt, int options_count, + struct lwm2m_obj_path *path); /* LwM2M message functions */ struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx); struct lwm2m_message *find_msg(struct coap_pending *pending, struct coap_reply *reply); diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_device.c b/subsys/net/lib/lwm2m/lwm2m_obj_device.c index c17815795c26..f5399fefc1e4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_device.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_device.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017 Linaro Limited * Copyright (c) 2018-2019 Foundries.io + * Copyright (c) 2023 FTP Technologies * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +20,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #include "lwm2m_object.h" #include "lwm2m_engine.h" @@ -89,7 +91,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); DEVICE_EXT_DEV_INFO_MAX) /* resource state variables */ -static uint8_t error_code_list[DEVICE_ERROR_CODE_MAX]; +static uint8_t error_code_list[DEVICE_ERROR_CODE_MAX] = { LWM2M_DEVICE_ERROR_NONE }; static time_t time_temp; static time_t time_offset; static uint8_t binding_mode[DEVICE_STRING_SHORT]; @@ -129,23 +131,46 @@ static struct lwm2m_engine_res_inst res_inst[RESOURCE_INSTANCE_COUNT]; /* save error code resource instance point so we can easily clear later */ static struct lwm2m_engine_res_inst *error_code_ri; +#define SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "lwm2m_obj_dev" +#define ERROR_LIST_KEY "err" + /* callbacks */ -static int reset_error_list_cb(uint16_t obj_inst_id, - uint8_t *args, uint16_t args_len) +static void reset_error_list(void) { int i; /* "delete" error codes */ for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) { - error_code_list[i] = 0; + error_code_list[i] = LWM2M_DEVICE_ERROR_NONE; error_code_ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED; } /* Default error code indicating no error */ error_code_ri[0].res_inst_id = 0; +} + +static int reset_error_list_cb(uint16_t obj_inst_id, + uint8_t *args, uint16_t args_len) +{ + int ret = 0; + + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(args); + ARG_UNUSED(args_len); + + reset_error_list(); - return 0; + lwm2m_notify_observer(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_ERROR_CODE_ID); + + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_delete(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "/" ERROR_LIST_KEY); + if (ret != 0) { + LOG_ERR("Couldn't save error list: %d", ret); + } + } + + return ret; } static void *current_time_read_cb(uint16_t obj_inst_id, uint16_t res_id, @@ -182,13 +207,13 @@ static int current_time_post_write_cb(uint16_t obj_inst_id, uint16_t res_id, } /* error code function */ - int lwm2m_device_add_err(uint8_t error_code) { + int ret = 0; int i; for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) { - if (error_code_list[i] == 0) { + if (error_code_list[i] == LWM2M_DEVICE_ERROR_NONE) { break; } @@ -206,7 +231,15 @@ int lwm2m_device_add_err(uint8_t error_code) error_code_ri[i].res_inst_id = i; lwm2m_notify_observer(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_ERROR_CODE_ID); - return 0; + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_save_one(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "/" ERROR_LIST_KEY, + error_code_list, i + 1); + if (ret != 0) { + LOG_ERR("Couldn't save error list: %d", ret); + } + } + + return ret; } static void device_periodic_service(struct k_work *work) @@ -219,6 +252,49 @@ int lwm2m_update_device_service_period(uint32_t period_ms) return lwm2m_engine_update_service_period(device_periodic_service, period_ms); } +static int lwm2m_obj_device_settings_set(const char *name, size_t len, + settings_read_cb read_cb, void *cb_arg) +{ + const char *next; + int rc; + int i; + + if (settings_name_steq(name, ERROR_LIST_KEY, &next) && !next) { + if (len > sizeof(error_code_list)) { + LOG_ERR("Error code list too large: %zu", len); + return -EINVAL; + } + + rc = read_cb(cb_arg, error_code_list, sizeof(error_code_list)); + if (rc == 0) { + reset_error_list(); + return 0; + } else if (rc > 0) { + for (i = 0; i < ARRAY_SIZE(error_code_list); i++) { + if (i < rc) { + error_code_ri[i].res_inst_id = i; + } else { + /* Reset remaining error code instances */ + error_code_list[i] = LWM2M_DEVICE_ERROR_NONE; + error_code_ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED; + } + } + return 0; + } + + LOG_ERR("Error code list read failure: %d", rc); + + return rc; + } + + return -ENOENT; +} + +static struct settings_handler lwm2m_obj_device_settings_handler = { + .name = SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE, + .h_set = lwm2m_obj_device_settings_set, +}; + static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id) { int i = 0, j = 0; @@ -271,7 +347,7 @@ static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id) static int lwm2m_device_init(void) { struct lwm2m_engine_obj_inst *obj_inst = NULL; - int ret = 0; + int ret; /* Set default values */ time_offset = 0U; @@ -294,12 +370,26 @@ static int lwm2m_device_init(void) LOG_DBG("Create LWM2M instance 0 error: %d", ret); } - /* Create the default error code resource instance */ - lwm2m_device_add_err(0); + /* Ensure error list is reset if not loaded from settings */ + reset_error_list(); + + /* Load error code resource instances */ + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_register(&lwm2m_obj_device_settings_handler); + if (ret == 0) { + ret = settings_load_subtree(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE); + if (ret != 0) { + LOG_ERR("Settings load failed: %d", ret); + } + } else { + LOG_ERR("Settings register failed: %d", ret); + } + } /* call device_periodic_service() every 10 seconds */ ret = lwm2m_engine_add_service(device_periodic_service, DEVICE_SERVICE_INTERVAL_MS); + return ret; } diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c index 711fd5fe127d..5bb12f80f478 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c @@ -59,6 +59,7 @@ static struct lwm2m_engine_obj_field fields[] = { static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][GATEWAY_MAX_ID]; static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT]; +lwm2m_engine_gateway_msg_cb gateway_msg_cb[MAX_INSTANCE_COUNT]; static int prefix_validation_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, uint8_t *data, uint16_t data_len, bool last_block, @@ -146,6 +147,57 @@ static struct lwm2m_engine_obj_inst *lwm2m_gw_create(uint16_t obj_inst_id) return &inst[index]; } +int lwm2m_gw_handle_req(struct lwm2m_message *msg) +{ + struct coap_option options[4]; + int ret; + + ret = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options, + ARRAY_SIZE(options)); + if (ret < 0) { + return ret; + } + + for (int index = 0; index < MAX_INSTANCE_COUNT; index++) { + /* Skip uninitialized objects */ + if (!inst[index].obj) { + continue; + } + + char *prefix = device_table[index].prefix; + size_t prefix_len = strlen(prefix); + + if (prefix_len != options[0].len) { + continue; + } + if (strncmp(options[0].value, prefix, prefix_len) != 0) { + continue; + } + + if (gateway_msg_cb[index] == NULL) { + return -ENOENT; + } + /* Delete prefix from path*/ + ret = coap_options_to_path(&options[1], ret - 1, &msg->path); + if (ret < 0) { + return ret; + } + return gateway_msg_cb[index](msg); + } + return -ENOENT; +} + +int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb) +{ + for (int index = 0; index < MAX_INSTANCE_COUNT; index++) { + if (inst[index].obj_inst_id == obj_inst_id) { + gateway_msg_cb[index] = cb; + return 0; + } + } + return -ENOENT; +} + static int lwm2m_gw_init(void) { int ret = 0; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h index 597e3de19bc4..0f7a82af2494 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h +++ b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h @@ -9,6 +9,8 @@ #ifndef __LWM2M_OBJ_GATEWAY__ #define __LWM2M_OBJ_GATEWAY__ +#include + /* LwM2M Gateway resource IDs */ /* clang-format off */ #define LWM2M_GATEWAY_DEVICE_RID 0 @@ -17,4 +19,42 @@ #define LWM2M_GATEWAY_IOT_DEVICE_OBJECTS_RID 3 /* clang-format on */ +/** + * @brief A callback which handles the prefixed messages from the server. + * + * The callback gets triggered each time the prefix in front of a received lwm2m + * msg path matches the prefix set in the LWM2M_GATEWAY_PREFIX_RID buffer. + * + * It must handle the content of the coap message completely. + * In case of success the LwM2M engine will then send the formatted coap message, + * otherwise a coap response code is sent. + * + * Example of returning CoAP response: + * @code{.c} + * lwm2m_init_message(msg); + * // Write CoAP packet to msg->out.out_cpkt + * return 0; + * @endcode + * + * + * @return 0 if msg contains a valid CoAP response. + * @return negative error code otherwise. + */ +typedef int (*lwm2m_engine_gateway_msg_cb)(struct lwm2m_message *msg); +/** + * @brief Register a callback which handles the prefixed messages from the server. + * + * @return 0 on success + * @return -ENOENT if no object instance with obj_inst_id was found + */ +int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb); +/** + * @brief Check if given message is handled by Gateway callback. + * + * @return 0 if msg was handled by Gateawy and contains a valid response. Negative error code + * otherwise. + * @return -ENOENT if this msg was not handled by Gateway object. + */ +int lwm2m_gw_handle_req(struct lwm2m_message *msg); + #endif /* __LWM2M_OBJ_GATEWAY__ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_security.c b/subsys/net/lib/lwm2m/lwm2m_obj_security.c index 874925c39d89..007966486346 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_security.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_security.c @@ -212,6 +212,16 @@ int lwm2m_security_index_to_inst_id(int index) return inst[index].obj_inst_id; } +int lwm2m_security_short_id_to_inst(uint16_t short_id) +{ + for (int i = 0; i < MAX_INSTANCE_COUNT; i++) { + if (short_server_id[i] == short_id) { + return inst[i].obj_inst_id; + } + } + return -ENOENT; +} + int lwm2m_security_mode(struct lwm2m_ctx *ctx) { int ret; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.c b/subsys/net/lib/lwm2m/lwm2m_obj_server.c index a1b2185ef1d6..a9432340038e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_server.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.c @@ -15,8 +15,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include "lwm2m_object.h" -#include "lwm2m_engine.h" +#include "lwm2m_obj_server.h" #include "lwm2m_rd_client.h" +#include "lwm2m_registry.h" #define SERVER_VERSION_MAJOR 1 #if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) @@ -27,37 +28,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define SERVER_MAX_ID 9 #endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ -/* Server resource IDs */ -#define SERVER_SHORT_SERVER_ID 0 -#define SERVER_LIFETIME_ID 1 -#define SERVER_DEFAULT_MIN_PERIOD_ID 2 -#define SERVER_DEFAULT_MAX_PERIOD_ID 3 -#define SERVER_DISABLE_ID 4 -#define SERVER_DISABLE_TIMEOUT_ID 5 -#define SERVER_STORE_NOTIFY_ID 6 -#define SERVER_TRANSPORT_BINDING_ID 7 -#define SERVER_REG_UPDATE_TRIGGER_ID 8 -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) -#define SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID 9 -#define SERVER_APN_LINK_ID 10 -#define SERVER_TLS_DTLS_ALERT_CODE_ID 11 -#define SERVER_LAST_BOOTSTRAPPED_ID 12 -#define SERVER_REGISTRATION_PRIORITY_ORDER_ID 13 -#define SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID 14 -#define SERVER_REGISTRATION_FAILURE_BLOCK_ID 15 -#define SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID 16 -#define SERVER_COMMUNICATION_RETRY_COUNT_ID 17 -#define SERVER_COMMUNICATION_RETRY_TIMER_ID 18 -#define SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID 19 -#define SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID 20 -#define SERVER_SMS_TRIGGER_ID 21 -#define SERVER_PREFERRED_TRANSPORT_ID 22 -#define SERVER_MUTE_SEND_ID 23 -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ - - /* Server flags */ -#define SERVER_FLAG_DISABLED 1 #define SERVER_FLAG_STORE_NOTIFY 2 #define MAX_INSTANCE_COUNT CONFIG_LWM2M_SERVER_INSTANCE_COUNT @@ -76,13 +47,14 @@ static uint16_t server_id[MAX_INSTANCE_COUNT]; static uint32_t lifetime[MAX_INSTANCE_COUNT]; static uint32_t default_min_period[MAX_INSTANCE_COUNT]; static uint32_t default_max_period[MAX_INSTANCE_COUNT]; -static uint8_t server_flag_disabled[MAX_INSTANCE_COUNT]; +static k_timepoint_t disabled_until[MAX_INSTANCE_COUNT]; static uint32_t disabled_timeout[MAX_INSTANCE_COUNT]; static uint8_t server_flag_store_notify[MAX_INSTANCE_COUNT]; static char transport_binding[MAX_INSTANCE_COUNT][TRANSPORT_BINDING_LEN]; -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) +/* Server object version 1.1 */ +static uint8_t priority[MAX_INSTANCE_COUNT]; static bool mute_send[MAX_INSTANCE_COUNT]; -#endif +static bool boostrap_on_fail[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_obj server; static struct lwm2m_engine_obj_field fields[] = { @@ -101,10 +73,10 @@ static struct lwm2m_engine_obj_field fields[] = { OBJ_FIELD_DATA(SERVER_APN_LINK_ID, RW_OPT, OBJLNK), OBJ_FIELD_DATA(SERVER_TLS_DTLS_ALERT_CODE_ID, R_OPT, U8), OBJ_FIELD_DATA(SERVER_LAST_BOOTSTRAPPED_ID, R_OPT, TIME), - OBJ_FIELD_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, W_OPT, U16), + OBJ_FIELD_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, RW_OPT, U8), OBJ_FIELD_DATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, W_OPT, BOOL), - OBJ_FIELD_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, W_OPT, BOOL), + OBJ_FIELD_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, RW_OPT, BOOL), OBJ_FIELD_DATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, W_OPT, U16), @@ -123,13 +95,21 @@ static struct lwm2m_engine_res_inst static int disable_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { - int i; + ARG_UNUSED(args); + ARG_UNUSED(args_len); - LOG_DBG("DISABLE %d", obj_inst_id); - for (i = 0; i < MAX_INSTANCE_COUNT; i++) { + int ret; + + for (int i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { - server_flag_disabled[i] = 1U; - return 0; + LOG_DBG("DISABLE %d", obj_inst_id); + ret = lwm2m_rd_client_server_disabled(obj_inst_id); + if (ret == 0) { + disabled_until[i] = + sys_timepoint_calc(K_SECONDS(disabled_timeout[i])); + return 0; + } + return ret; } } @@ -143,7 +123,6 @@ static int update_trigger_cb(uint16_t obj_inst_id, return 0; } -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) static int bootstrap_trigger_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { @@ -161,7 +140,6 @@ bool lwm2m_server_get_mute_send(uint16_t obj_inst_id) } return false; } -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ static int lifetime_write_cb(uint16_t obj_inst_id, uint16_t res_id, @@ -233,6 +211,116 @@ int lwm2m_server_short_id_to_inst(uint16_t short_id) return -ENOENT; } +static int lwm2m_server_inst_id_to_index(uint16_t obj_inst_id) +{ + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { + return i; + } + } + return -1; +} + +bool lwm2m_server_is_enabled(uint16_t obj_inst_id) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return false; + } + return sys_timepoint_expired(disabled_until[idx]); +} + +int lwm2m_server_disable(uint16_t obj_inst_id, k_timeout_t timeout) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return -ENOENT; + } + disabled_until[idx] = sys_timepoint_calc(timeout); + return 0; +} + +k_timepoint_t lwm2m_server_get_disabled_time(uint16_t obj_inst_id) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return sys_timepoint_calc(K_FOREVER); + } + return disabled_until[idx]; +} + +void lwm2m_server_reset_timestamps(void) +{ + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + disabled_until[i] = sys_timepoint_calc(K_NO_WAIT); + } +} + +bool lwm2m_server_select(uint16_t *obj_inst_id) +{ + uint8_t min = UINT8_MAX; + uint8_t max = 0; + + /* Find priority boundaries */ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + if (min > priority[i]) { + min = priority[i]; + } + if (max < priority[i]) { + max = priority[i]; + } + } + } else { + min = max = 0; + } + + for (uint8_t prio = min; prio <= max; prio++) { + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + /* Disabled for a period */ + if (!lwm2m_server_is_enabled(inst[i].obj_inst_id)) { + continue; + } + + /* Invalid short IDs */ + if (server_id[i] == 0 || server_id[i] == UINT16_MAX) { + continue; + } + + /* Check priority */ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + if (priority[i] > prio) { + continue; + } + } + if (obj_inst_id) { + *obj_inst_id = inst[i].obj_inst_id; + } + return true; + } + } + + LOG_ERR("No server candidate found"); + return false; +} + +uint8_t lwm2m_server_get_prio(uint16_t obj_inst_id) +{ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return UINT8_MAX; + } + return priority[idx]; + } + + return (uint8_t)obj_inst_id % UINT8_MAX; +} + static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) { int index, i = 0, j = 0; @@ -259,16 +347,14 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) } /* Set default values */ - server_flag_disabled[index] = 0U; + disabled_until[i] = sys_timepoint_calc(K_NO_WAIT); server_flag_store_notify[index] = 0U; server_id[index] = index + 1; lifetime[index] = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME; default_min_period[index] = CONFIG_LWM2M_SERVER_DEFAULT_PMIN; default_max_period[index] = CONFIG_LWM2M_SERVER_DEFAULT_PMAX; disabled_timeout[index] = 86400U; -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) - mute_send[index] = false; -#endif + boostrap_on_fail[index] = true; lwm2m_engine_get_binding(transport_binding[index]); @@ -305,33 +391,39 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) transport_binding[index], TRANSPORT_BINDING_LEN, strlen(transport_binding[index]) + 1); INIT_OBJ_RES_EXECUTE(SERVER_REG_UPDATE_TRIGGER_ID, res[index], i, update_trigger_cb); -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) - INIT_OBJ_RES_EXECUTE(SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID, res[index], i, - bootstrap_trigger_cb); - INIT_OBJ_RES_OPTDATA(SERVER_APN_LINK_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_TLS_DTLS_ALERT_CODE_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_LAST_BOOTSTRAPPED_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_SMS_TRIGGER_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_PREFERRED_TRANSPORT_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_DATA(SERVER_MUTE_SEND_ID, res[index], i, res_inst[index], j, &mute_send[index], - sizeof(bool)); -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ + + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + mute_send[index] = false; + priority[index] = 0; + INIT_OBJ_RES_EXECUTE(SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID, res[index], i, + bootstrap_trigger_cb); + INIT_OBJ_RES_OPTDATA(SERVER_APN_LINK_ID, res[index], i, res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_TLS_DTLS_ALERT_CODE_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_OPTDATA(SERVER_LAST_BOOTSTRAPPED_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, res[index], i, + res_inst[index], j, &priority[index], sizeof(uint8_t)); + INIT_OBJ_RES_OPTDATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, res[index], i, + res_inst[index], j, &boostrap_on_fail[index], sizeof(bool)); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_SMS_TRIGGER_ID, res[index], i, res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_PREFERRED_TRANSPORT_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_DATA(SERVER_MUTE_SEND_ID, res[index], i, res_inst[index], j, + &mute_send[index], sizeof(bool)); + } inst[index].resources = res[index]; inst[index].resource_count = i; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.h b/subsys/net/lib/lwm2m/lwm2m_obj_server.h new file mode 100644 index 000000000000..56d7a6740717 --- /dev/null +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LWM2M_OBJ_SERVER_H_ +#define LWM2M_OBJ_SERVER_H_ + +#include +#include +#include + +/* Server resource IDs */ +#define SERVER_SHORT_SERVER_ID 0 +#define SERVER_LIFETIME_ID 1 +#define SERVER_DEFAULT_MIN_PERIOD_ID 2 +#define SERVER_DEFAULT_MAX_PERIOD_ID 3 +#define SERVER_DISABLE_ID 4 +#define SERVER_DISABLE_TIMEOUT_ID 5 +#define SERVER_STORE_NOTIFY_ID 6 +#define SERVER_TRANSPORT_BINDING_ID 7 +#define SERVER_REG_UPDATE_TRIGGER_ID 8 +/* Server object version 1.1 resource IDs */ +#define SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID 9 +#define SERVER_APN_LINK_ID 10 +#define SERVER_TLS_DTLS_ALERT_CODE_ID 11 +#define SERVER_LAST_BOOTSTRAPPED_ID 12 +#define SERVER_REGISTRATION_PRIORITY_ORDER_ID 13 +#define SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID 14 +#define SERVER_REGISTRATION_FAILURE_BLOCK_ID 15 +#define SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID 16 +#define SERVER_COMMUNICATION_RETRY_COUNT_ID 17 +#define SERVER_COMMUNICATION_RETRY_TIMER_ID 18 +#define SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID 19 +#define SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID 20 +#define SERVER_SMS_TRIGGER_ID 21 +#define SERVER_PREFERRED_TRANSPORT_ID 22 +#define SERVER_MUTE_SEND_ID 23 + +/** + * @brief Returns the default minimum period for an observation set for the server + * with object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object instance + * @return int32_t pmin value + */ +int32_t lwm2m_server_get_pmin(uint16_t obj_inst_id); + +/** + * @brief Returns the default maximum period for an observation set for the server + * with object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object instance + * @return int32_t pmax value + */ +int32_t lwm2m_server_get_pmax(uint16_t obj_inst_id); + +/** + * @brief Returns the Short Server ID of the server object instance with + * object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object + * @return SSID or negative in case not found + */ +int lwm2m_server_get_ssid(uint16_t obj_inst_id); + +/** + * @brief Returns the object instance id of the server having ssid given by @p short_id. + * + * @param[in] short_id ssid of the server object + * @return Object instance id or negative in case not found + */ +int lwm2m_server_short_id_to_inst(uint16_t short_id); + +/** + * @brief Check if given server instance is not disabled + * + * @param[in] obj_inst_id server instance + * @return true if not disabled, false otherwise. + */ +bool lwm2m_server_is_enabled(uint16_t obj_inst_id); + +/** + * @brief Select server instance. + * + * Find possible server instance considering values on server data. + * Server candidates cannot be in disabled state and if priority values are set, + * those are compared and lowest values are considered first. + * + * If @ref obj_inst_id is NULL, this can be used to check if there are any server available. + * + * @param[out] obj_inst_id where selected server instance ID is written. Can be NULL. + * @return true if server instance was found, false otherwise. + */ +bool lwm2m_server_select(uint16_t *obj_inst_id); + +/** + * @brief Disable server instance for a period of time. + * + * Timeout values can be calculated using kernel macros like K_SECONDS(). + * Values like K_FOREVER or K_NO_WAIT are also accepted. + * + * @param timeout Timeout value. + * @return zero on success, negative error code otherwise. + */ +int lwm2m_server_disable(uint16_t obj_inst_id, k_timeout_t timeout); + +/** + * @brief Get timepoint how long server instance is disabled. + * + * If server instance is not disabled, this still returns a valid timepoint + * that have already expired. + * If the instance id is not valid, the timepoint is set to K_FOREVER. + * + * @param obj_inst_id Server instance ID. + * @return timepoint + */ +k_timepoint_t lwm2m_server_get_disabled_time(uint16_t obj_inst_id); + +/** + * @brief Get priority of given server instance. + * + * Lower values mean higher priority. + * If LwM2M server object version 1.1 is not enabled, + * this returns obj_inst_id as priority. + * + * @param obj_inst_id instance ID + * @return priority or UINT8_MAX if instance not found + */ +uint8_t lwm2m_server_get_prio(uint16_t obj_inst_id); + +/** + * @brief Reset all disable-timers for all server instances. + * + */ +void lwm2m_server_reset_timestamps(void); + +#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) +bool lwm2m_server_get_mute_send(uint16_t obj_inst_id); +#endif + + +#endif /* LWM2M_OBJ_SERVER_H_ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 9ee1fa6eda18..1c8034e6535e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -37,6 +37,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include "lwm2m_obj_server.h" #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) #include "lwm2m_rw_senml_json.h" diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index d9f2e229edd9..95b576cb1c6d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -62,6 +62,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_rd_client.h" #include "lwm2m_rw_link_format.h" #include "lwm2m_util.h" +#include "lwm2m_obj_server.h" #define LWM2M_RD_CLIENT_URI "rd" #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH @@ -71,6 +72,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DELAY_FOR_ACK 100U #define EXCHANGE_LIFETIME 247U #define MINIMUM_PERIOD 15 +#define DISABLE_TIMEOUT (K_SECONDS(CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES * EXCHANGE_LIFETIME)) static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -79,6 +81,8 @@ static void lwm2m_rd_client_service(struct k_work *work); static int64_t calc_next_event(void); static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms); static void set_sm_state(uint8_t sm_state); +/** Try to fallback to bootstrap. Return true if we did. */ +static bool fallback_to_bootstrap(void); /* The states for the RD client state machine */ /* @@ -100,6 +104,7 @@ enum sm_engine_state { ENGINE_REGISTRATION_DONE_RX_OFF, ENGINE_UPDATE_REGISTRATION, ENGINE_UPDATE_SENT, + ENGINE_SERVER_DISABLED, ENGINE_SUSPENDED, ENGINE_DEREGISTER, ENGINE_DEREGISTER_SENT, @@ -124,11 +129,11 @@ struct lwm2m_rd_client_info { char ep_name[CLIENT_EP_LEN]; char server_ep[CLIENT_EP_LEN]; - bool use_bootstrap : 1; - + bool use_bootstrap : 1; bool trigger_update : 1; bool update_objects : 1; - bool close_socket : 1; + bool close_socket : 1; + bool server_disabled: 1; } client; /* Allocate some data for queries and updates. Make sure it's large enough to @@ -200,23 +205,18 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE; } else if (sm_state == ENGINE_REGISTRATION_DONE_RX_OFF) { event = LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF; - } else if ((sm_state == ENGINE_INIT || - sm_state == ENGINE_DEREGISTERED) && + } else if (sm_state == ENGINE_DEREGISTERED && (client.engine_state >= ENGINE_DO_REGISTRATION && - client.engine_state <= ENGINE_DEREGISTER_SENT)) { + client.engine_state <= ENGINE_DEREGISTER_SENT) && !client.server_disabled) { event = LWM2M_RD_CLIENT_EVENT_DISCONNECT; - } else if (sm_state == ENGINE_NETWORK_ERROR) { - lwm2m_socket_close(client.ctx); - client.retry_delay = 1 << client.retries; - client.retries++; - if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) { - client.retries = 0; - event = LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR; - } } else if (sm_state == ENGINE_UPDATE_REGISTRATION) { event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE; } else if (sm_state == ENGINE_DEREGISTER) { - event = LWM2M_RD_CLIENT_EVENT_DEREGISTER; + if (client.server_disabled) { + event = LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED; + } else { + event = LWM2M_RD_CLIENT_EVENT_DEREGISTER; + } } if (sm_is_suspended()) { @@ -291,27 +291,22 @@ static uint8_t get_sm_state(void) return state; } -static void sm_handle_timeout_state(struct lwm2m_message *msg, - enum sm_engine_state sm_state) +static void sm_handle_timeout_state(enum sm_engine_state sm_state) { k_mutex_lock(&client.mutex, K_FOREVER); enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE; -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.engine_state == ENGINE_BOOTSTRAP_REG_SENT) { - event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE; - } else -#endif - { - if (client.engine_state == ENGINE_REGISTRATION_SENT) { - event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; - } else if (client.engine_state == ENGINE_UPDATE_SENT) { - event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; - } else if (client.engine_state == ENGINE_DEREGISTER_SENT) { - event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE; - } else { - /* TODO: unknown timeout state */ - } + /* Don't send BOOTSTRAP_REG_FAILURE event, that is only emitted from + * do_network_error() once we are out of retries. + */ + if (client.engine_state == ENGINE_REGISTRATION_SENT) { + event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; + } else if (client.engine_state == ENGINE_UPDATE_SENT) { + event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; + } else if (client.engine_state == ENGINE_DEREGISTER_SENT) { + event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE; + } else { + /* TODO: unknown timeout state */ } set_sm_state(sm_state); @@ -373,11 +368,14 @@ static void socket_fault_cb(int error) /* Network error state causes engine to re-register, * so only trigger that state if we are not stopping the * engine. + * Also when engine is going to be disabled, for a while, we might get spurious + * socket errors when closing, so ignore them. */ if (client.engine_state > ENGINE_IDLE && - client.engine_state < ENGINE_SUSPENDED) { - set_sm_state(ENGINE_NETWORK_ERROR); - } else if (client.engine_state != ENGINE_SUSPENDED) { + client.engine_state < ENGINE_SERVER_DISABLED) { + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); + } else if (client.engine_state != ENGINE_SUSPENDED && + !client.server_disabled) { sm_handle_failure_state(ENGINE_IDLE); } } @@ -452,13 +450,7 @@ static int do_bootstrap_reply_cb(const struct coap_packet *response, static void do_bootstrap_reg_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("Bootstrap Timeout"); - - /* TODO: - * Look for the "next" BOOTSTRAP server entry in our security info - */ - - /* Restart from scratch */ - sm_handle_timeout_state(msg, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); } #endif @@ -521,6 +513,8 @@ static int do_registration_reply_cb(const struct coap_packet *response, /* remember the last reg time */ client.last_update = k_uptime_get(); + client.server_disabled = false; + client.retries = 0; memcpy(client.server_ep, options[1].value, options[1].len); @@ -532,11 +526,12 @@ static int do_registration_reply_cb(const struct coap_packet *response, return 0; } - LOG_ERR("Failed with code %u.%u (%s). Not Retrying.", + LOG_ERR("Failed with code %u.%u (%s).", COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code), code2str(code)); fail: - sm_handle_failure_state(ENGINE_IDLE); + lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT); + sm_handle_failure_state(ENGINE_NETWORK_ERROR); return ret; } @@ -545,8 +540,7 @@ static void do_registration_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("Registration Timeout"); - /* Restart from scratch */ - sm_handle_timeout_state(msg, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); } static int do_update_reply_cb(const struct coap_packet *response, @@ -587,7 +581,7 @@ static void do_update_timeout_cb(struct lwm2m_message *msg) client.close_socket = true; } /* Re-do registration */ - sm_handle_timeout_state(msg, ENGINE_DO_REGISTRATION); + sm_handle_timeout_state(ENGINE_DO_REGISTRATION); } static int do_deregister_reply_cb(const struct coap_packet *response, @@ -611,7 +605,7 @@ static int do_deregister_reply_cb(const struct coap_packet *response, COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code), code2str(code)); - sm_handle_failure_state(ENGINE_IDLE); + sm_handle_failure_state(ENGINE_DEREGISTERED); return 0; } @@ -620,10 +614,10 @@ static void do_deregister_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("De-Registration Timeout"); - sm_handle_timeout_state(msg, ENGINE_IDLE); + sm_handle_timeout_state(ENGINE_DEREGISTERED); } -static bool sm_bootstrap_verify(bool bootstrap_server, int sec_obj_inst) +static bool is_bootsrap_server(int sec_obj_inst) { bool bootstrap; int ret; @@ -633,12 +627,7 @@ static bool sm_bootstrap_verify(bool bootstrap_server, int sec_obj_inst) LOG_WRN("Failed to check bootstrap, err %d", ret); return false; } - - if (bootstrap == bootstrap_server) { - return true; - } else { - return false; - } + return bootstrap; } static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) @@ -664,58 +653,40 @@ static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) return false; } -static int sm_select_server_inst(int sec_obj_inst, int *srv_obj_inst, - uint32_t *lifetime) -{ - uint16_t server_id; - int ret, obj_inst_id; - - ret = lwm2m_get_u16(&LWM2M_OBJ(0, sec_obj_inst, 10), &server_id); - if (ret < 0) { - LOG_WRN("Failed to obtain Short Server ID, err %d", ret); - return -EINVAL; - } - - obj_inst_id = lwm2m_server_short_id_to_inst(server_id); - if (obj_inst_id < 0) { - LOG_WRN("Failed to obtain Server Object instance, err %d", - obj_inst_id); - return -EINVAL; - } - - sm_update_lifetime(obj_inst_id, lifetime); - *srv_obj_inst = obj_inst_id; - - return 0; -} - -static int sm_select_security_inst(bool bootstrap_server, int *sec_obj_inst) +/** + * @brief Find the next security instance for bootstrapping. + * + * Search for the next security instance that has the bootstrap flag set and + * is not the same as current security instance. + * + * @param sec_obj_inst current security instance or -1. + * @return zero on success, negative on error. + */ +static int sm_next_bootstrap_inst(int *sec_obj_inst) { int i, obj_inst_id = -1; - /* lookup existing index */ - i = lwm2m_security_inst_id_to_index(*sec_obj_inst); - if (i >= 0 && sm_bootstrap_verify(bootstrap_server, *sec_obj_inst)) { - return 0; + if (*sec_obj_inst >= 0 && !is_bootsrap_server(*sec_obj_inst)) { + *sec_obj_inst = -1; } - *sec_obj_inst = -1; - /* Iterate over all instances to find the correct one. */ for (i = 0; i < CONFIG_LWM2M_SECURITY_INSTANCE_COUNT; i++) { obj_inst_id = lwm2m_security_index_to_inst_id(i); if (obj_inst_id < 0) { - LOG_WRN("Failed to get inst id for %d", i); + continue; + } + if (obj_inst_id == *sec_obj_inst) { continue; } - if (sm_bootstrap_verify(bootstrap_server, obj_inst_id)) { + if (is_bootsrap_server(obj_inst_id)) { *sec_obj_inst = obj_inst_id; return 0; } } - LOG_WRN("sec_obj_inst: No matching servers found."); + LOG_WRN("No Bootstrap servers found."); return -ENOENT; } @@ -725,24 +696,17 @@ static int sm_select_security_inst(bool bootstrap_server, int *sec_obj_inst) static int sm_do_init(void) { lwm2m_engine_stop(client.ctx); - client.ctx->sec_obj_inst = -1; - client.ctx->srv_obj_inst = -1; client.trigger_update = false; client.lifetime = 0U; - client.retries = 0U; client.last_update = 0U; client.close_socket = false; /* Do bootstrap or registration */ -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.use_bootstrap) { + if (client.use_bootstrap && IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { set_sm_state(ENGINE_DO_BOOTSTRAP_REG); } else { set_sm_state(ENGINE_DO_REGISTRATION); } -#else - set_sm_state(ENGINE_DO_REGISTRATION); -#endif return 0; } @@ -813,7 +777,7 @@ static int sm_send_bootstrap_registration(void) return ret; } -static int sm_do_bootstrap_reg(void) +static void sm_do_bootstrap_reg(void) { int ret; @@ -823,23 +787,20 @@ static int sm_do_bootstrap_reg(void) } client.ctx->bootstrap_mode = true; - ret = sm_select_security_inst(client.ctx->bootstrap_mode, - &client.ctx->sec_obj_inst); + ret = sm_next_bootstrap_inst(&client.ctx->sec_obj_inst); if (ret < 0) { - /* no bootstrap server found, let's move to registration */ - LOG_WRN("Bootstrap server not found! Try normal registration."); - set_sm_state(ENGINE_DO_REGISTRATION); - return ret; + set_sm_state(ENGINE_NETWORK_ERROR); + return; } - LOG_INF("Bootstrap started with endpoint '%s' with client lifetime %d", - client.ep_name, client.lifetime); + LOG_INF("Bootstrap started with endpoint '%s' using security object %d", + client.ep_name, client.ctx->sec_obj_inst); ret = lwm2m_engine_start(client.ctx); if (ret < 0) { LOG_ERR("Cannot init LWM2M engine (%d)", ret); set_sm_state(ENGINE_NETWORK_ERROR); - return ret; + return; } ret = sm_send_bootstrap_registration(); @@ -850,7 +811,7 @@ static int sm_do_bootstrap_reg(void) set_sm_state(ENGINE_NETWORK_ERROR); } - return ret; + return; } void engine_bootstrap_finish(void) @@ -1046,8 +1007,9 @@ static int sm_send_registration_msg(void) return ret; } -static int sm_do_registration(void) +static void sm_do_registration(void) { + uint16_t ssid; int ret = 0; if (client.ctx->connection_suspended) { @@ -1055,10 +1017,16 @@ static int sm_do_registration(void) lwm2m_engine_context_close(client.ctx); /* perform full registration */ set_sm_state(ENGINE_DO_REGISTRATION); - return 0; + return; } } else { + bool select_srv = true; + uint16_t srv = (uint16_t) client.ctx->srv_obj_inst; + + client.last_update = 0; + client.ctx->bootstrap_mode = false; + /* clear out existing connection data */ if (client.ctx->sock_fd > -1) { if (client.close_socket) { @@ -1067,43 +1035,58 @@ static int sm_do_registration(void) lwm2m_engine_stop(client.ctx); } else { lwm2m_engine_context_close(client.ctx); + /* Keep current connection, retry registration with same server */ + select_srv = false; } } - client.last_update = 0; + if (select_srv) { + /* Select next one from the list, or fail */ + if (!lwm2m_server_select(&srv)) { + LOG_ERR("Unable to find a valid server instance."); + goto bootstrap_or_retry; + } - client.ctx->bootstrap_mode = false; - ret = sm_select_security_inst(client.ctx->bootstrap_mode, - &client.ctx->sec_obj_inst); - if (ret < 0) { - LOG_ERR("Unable to find a valid security instance."); - set_sm_state(ENGINE_INIT); - return -EINVAL; - } + client.ctx->srv_obj_inst = srv; + sm_update_lifetime(srv, &client.lifetime); - ret = sm_select_server_inst(client.ctx->sec_obj_inst, - &client.ctx->srv_obj_inst, - &client.lifetime); - if (ret < 0) { - LOG_ERR("Unable to find a valid server instance."); - set_sm_state(ENGINE_INIT); - return -EINVAL; + ret = lwm2m_get_u16(&LWM2M_OBJ(1, client.ctx->srv_obj_inst, 0), &ssid); + if (ret < 0) { + LOG_ERR("Failed to read SSID"); + lwm2m_server_disable(srv, K_FOREVER); + goto bootstrap_or_retry; + } + + ret = lwm2m_security_short_id_to_inst(ssid); + if (ret < 0) { + LOG_ERR("Unable to find a valid security instance."); + lwm2m_server_disable(srv, K_FOREVER); + goto bootstrap_or_retry; + } + client.ctx->sec_obj_inst = (uint16_t) ret; } - LOG_INF("RD Client started with endpoint '%s' with client lifetime %d", - client.ep_name, client.lifetime); + LOG_INF("RD Client started with endpoint '%s' with client lifetime %d using server " + "object %d", + client.ep_name, client.lifetime, client.ctx->srv_obj_inst); ret = lwm2m_engine_start(client.ctx); if (ret < 0) { LOG_ERR("Cannot init LWM2M engine (%d)", ret); - set_sm_state(ENGINE_NETWORK_ERROR); - return ret; + goto bootstrap_or_retry; } } - ret = sm_send_registration_msg(); + sm_send_registration_msg(); + return; - return ret; +bootstrap_or_retry: + lwm2m_engine_stop(client.ctx); + if (!client.server_disabled && fallback_to_bootstrap()) { + return; + } + + set_sm_state(ENGINE_NETWORK_ERROR); } static int64_t next_update(void) @@ -1149,7 +1132,7 @@ static void sm_registration_done(void) if (sm_is_registered() && (client.trigger_update || now >= next_update())) { - set_sm_state(ENGINE_UPDATE_REGISTRATION); + set_sm_state_delayed(ENGINE_UPDATE_REGISTRATION, DELAY_FOR_ACK); } else if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED) && (client.engine_state != ENGINE_REGISTRATION_DONE_RX_OFF) && (now >= next_rx_off())) { @@ -1268,32 +1251,116 @@ static int sm_do_deregister(void) return ret; } +static bool fallback_to_bootstrap(void) +{ + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + bool fallback = true; + + (void)lwm2m_get_bool(&LWM2M_OBJ(LWM2M_OBJECT_SERVER_ID, client.ctx->srv_obj_inst, + SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID), + &fallback); + if (fallback) { + client.use_bootstrap = true; + set_sm_state(ENGINE_INIT); + return true; + } + } + return false; +} + static void sm_do_network_error(void) { int err; + LOG_ERR("sm_do_network_error, retries %d", client.retries); + + lwm2m_socket_close(client.ctx); + if (client.retry_delay) { - client.retry_delay = 0; next_event_at(k_uptime_get() + client.retry_delay * MSEC_PER_SEC); + client.retry_delay = 0; return; } + client.retry_delay = 1 << client.retries; + client.retries++; -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.ctx->bootstrap_mode) { - lwm2m_engine_context_close(client.ctx); - set_sm_state(ENGINE_DO_BOOTSTRAP_REG); - return; + /* Stop retrying and try fallback */ + if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) { + LOG_ERR("Network error, max retries reached (%d)", client.retries); + + /* Disable current server for a period so lwm2m_server_select() does not pick it */ + if (client.ctx->srv_obj_inst > -1) { + lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT); + } + + /* Are we in bootstrap? Try if we can fallback to some other BS server */ + if (client.ctx->bootstrap_mode && + IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + LOG_DBG("In bootstrap, try fallback srv"); + /* Do we have any other bootstrap server to back off to? */ + if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) { + /* No, we are out of options, stop engine */ + goto stop_engine; + } + set_sm_state(ENGINE_INIT); + return; + } + + /* Try if there are other server to fall back to, + * Only allow fallback to higher priority server (lower value, or lower id) + * if we have successfully registered before. + * This should block us from looping the same list again. + * Instead we should fallback to bootstrap. + */ + uint16_t srv; + + if (lwm2m_server_select(&srv)) { + uint8_t p1, p2; + + p1 = lwm2m_server_get_prio(client.ctx->srv_obj_inst); + p2 = lwm2m_server_get_prio(srv); + if (p1 < p2 || client.last_update != 0) { + set_sm_state(ENGINE_INIT); + return; + } + } + + /* If we have been disabled by some server, don't fall back to bootstrap */ + if (client.server_disabled) { + set_sm_state(ENGINE_SERVER_DISABLED); + return; + } + + if (fallback_to_bootstrap()) { + return; + } + goto stop_engine; + } + + /* Retry bootstrap */ + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + if (client.ctx->bootstrap_mode) { + lwm2m_engine_context_close(client.ctx); + /* If we don't have fallback BS server, retry with current one */ + if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) { + client.ctx->sec_obj_inst = -1; + } + set_sm_state(ENGINE_DO_BOOTSTRAP_REG); + return; + } } -#endif if (!client.last_update || (k_uptime_get() - client.last_update) / MSEC_PER_SEC > client.lifetime) { /* do full registration as there is no active registration or lifetime exceeded */ - lwm2m_engine_context_close(client.ctx); + /* Keep the same server until out of retry */ set_sm_state(ENGINE_DO_REGISTRATION); return; } + /* Try if we can recover the DTLS session and try Update. + * This might fallback into full registration on sm_handle_registration_update_failure(). + */ err = lwm2m_socket_start(client.ctx); if (err) { LOG_ERR("Failed to start socket %d", err); @@ -1304,8 +1371,21 @@ static void sm_do_network_error(void) set_sm_state(ENGINE_NETWORK_ERROR); return; } - set_sm_state(ENGINE_UPDATE_REGISTRATION); + return; + +stop_engine: + + /* We are out of options, stop engine */ + if (client.ctx->event_cb) { + if (client.ctx->bootstrap_mode) { + client.ctx->event_cb(client.ctx, + LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE); + } else { + client.ctx->event_cb(client.ctx, LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR); + } + } + set_sm_state(ENGINE_IDLE); } static void lwm2m_rd_client_service(struct k_work *work) @@ -1379,6 +1459,19 @@ static void lwm2m_rd_client_service(struct k_work *work) timeout = EXCHANGE_LIFETIME; break; + case ENGINE_SERVER_DISABLED: + if (lwm2m_server_select(NULL)) { + set_sm_state(ENGINE_INIT); + } else { + /* wait for server to be enabled. */ + /* + * TODO: Once engine is converted to use timepoint_t + * this should calculate the next event from the previous server. + */ + next_event_at(k_uptime_get() + SEC_PER_MIN * MSEC_PER_SEC); + } + break; + case ENGINE_DEREGISTER: sm_do_deregister(); break; @@ -1390,7 +1483,11 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_DEREGISTERED: lwm2m_engine_stop(client.ctx); - set_sm_state(ENGINE_IDLE); + if (client.server_disabled) { + set_sm_state(ENGINE_SERVER_DISABLED); + } else { + set_sm_state(ENGINE_IDLE); + } break; case ENGINE_NETWORK_ERROR: @@ -1407,7 +1504,7 @@ static void lwm2m_rd_client_service(struct k_work *work) if (end < k_uptime_get()) { LOG_DBG("State machine have timed out"); - sm_handle_timeout_state(NULL, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_INIT); } else if (client.next_event > end) { next_event_at(end); } @@ -1441,6 +1538,7 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name, } /* Init Context */ + lwm2m_server_reset_timestamps(); lwm2m_engine_context_init(client_ctx); client.ctx = client_ctx; @@ -1449,13 +1547,15 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name, client.ctx->observe_cb = observe_cb; client.ctx->event_cb = event_cb; client.use_bootstrap = flags & LWM2M_RD_CLIENT_FLAG_BOOTSTRAP; + client.ctx->srv_obj_inst = -1; + client.ctx->sec_obj_inst = -1; + client.retries = 0; - set_sm_state(ENGINE_INIT); strncpy(client.ep_name, ep_name, CLIENT_EP_LEN - 1); client.ep_name[CLIENT_EP_LEN - 1] = '\0'; LOG_INF("Start LWM2M Client: %s", client.ep_name); - next_event_at(0); + set_sm_state(ENGINE_INIT); k_mutex_unlock(&client.mutex); @@ -1476,9 +1576,10 @@ int lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx, client.ctx->event_cb = event_cb; rd_client_message_free(); - if (sm_is_registered() && deregister) { + if (sm_is_registered() && deregister && !client.server_disabled) { set_sm_state(ENGINE_DEREGISTER); } else { + client.server_disabled = false; set_sm_state(ENGINE_DEREGISTERED); } @@ -1556,7 +1657,7 @@ int lwm2m_rd_client_resume(void) #endif /* Or do we resume into registration state */ if (client.engine_state >= ENGINE_DO_REGISTRATION && - client.engine_state <= ENGINE_SUSPENDED) { + client.engine_state <= ENGINE_SERVER_DISABLED) { if (!client.last_update || (client.lifetime <= (k_uptime_get() - client.last_update) / MSEC_PER_SEC)) { /* No lifetime left, register again */ @@ -1574,6 +1675,29 @@ int lwm2m_rd_client_resume(void) return 0; } +int lwm2m_rd_client_server_disabled(uint16_t inst_id) +{ + if (client.ctx->srv_obj_inst != inst_id) { + return -EPERM; + } + + k_mutex_lock(&client.mutex, K_FOREVER); + + client.server_disabled = true; + + if (sm_is_registered()) { + LOG_INF("Server disabled, deregister"); + set_sm_state_delayed(ENGINE_DEREGISTER, DELAY_BEFORE_CLOSING); + } else { + LOG_INF("Server disabled"); + set_sm_state(ENGINE_DEREGISTERED); + } + + k_mutex_unlock(&client.mutex); + + return 0; +} + void lwm2m_rd_client_update(void) { engine_trigger_update(false); diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.h b/subsys/net/lib/lwm2m/lwm2m_rd_client.h index 66a3aac20f32..5d71ccb30f67 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.h +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.h @@ -56,4 +56,14 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx); void engine_update_tx_time(void); struct lwm2m_message *lwm2m_get_ongoing_rd_msg(void); +/** + * @brief Notify RD client that this server is disabled. + * + * This may return error -EPERM, if RD client is not registered on that server. + * + * @param inst_id server instance id + * @return int 0 on success, negative errno on failure. + */ +int lwm2m_rd_client_server_disabled(uint16_t inst_id); + #endif /* LWM2M_RD_CLIENT_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index 210c55257563..1701b7f74121 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -890,7 +890,7 @@ int lwm2m_engine_set_u64(const char *pathstr, uint64_t value) if (ret < 0) { return ret; } - return lwm2m_set_u64(&path, value); + return lwm2m_set_s64(&path, (int64_t) value); } int lwm2m_set_s8(const struct lwm2m_obj_path *path, int8_t value) @@ -1378,7 +1378,7 @@ int lwm2m_engine_get_u64(const char *pathstr, uint64_t *value) if (ret < 0) { return ret; } - return lwm2m_get_u64(&path, value); + return lwm2m_get_s64(&path, (int64_t *) value); } int lwm2m_get_s8(const struct lwm2m_obj_path *path, int8_t *value) diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index a4cedf8cd625..aad7dc5d1662 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -246,14 +246,6 @@ static int cmd_read(const struct shell *sh, size_t argc, char **argv) goto out; } shell_print(sh, "%d\n", temp); - } else if (strcmp(dtype, "-u64") == 0) { - uint64_t temp = 0; - - ret = lwm2m_get_u64(&path, &temp); - if (ret != 0) { - goto out; - } - shell_print(sh, "%lld\n", temp); } else if (strcmp(dtype, "-f") == 0) { double temp = 0; @@ -349,8 +341,6 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) ret = lwm2m_set_u16(&path, strtoul(value, &e, 10)); } else if (strcmp(dtype, "-u32") == 0) { ret = lwm2m_set_u32(&path, strtoul(value, &e, 10)); - } else if (strcmp(dtype, "-u64") == 0) { - ret = lwm2m_set_u64(&path, strtoull(value, &e, 10)); } else if (strcmp(dtype, "-b") == 0) { ret = lwm2m_set_bool(&path, strtoul(value, &e, 10)); } else if (strcmp(dtype, "-t") == 0) { diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index c835656b6cf8..8e9cc87239af 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -22,10 +22,15 @@ int mqtt_client_tls_connect(struct mqtt_client *client) { const struct sockaddr *broker = client->broker; struct mqtt_sec_config *tls_config = &client->transport.tls.config; + int type = SOCK_STREAM; int ret; + if (tls_config->set_native_tls) { + type |= SOCK_NATIVE_TLS; + } + client->transport.tls.sock = zsock_socket(broker->sa_family, - SOCK_STREAM, IPPROTO_TLS_1_2); + type, IPPROTO_TLS_1_2); if (client->transport.tls.sock < 0) { return -errno; } @@ -78,6 +83,16 @@ int mqtt_client_tls_connect(struct mqtt_client *client) } } + if (tls_config->session_cache == TLS_SESSION_CACHE_ENABLED) { + ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, + TLS_SESSION_CACHE, + &tls_config->session_cache, + sizeof(tls_config->session_cache)); + if (ret < 0) { + goto error; + } + } + if (tls_config->cert_nocopy != TLS_CERT_NOCOPY_NONE) { ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, TLS_CERT_NOCOPY, &tls_config->cert_nocopy, diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 2c5c07575057..5cfb5c269b44 100644 --- a/subsys/net/lib/shell/CMakeLists.txt +++ b/subsys/net/lib/shell/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources(allocs.c) zephyr_library_sources(arp.c) zephyr_library_sources(capture.c) zephyr_library_sources(conn.c) +zephyr_library_sources(dhcpv4.c) zephyr_library_sources(dns.c) zephyr_library_sources(events.c) zephyr_library_sources(gptp.c) diff --git a/subsys/net/lib/shell/allocs.c b/subsys/net/lib/shell/allocs.c index 1c6e7288003e..a26695905203 100644 --- a/subsys/net/lib/shell/allocs.c +++ b/subsys/net/lib/shell/allocs.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) static void allocs_cb(struct net_pkt *pkt, diff --git a/subsys/net/lib/shell/arp.c b/subsys/net/lib/shell/arp.c index fb1582411e9f..58889f27d5c5 100644 --- a/subsys/net/lib/shell/arp.c +++ b/subsys/net/lib/shell/arp.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_ARP) #include "ethernet/arp.h" diff --git a/subsys/net/lib/shell/capture.c b/subsys/net/lib/shell/capture.c index f05531562ae5..0c7347f87745 100644 --- a/subsys/net/lib/shell/capture.c +++ b/subsys/net/lib/shell/capture.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include diff --git a/subsys/net/lib/shell/conn.c b/subsys/net/lib/shell/conn.c index 36831809eb83..24b528537bd3 100644 --- a/subsys/net/lib/shell/conn.c +++ b/subsys/net/lib/shell/conn.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_TCP) #include "tcp_internal.h" diff --git a/subsys/net/lib/shell/dhcpv4.c b/subsys/net/lib/shell/dhcpv4.c new file mode 100644 index 000000000000..a59b9c45edb6 --- /dev/null +++ b/subsys/net/lib/shell/dhcpv4.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include +#include +#include + +#include "net_shell_private.h" + +static int cmd_net_dhcpv4_server_start(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_if *iface = NULL; + struct in_addr base_addr; + int idx, ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_addr_pton(AF_INET, argv[2], &base_addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + ret = net_dhcpv4_server_start(iface, &base_addr); + if (ret == -EALREADY) { + PR_WARNING("DHCPv4 server already running on interface %d\n", idx); + } else if (ret < 0) { + PR_ERROR("DHCPv4 server failed to start on interface %d, error %d\n", + idx, -ret); + } else { + PR("DHCPv4 server started on interface %d\n", idx); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +static int cmd_net_dhcpv4_server_stop(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_if *iface = NULL; + int idx, ret; + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + ret = net_dhcpv4_server_stop(iface); + if (ret == -ENOENT) { + PR_WARNING("DHCPv4 server is not running on interface %d\n", idx); + } else if (ret < 0) { + PR_ERROR("DHCPv4 server failed to stop on interface %d, error %d\n", + idx, -ret); + } else { + PR("DHCPv4 server stopped on interface %d\n", idx); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +#if defined(CONFIG_NET_DHCPV4_SERVER) +static const char *dhcpv4_addr_state_to_str(enum dhcpv4_server_addr_state state) +{ + switch (state) { + case DHCPV4_SERVER_ADDR_FREE: + return "FREE"; + case DHCPV4_SERVER_ADDR_RESERVED: + return "RESERVED"; + case DHCPV4_SERVER_ADDR_ALLOCATED: + return "ALLOCATED"; + case DHCPV4_SERVER_ADDR_DECLINED: + return "DECLINED"; + } + + return ""; +} + +static uint32_t timepoint_to_s(k_timepoint_t timepoint) +{ + k_timeout_t timeout = sys_timepoint_timeout(timepoint); + + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + return 0; + } + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + return UINT32_MAX; + } + + return k_ticks_to_ms_floor64(timeout.ticks) / 1000; +} + +static void dhcpv4_lease_cb(struct net_if *iface, + struct dhcpv4_addr_slot *lease, + void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char expiry_str[] = "4294967295"; /* Lease time is uint32_t, so take + * theoretical max. + */ + char iface_name[IFNAMSIZ] = ""; + + if (*count == 0) { + PR(" Iface Address\t State\tExpiry (sec)\n"); + } + + (*count)++; + + (void)net_if_get_name(iface, iface_name, sizeof(iface_name)); + + if (lease->state == DHCPV4_SERVER_ADDR_DECLINED) { + snprintk(expiry_str, sizeof(expiry_str) - 1, "infinite"); + } else { + snprintk(expiry_str, sizeof(expiry_str) - 1, "%u", + timepoint_to_s(lease->expiry)); + } + + PR("%2d. %6s %15s\t%9s\t%12s\n", + *count, iface_name, net_sprint_ipv4_addr(&lease->addr), + dhcpv4_addr_state_to_str(lease->state), expiry_str); +} +#endif /* CONFIG_NET_DHCPV4_SERVER */ + +static int cmd_net_dhcpv4_server_status(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_shell_user_data user_data; + struct net_if *iface = NULL; + int idx = 0, ret; + int count = 0; + + if (argc > 1) { + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + } + + user_data.sh = sh; + user_data.user_data = &count; + + ret = net_dhcpv4_server_foreach_lease(iface, dhcpv4_lease_cb, &user_data); + if (ret == -ENOENT) { + PR_WARNING("DHCPv4 server is not running on interface %d\n", idx); + } else if (count == 0) { + PR("DHCPv4 server - no addresses assigned\n"); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dhcpv4_server, + SHELL_CMD_ARG(start, NULL, "Start the DHCPv4 server operation on the interface.\n" + "'net dhcpv4 server start '\n" + " is the network interface index.\n" + " is the first address for the address pool.", + cmd_net_dhcpv4_server_start, 3, 0), + SHELL_CMD_ARG(stop, NULL, "Stop the DHCPv4 server operation on the interface.\n" + "'net dhcpv4 server stop '\n" + " is the network interface index.", + cmd_net_dhcpv4_server_stop, 2, 0), + SHELL_CMD_ARG(status, NULL, "Print the DHCPv4 server status on the interface.\n" + "'net dhcpv4 server status '\n" + " is the network interface index. Optional.", + cmd_net_dhcpv4_server_status, 1, 1), + SHELL_SUBCMD_SET_END +); + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dhcpv4, + SHELL_CMD(server, &net_cmd_dhcpv4_server, + "DHCPv4 server service management.", + NULL), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), dhcpv4, &net_cmd_dhcpv4, "Manage DHPCv4 services.", + NULL, 1, 0); diff --git a/subsys/net/lib/shell/dns.c b/subsys/net/lib/shell/dns.c index 24a52f5e8a26..54c768cecd1c 100644 --- a/subsys/net/lib/shell/dns.c +++ b/subsys/net/lib/shell/dns.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_DNS_RESOLVER) static void dns_result_cb(enum dns_resolve_status status, diff --git a/subsys/net/lib/shell/events.c b/subsys/net/lib/shell/events.c index 047fd1e21863..5a5d0f38f7dc 100644 --- a/subsys/net/lib/shell/events.c +++ b/subsys/net/lib/shell/events.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(net_shell); #include #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_MGMT_EVENT_MONITOR) #define EVENT_MON_STACK_SIZE 1024 diff --git a/subsys/net/lib/shell/gptp.c b/subsys/net/lib/shell/gptp.c index a156637e3af7..0de653e26cd1 100644 --- a/subsys/net/lib/shell/gptp.c +++ b/subsys/net/lib/shell/gptp.c @@ -19,7 +19,7 @@ LOG_MODULE_DECLARE(net_shell); #include "ethernet/gptp/gptp_private.h" #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_GPTP) static const char *selected_role_str(int port); diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index 89983bd4839c..53d4e99bd219 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_NATIVE) struct ethernet_capabilities { diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index 8fc88168c9a6..e8584b205fbf 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/ipv4.h" #if defined(CONFIG_NET_NATIVE_IPV4) diff --git a/subsys/net/lib/shell/ipv6.c b/subsys/net/lib/shell/ipv6.c index f81b8dcae23e..04efda65d0f8 100644 --- a/subsys/net/lib/shell/ipv6.c +++ b/subsys/net/lib/shell/ipv6.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include "../ip/ipv6.h" #if defined(CONFIG_NET_IPV6_FRAGMENT) diff --git a/subsys/net/lib/shell/mem.c b/subsys/net/lib/shell/mem.c index cf58cda6bd67..47058f927674 100644 --- a/subsys/net/lib/shell/mem.c +++ b/subsys/net/lib/shell/mem.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" struct ctx_info { int pos; diff --git a/subsys/net/lib/shell/nbr.c b/subsys/net/lib/shell/nbr.c index fd420b818aec..63b624067020 100644 --- a/subsys/net/lib/shell/nbr.c +++ b/subsys/net/lib/shell/nbr.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/net_shell.c b/subsys/net/lib/shell/net_shell.c index 19bab12e0290..9f932cb1bc46 100644 --- a/subsys/net/lib/shell/net_shell.c +++ b/subsys/net/lib/shell/net_shell.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG); #include -#include "common.h" +#include "net_shell_private.h" #include "net_shell.h" int get_iface_idx(const struct shell *sh, char *index_str) diff --git a/subsys/net/lib/shell/common.h b/subsys/net/lib/shell/net_shell_private.h similarity index 100% rename from subsys/net/lib/shell/common.h rename to subsys/net/lib/shell/net_shell_private.h diff --git a/subsys/net/lib/shell/ping.c b/subsys/net/lib/shell/ping.c index 8b52df110be8..833c6eb8d540 100644 --- a/subsys/net/lib/shell/ping.c +++ b/subsys/net/lib/shell/ping.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(net_shell); #include #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/icmpv6.h" #include "../ip/icmpv4.h" diff --git a/subsys/net/lib/shell/pkt.c b/subsys/net/lib/shell/pkt.c index 09d7ae6738ad..3306b05d1a79 100644 --- a/subsys/net/lib/shell/pkt.c +++ b/subsys/net/lib/shell/pkt.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static bool is_pkt_part_of_slab(const struct k_mem_slab *slab, const char *ptr) { diff --git a/subsys/net/lib/shell/ppp.c b/subsys/net/lib/shell/ppp.c index 9b5f8355d473..f63c6ca33241 100644 --- a/subsys/net/lib/shell/ppp.c +++ b/subsys/net/lib/shell/ppp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_PPP) #include diff --git a/subsys/net/lib/shell/resume.c b/subsys/net/lib/shell/resume.c index 585d421efabf..dcd3fbf309d6 100644 --- a/subsys/net/lib/shell/resume.c +++ b/subsys/net/lib/shell/resume.c @@ -9,7 +9,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_resume(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/route.c b/subsys/net/lib/shell/route.c index d48c442ed415..035b56f6dfcd 100644 --- a/subsys/net/lib/shell/route.c +++ b/subsys/net/lib/shell/route.c @@ -8,7 +8,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include "../ip/route.h" diff --git a/subsys/net/lib/shell/sockets.c b/subsys/net/lib/shell/sockets.c index 792e34efc21d..8be67fc5faf0 100644 --- a/subsys/net/lib/shell/sockets.c +++ b/subsys/net/lib/shell/sockets.c @@ -7,7 +7,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" #include #if defined(CONFIG_NET_SOCKETS_OBJ_CORE) diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c index 455f5d7decde..666a98e35d70 100644 --- a/subsys/net/lib/shell/stats.c +++ b/subsys/net/lib/shell/stats.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #include "../ip/net_stats.h" diff --git a/subsys/net/lib/shell/suspend.c b/subsys/net/lib/shell/suspend.c index 326eb602077f..cfa01375cacb 100644 --- a/subsys/net/lib/shell/suspend.c +++ b/subsys/net/lib/shell/suspend.c @@ -9,7 +9,7 @@ #include LOG_MODULE_DECLARE(net_shell); -#include "common.h" +#include "net_shell_private.h" static int cmd_net_suspend(const struct shell *sh, size_t argc, char *argv[]) { diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index f90e16b3b66a..e2839af36ba3 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) static struct net_context *tcp_ctx; diff --git a/subsys/net/lib/shell/udp.c b/subsys/net/lib/shell/udp.c index 9eaf32545143..7bccbf93ba3a 100644 --- a/subsys/net/lib/shell/udp.c +++ b/subsys/net/lib/shell/udp.c @@ -10,7 +10,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_NATIVE_UDP) static struct net_context *udp_ctx; diff --git a/subsys/net/lib/shell/virtual.c b/subsys/net/lib/shell/virtual.c index 19c9b1c1b0e1..4eaabaa99163 100644 --- a/subsys/net/lib/shell/virtual.c +++ b/subsys/net/lib/shell/virtual.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_L2_VIRTUAL) static void virtual_iface_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c index 0a980caa11fa..ea7103ef1c95 100644 --- a/subsys/net/lib/shell/vlan.c +++ b/subsys/net/lib/shell/vlan.c @@ -15,7 +15,7 @@ LOG_MODULE_DECLARE(net_shell); #include -#include "common.h" +#include "net_shell_private.h" #if defined(CONFIG_NET_VLAN) static void iface_vlan_del_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/lib/shell/websocket.c b/subsys/net/lib/shell/websocket.c index f3e77187627c..56e705199e34 100644 --- a/subsys/net/lib/shell/websocket.c +++ b/subsys/net/lib/shell/websocket.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(net_shell); #include #endif -#include "common.h" +#include "net_shell_private.h" #include "websocket/websocket_internal.h" diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 7ffd6dc476b9..253cb4a182f8 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c) zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER socket_dispatcher.c) zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_OBJ_CORE socket_obj_core.c) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_SERVICE sockets_service.c) if(CONFIG_NET_SOCKETS_NET_MGMT) zephyr_library_sources(sockets_net_mgmt.c) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index b2da30c1e487..35750dd35837 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -73,6 +73,32 @@ config NET_SOCKET_MAX_SEND_WAIT The maximum time a socket is waiting for a blocked connection before returning an ENOBUFS error. +config NET_SOCKETS_SERVICE + bool "Socket service support [EXPERIMENTAL]" + select EXPERIMENTAL + select EVENTFD + help + The socket service can monitor multiple sockets and save memory + by only having one thread listening socket data. If data is received + in the monitored socket, a user supplied work is called. + Note that you need to set CONFIG_NET_SOCKETS_POLL_MAX high enough + so that enough sockets entries can be serviced. This depends on + system needs as multiple services can be activated at the same time + depending on network configuration. + +config NET_SOCKETS_SERVICE_STACK_SIZE + int "Stack size for the thread handling socket services" + default 2400 if NET_DHCPV4_SERVER + default 1200 + depends on NET_SOCKETS_SERVICE + help + Set the internal stack size for the thread that polls sockets. + +config NET_SOCKETS_SERVICE_INIT_PRIO + int "Startup priority for the network socket service" + default 95 + depends on NET_SOCKETS_SERVICE + config NET_SOCKETS_SOCKOPT_TLS bool "TCP TLS socket option support [EXPERIMENTAL]" imply TLS_CREDENTIALS diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index d35317352c97..060c7fff8f74 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -681,7 +681,9 @@ int z_impl_zsock_accept(int sock, struct sockaddr *addr, socklen_t *addrlen) new_sock = VTABLE_CALL(accept, sock, addr, addrlen); - (void)sock_obj_core_alloc_find(sock, new_sock, addr->sa_family, SOCK_STREAM); + if (addr) { + (void)sock_obj_core_alloc_find(sock, new_sock, addr->sa_family, SOCK_STREAM); + } return new_sock; } diff --git a/subsys/net/lib/sockets/sockets_service.c b/subsys/net/lib/sockets/sockets_service.c new file mode 100644 index 000000000000..d253ece629c5 --- /dev/null +++ b/subsys/net/lib/sockets/sockets_service.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_sock_svc, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include +#include +#include + +static int init_socket_service(void); +static bool init_done; + +static K_MUTEX_DEFINE(lock); +static K_CONDVAR_DEFINE(wait_start); + +STRUCT_SECTION_START_EXTERN(net_socket_service_desc); +STRUCT_SECTION_END_EXTERN(net_socket_service_desc); + +static struct service { + /* The +1 is for triggering events from register function */ + struct zsock_pollfd events[1 + CONFIG_NET_SOCKETS_POLL_MAX]; + int count; +} ctx; + +#define get_idx(svc) (*(svc->idx)) + +void net_socket_service_foreach(net_socket_service_cb_t cb, void *user_data) +{ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + cb(svc, user_data); + } +} + +static void cleanup_svc_events(const struct net_socket_service_desc *svc) +{ + for (int i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i].fd = -1; + svc->pev[i].event.fd = -1; + svc->pev[i].event.events = 0; + } +} + +int z_impl_net_socket_service_register(const struct net_socket_service_desc *svc, + struct zsock_pollfd *fds, int len, + void *user_data) +{ + int i, ret = -ENOENT; + + k_mutex_lock(&lock, K_FOREVER); + + if (!init_done) { + (void)k_condvar_wait(&wait_start, &lock, K_FOREVER); + } + + if (STRUCT_SECTION_START(net_socket_service_desc) > svc || + STRUCT_SECTION_END(net_socket_service_desc) <= svc) { + goto out; + } + + if (fds == NULL) { + cleanup_svc_events(svc); + } else { + if (len > svc->pev_len) { + NET_DBG("Too many file descriptors, " + "max is %d for service %p", + svc->pev_len, svc); + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < len; i++) { + svc->pev[i].event = fds[i]; + svc->pev[i].user_data = user_data; + } + + for (i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i] = svc->pev[i].event; + } + } + + /* Tell the thread to re-read the variables */ + eventfd_write(ctx.events[0].fd, 1); + ret = 0; + +out: + k_mutex_unlock(&lock); + + return ret; +} + +static struct net_socket_service_desc *find_svc_and_event( + struct zsock_pollfd *pev, + struct net_socket_service_event **event) +{ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + for (int i = 0; i < svc->pev_len; i++) { + if (svc->pev[i].event.fd == pev->fd) { + *event = &svc->pev[i]; + return svc; + } + } + } + + return NULL; +} + +/* We do not set the user callback to our work struct because we need to + * hook into the flow and restore the global poll array so that the next poll + * round will not notice it and call the callback again while we are + * servicing the callback. + */ +void net_socket_service_callback(struct k_work *work) +{ + struct net_socket_service_event *pev = + CONTAINER_OF(work, struct net_socket_service_event, work); + struct net_socket_service_desc *svc = pev->svc; + struct net_socket_service_event ev = *pev; + + ev.callback(&ev.work); + + /* Copy back the socket fd to the global array because we marked + * it as -1 when triggering the work. + */ + for (int i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i] = svc->pev[i].event; + } +} + +static int call_work(struct zsock_pollfd *pev, struct k_work_q *work_q, + struct k_work *work) +{ + int ret = 0; + + /* Mark the global fd non pollable so that we do not + * call the callback second time. + */ + pev->fd = -1; + + if (work->handler == NULL) { + /* Synchronous call */ + net_socket_service_callback(work); + } else { + if (work_q != NULL) { + ret = k_work_submit_to_queue(work_q, work); + } else { + ret = k_work_submit(work); + } + + k_yield(); + } + + return ret; + +} + +static int trigger_work(struct zsock_pollfd *pev) +{ + struct net_socket_service_event *event; + struct net_socket_service_desc *svc; + + svc = find_svc_and_event(pev, &event); + if (svc == NULL) { + return -ENOENT; + } + + event->svc = svc; + + /* Copy the triggered event to our event so that we know what + * was actually causing the event. + */ + event->event = *pev; + + return call_work(pev, svc->work_q, &event->work); +} + +static void socket_service_thread(void) +{ + int ret, i, fd, count = 0; + eventfd_t value; + + STRUCT_SECTION_COUNT(net_socket_service_desc, &ret); + if (ret == 0) { + NET_INFO("No socket services found, service disabled."); + goto fail; + } + + /* Create contiguous poll event array to enable socket polling */ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + get_idx(svc) = count + 1; + count += svc->pev_len; + } + + if ((count + 1) > ARRAY_SIZE(ctx.events)) { + NET_WARN("You have %d services to monitor but " + "%d poll entries configured.", + count + 1, ARRAY_SIZE(ctx.events)); + NET_WARN("Consider increasing value of %s to %d", + "CONFIG_NET_SOCKETS_POLL_MAX", count + 1); + } + + NET_DBG("Monitoring %d socket entries", count); + + ctx.count = count + 1; + + /* Create an eventfd that can be used to trigger events during polling */ + fd = eventfd(0, 0); + if (fd < 0) { + fd = -errno; + NET_ERR("eventfd failed (%d)", fd); + goto out; + } + + init_done = true; + k_condvar_broadcast(&wait_start); + + ctx.events[0].fd = fd; + ctx.events[0].events = ZSOCK_POLLIN; + +restart: + i = 1; + + k_mutex_lock(&lock, K_FOREVER); + + /* Copy individual events to the big array */ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + for (int j = 0; j < svc->pev_len; j++) { + ctx.events[get_idx(svc) + j] = svc->pev[j].event; + } + } + + k_mutex_unlock(&lock); + + while (true) { + ret = zsock_poll(ctx.events, count + 1, -1); + if (ret < 0) { + ret = -errno; + NET_ERR("poll failed (%d)", ret); + goto out; + } + + if (ret == 0) { + /* should not happen because timeout is -1 */ + break; + } + + if (ret > 0 && ctx.events[0].revents) { + eventfd_read(ctx.events[0].fd, &value); + NET_DBG("Received restart event."); + goto restart; + } + + for (i = 1; i < (count + 1); i++) { + if (ctx.events[i].fd < 0) { + continue; + } + + if (ctx.events[i].revents > 0) { + ret = trigger_work(&ctx.events[i]); + if (ret < 0) { + NET_DBG("Triggering work failed (%d)", ret); + } + } + } + } + +out: + NET_DBG("Socket service thread stopped"); + init_done = false; + + return; + +fail: + k_condvar_broadcast(&wait_start); +} + +K_THREAD_DEFINE(socket_service_monitor, CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE, + socket_service_thread, NULL, NULL, NULL, + K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0); + +static int init_socket_service(void) +{ + k_thread_name_set(socket_service_monitor, "net_socket_service"); + + return 0; +} + +SYS_INIT(init_socket_service, APPLICATION, CONFIG_NET_SOCKETS_SERVICE_INIT_PRIO); diff --git a/subsys/net/lib/tls_credentials/CMakeLists.txt b/subsys/net/lib/tls_credentials/CMakeLists.txt index 490a558953d9..5a80bed58a68 100644 --- a/subsys/net/lib/tls_credentials/CMakeLists.txt +++ b/subsys/net/lib/tls_credentials/CMakeLists.txt @@ -15,3 +15,9 @@ zephyr_library_sources_ifdef(CONFIG_TLS_CREDENTIALS_SHELL ) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) + +if (CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE AND CONFIG_BUILD_WITH_TFM) + target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE + $/api_ns/interface/include + ) +endif() diff --git a/subsys/net/lib/trickle/CMakeLists.txt b/subsys/net/lib/trickle/CMakeLists.txt new file mode 100644 index 000000000000..b9cf222aab5e --- /dev/null +++ b/subsys/net/lib/trickle/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + trickle.c + ) diff --git a/subsys/net/lib/trickle/Kconfig b/subsys/net/lib/trickle/Kconfig new file mode 100644 index 000000000000..edc4f8fcf569 --- /dev/null +++ b/subsys/net/lib/trickle/Kconfig @@ -0,0 +1,18 @@ +# Trickle Library for Zephyr + +# Copyright (c) 2016 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config NET_TRICKLE + bool "Trickle library" + help + Normally this is enabled automatically if needed, + so say 'n' if unsure. + +if NET_TRICKLE +module = NET_TRICKLE +module-dep = NET_LOG +module-str = Log level for Trickle algorithm +module-help = Enables Trickle library output debug messages +source "subsys/net/Kconfig.template.log_config.net" +endif # NET_TRICKLE diff --git a/subsys/net/ip/trickle.c b/subsys/net/lib/trickle/trickle.c similarity index 100% rename from subsys/net/ip/trickle.c rename to subsys/net/lib/trickle/trickle.c diff --git a/subsys/shell/shell_help.c b/subsys/shell/shell_help.c index 53bf00953c19..235e21110322 100644 --- a/subsys/shell/shell_help.c +++ b/subsys/shell/shell_help.c @@ -139,7 +139,7 @@ static void help_item_print(const struct shell *sh, const char *item_name, z_cursor_next_line_move(sh); return; } else { - z_shell_fprintf(sh, SHELL_NORMAL, "%s:", tabulator); + z_shell_fprintf(sh, SHELL_NORMAL, "%s: ", tabulator); } /* print option help */ formatted_text_print(sh, item_help, offset, false); diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index 7d7930661099..61679107103e 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -16,66 +16,25 @@ */ #define _ISR_OFFSET 0 -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) -/* The customized solution for nRF51X-based and nRF52X-based - * platforms requires that the POWER_CLOCK_IRQn line equals 0. - */ -BUILD_ASSERT(POWER_CLOCK_IRQn == 0, - "POWER_CLOCK_IRQn != 0. Consider rework manual vector table."); - -/* The customized solution for nRF51X-based and nRF52X-based - * platforms requires that the RTC1 IRQ line equals 17. - */ -BUILD_ASSERT(RTC1_IRQn == 17, - "RTC1_IRQn != 17. Consider rework manual vector table."); - +#if defined(CONFIG_SOC_FAMILY_NRF) #undef _ISR_OFFSET -#if !defined(CONFIG_BOARD_QEMU_CORTEX_M0) -/* Interrupt line 0 is used by POWER_CLOCK */ -#define _ISR_OFFSET 1 +#if defined(CONFIG_BOARD_QEMU_CORTEX_M0) +/* For the nRF51-based QEMU Cortex-M0 platform, the first set of consecutive + * implemented interrupts that can be used by this test starts right after + * the TIMER0 IRQ line, which is used by the system timer. + */ +#define _ISR_OFFSET (TIMER0_IRQn + 1) +#elif defined(CONFIG_SOC_SERIES_NRF54LX) +/* For nRF54L Series, use SWI00-02 interrupt lines. */ +#define _ISR_OFFSET SWI00_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +/* For nRF54H Series, use BELLBOARD_0-2 interrupt lines. */ +#define _ISR_OFFSET BELLBOARD_0_IRQn #else -/* The customized solution for nRF51-based QEMU Cortex-M0 platform - * requires that the TIMER0 IRQ line equals 8. - */ -BUILD_ASSERT(TIMER0_IRQn == 8, - "TIMER0_IRQn != 8. Consider rework manual vector table."); -/* Interrupt lines 9-11 is the first set of consecutive interrupts implemented - * in QEMU Cortex M0. - */ -#define _ISR_OFFSET 9 - +/* For other nRF targets, use TIMER0-2 interrupt lines. */ +#define _ISR_OFFSET TIMER0_IRQn #endif - -#elif defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF91X) -/* The customized solution for nRF91X-based and nRF53X-based - * platforms requires that the POWER_CLOCK_IRQn line equals 5. - */ -BUILD_ASSERT(CLOCK_POWER_IRQn == 5, - "POWER_CLOCK_IRQn != 5." - "Consider rework manual vector table."); - -#if !defined(CONFIG_SOC_NRF5340_CPUNET) -/* The customized solution for nRF91X-based platforms - * requires that the RTC1 IRQ line equals 21. - */ -BUILD_ASSERT(RTC1_IRQn == 21, - "RTC1_IRQn != 21. Consider rework manual vector table."); - -#else /* CONFIG_SOC_NRF5340_CPUNET */ -/* The customized solution for nRF5340_CPUNET - * requires that the RTC1 IRQ line equals 22. - */ -BUILD_ASSERT(RTC1_IRQn == 22, - "RTC1_IRQn != 22. Consider rework manual vector table."); -#endif -#undef _ISR_OFFSET -/* Interrupt lines 8-10 is the first set of consecutive interrupts implemented - * in nRF9160 SOC. - */ -#define _ISR_OFFSET 8 - -#endif /* CONFIG_SOC_SERIES_NRF52X */ - +#endif /* CONFIG_SOC_FAMILY_NRF */ struct k_sem sem[3]; @@ -182,40 +141,38 @@ typedef void (*vth)(void); /* Vector Table Handler */ * * Note: qemu_cortex_m0 uses TIMER0 to implement system timer. */ -void rtc_nrf_isr(void); void nrfx_power_clock_irq_handler(void); #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#define POWER_CLOCK_IRQ_NUM POWER_CLOCK_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#define POWER_CLOCK_IRQ_NUM -1 /* not needed */ +#else +#define POWER_CLOCK_IRQ_NUM CLOCK_POWER_IRQn +#endif + #if defined(CONFIG_BOARD_QEMU_CORTEX_M0) void timer0_nrf_isr(void); -vth __irq_vector_table _irq_vector_table[] = { - nrfx_power_clock_irq_handler, 0, 0, 0, 0, 0, 0, 0, - timer0_nrf_isr, isr0, isr1, isr2 -}; +#define TIMER_IRQ_HANDLER timer0_nrf_isr +#define TIMER_IRQ_NUM TIMER0_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) +void nrfx_grtc_irq_handler(void); +#define TIMER_IRQ_HANDLER nrfx_grtc_irq_handler +#define TIMER_IRQ_NUM GRTC_0_IRQn #else -vth __irq_vector_table _irq_vector_table[] = { - nrfx_power_clock_irq_handler, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; -#endif /* CONFIG_BOARD_QEMU_CORTEX_M0 */ -#elif defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF91X) -#ifndef CONFIG_SOC_NRF5340_CPUNET -vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrfx_power_clock_irq_handler, 0, 0, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; -#else -vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrfx_power_clock_irq_handler, 0, 0, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; +void rtc_nrf_isr(void); +#define TIMER_IRQ_HANDLER rtc_nrf_isr +#define TIMER_IRQ_NUM RTC1_IRQn #endif + +#define IRQ_VECTOR_TABLE_SIZE (MAX(POWER_CLOCK_IRQ_NUM, MAX(TIMER_IRQ_NUM, _ISR_OFFSET + 2)) + 1) + +vth __irq_vector_table _irq_vector_table[IRQ_VECTOR_TABLE_SIZE] = { +#if (POWER_CLOCK_IRQ_NUM != -1) + [POWER_CLOCK_IRQ_NUM] = nrfx_power_clock_irq_handler, #endif + [TIMER_IRQ_NUM] = TIMER_IRQ_HANDLER, + [_ISR_OFFSET] = isr0, isr1, isr2, +}; #elif defined(CONFIG_SOC_SERIES_CC13X2_CC26X2) || defined(CONFIG_SOC_SERIES_CC13X2X7_CC26X2X7) /* TI CC13x2/CC26x2 based platforms also employ a Hardware RTC peripheral * to implement the Kernel system timer, instead of the ARM Cortex-M diff --git a/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt b/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt index 93e91deafcbe..10ee1786e16a 100644 --- a/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt +++ b/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt @@ -14,6 +14,6 @@ target_sources(app PRIVATE ${app_sources}) if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index 4b46c8d6781f..ef4eed67eb3f 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -13,6 +13,13 @@ tests: tags: bluetooth harness: keyboard min_flash: 145 + bluetooth.shell.power_control_request: + extra_configs: + - CONFIG_BT_TRANSMIT_POWER_CONTROL=y + - CONFIG_BT_CTLR=n + platform_allow: + - native_posix + build_only: true bluetooth.shell.cdc_acm: extra_args: - OVERLAY_CONFIG=cdc_acm.conf diff --git a/tests/boot/mcuboot_recovery_retention/sysbuild.conf b/tests/boot/mcuboot_recovery_retention/sysbuild.conf index 47f00ff3cff8..3b5b3c963800 100644 --- a/tests/boot/mcuboot_recovery_retention/sysbuild.conf +++ b/tests/boot/mcuboot_recovery_retention/sysbuild.conf @@ -1 +1,2 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_PARTITION_MANAGER=n diff --git a/tests/boot/test_mcuboot/sysbuild.conf b/tests/boot/test_mcuboot/sysbuild.conf index 47f00ff3cff8..3b5b3c963800 100644 --- a/tests/boot/test_mcuboot/sysbuild.conf +++ b/tests/boot/test_mcuboot/sysbuild.conf @@ -1 +1,2 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_PARTITION_MANAGER=n diff --git a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake index a922830546d3..2bf2920a4766 100644 --- a/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake +++ b/tests/bsim/bluetooth/audio_samples/broadcast_audio_sink/sysbuild.cmake @@ -3,11 +3,4 @@ include(${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/sysbuild.cmake) -if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) -endif() +native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) diff --git a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake index 9686cde1bce6..85b85b7cb635 100644 --- a/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake +++ b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/sysbuild.cmake @@ -3,11 +3,4 @@ include(${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/sysbuild.cmake) -if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) -endif() +native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) diff --git a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh index 4f175540347d..65769185867f 100755 --- a/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh +++ b/tests/bsim/bluetooth/compile.nrf5340bsim_nrf5340_cpuapp.sh @@ -21,6 +21,7 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile app=tests/bsim/bluetooth/ll/bis sysbuild=1 compile +app=tests/bsim/bluetooth/ll/cis conf_overlay=overlay-acl_group.conf sysbuild=1 compile run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index ff42fd27adf9..098c983d75f6 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -41,6 +41,7 @@ app=tests/bsim/bluetooth/host/att/sequential/dut compile app=tests/bsim/bluetooth/host/att/sequential/tester compile app=tests/bsim/bluetooth/host/att/long_read compile +app=tests/bsim/bluetooth/host/gatt/authorization compile app=tests/bsim/bluetooth/host/gatt/caching compile app=tests/bsim/bluetooth/host/gatt/general compile app=tests/bsim/bluetooth/host/gatt/notify compile diff --git a/tests/bsim/bluetooth/host/gatt/authorization/CMakeLists.txt b/tests/bsim/bluetooth/host/gatt/authorization/CMakeLists.txt new file mode 100644 index 000000000000..acb0dd45947b --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/CMakeLists.txt @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(bsim_test_gatt_authorization) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources} ) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/host/gatt/authorization/prj.conf b/tests/bsim/bluetooth/host/gatt/authorization/prj.conf new file mode 100644 index 000000000000..9cba554afef6 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/prj.conf @@ -0,0 +1,7 @@ +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME="GATT tester" +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_AUTHORIZATION_CUSTOM=y +CONFIG_BT_ATT_PREPARE_COUNT=3 diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/common.c b/tests/bsim/bluetooth/host/gatt/authorization/src/common.c new file mode 100644 index 000000000000..adff2dd05ef6 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/common.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + FAIL("test failed (not passed after %i seconds)\n", WAIT_TIME); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(WAIT_TIME); + bst_result = In_progress; +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/common.h b/tests/bsim/bluetooth/host/gatt/authorization/src/common.h new file mode 100644 index 000000000000..339919dfe884 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/common.h @@ -0,0 +1,73 @@ +/** + * Common functions and helpers for BSIM GATT tests + * + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "bs_types.h" +#include "bs_tracing.h" +#include "time_machine.h" +#include "bstests.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +extern enum bst_result_t bst_result; + +#define WAIT_TIME (30 * 1e6) /*seconds*/ + +#define CREATE_FLAG(flag) static atomic_t flag = (atomic_t)false +#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t)true) +#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t)false) +#define WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#define FAIL(...) \ + do { \ + bst_result = Failed; \ + bs_trace_error_time_line(__VA_ARGS__); \ + } while (0) + +#define PASS(...) \ + do { \ + bst_result = Passed; \ + bs_trace_info_time(1, __VA_ARGS__); \ + } while (0) + +#define CHRC_SIZE 10 + +#define TEST_SERVICE_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00) + +#define TEST_UNHANDLED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFD, 0x00) + +#define TEST_UNAUTHORIZED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFE, 0x00) + +#define TEST_AUTHORIZED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0x00) + +#define TEST_CP_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xF0, 0x00) + +void test_tick(bs_time_t HW_device_time); +void test_init(void); diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c new file mode 100644 index 000000000000..9c60c5b57b2d --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "common.h" + +CREATE_FLAG(flag_is_connected); +CREATE_FLAG(flag_discover_complete); +CREATE_FLAG(flag_write_complete); +CREATE_FLAG(flag_read_complete); + +static struct bt_conn *g_conn; +static uint16_t unhandled_chrc_handle; +static uint16_t unauthorized_chrc_handle; +static uint16_t authorized_chrc_handle; +static uint16_t cp_chrc_handle; +static const struct bt_uuid *test_svc_uuid = TEST_SERVICE_UUID; + +#define ARRAY_ITEM(i, _) i +static uint8_t chrc_data[] = { LISTIFY(CHRC_SIZE, ARRAY_ITEM, (,)) }; /* 1, 2, 3 ... */ + +static void connected(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err != 0) { + FAIL("Failed to connect to %s (%u)\n", addr, err); + return; + } + + printk("Connected to %s\n", addr); + + __ASSERT_NO_MSG(g_conn == conn); + + SET_FLAG(flag_is_connected); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != g_conn) { + return; + } + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Disconnected: %s (reason 0x%02x)\n", addr, reason); + + bt_conn_unref(g_conn); + + g_conn = NULL; + UNSET_FLAG(flag_is_connected); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + int err; + + if (g_conn != NULL) { + return; + } + + /* We're only interested in connectable events */ + if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) { + return; + } + + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, rssi); + + printk("Stopping scan\n"); + err = bt_le_scan_stop(); + if (err != 0) { + FAIL("Could not stop scan: %d"); + return; + } + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &g_conn); + if (err != 0) { + FAIL("Could not connect to peer: %d", err); + } +} + +static uint8_t discover_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + int err; + + if (attr == NULL) { + if (unhandled_chrc_handle == 0 || + unauthorized_chrc_handle == 0 || + authorized_chrc_handle == 0) { + FAIL("Did not discover required characterstics"); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_discover_complete); + + return BT_GATT_ITER_STOP; + } + + printk("[ATTRIBUTE] handle %u\n", attr->handle); + + if (params->type == BT_GATT_DISCOVER_PRIMARY && + bt_uuid_cmp(params->uuid, TEST_SERVICE_UUID) == 0) { + printk("Found test service\n"); + params->uuid = NULL; + params->start_handle = attr->handle + 1; + params->type = BT_GATT_DISCOVER_CHARACTERISTIC; + + err = bt_gatt_discover(conn, params); + if (err != 0) { + FAIL("Discover failed (err %d)\n", err); + } + + return BT_GATT_ITER_STOP; + } else if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) { + struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + + if (bt_uuid_cmp(chrc->uuid, TEST_UNHANDLED_CHRC_UUID) == 0) { + printk("Found unhandled chrc\n"); + unhandled_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + printk("Found unauthorized\n"); + unauthorized_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + printk("Found authorized chrc\n"); + authorized_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_CP_CHRC_UUID) == 0) { + printk("Found CP chrc\n"); + cp_chrc_handle = chrc->value_handle; + } + } + + return BT_GATT_ITER_CONTINUE; +} + +static void gatt_discover(void) +{ + static struct bt_gatt_discover_params discover_params; + int err; + + printk("Discovering services and characteristics\n"); + + discover_params.uuid = test_svc_uuid; + discover_params.func = discover_func; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_PRIMARY; + + err = bt_gatt_discover(g_conn, &discover_params); + if (err != 0) { + FAIL("Discover failed(err %d)\n", err); + } + + WAIT_FOR_FLAG(flag_discover_complete); + printk("Discover complete\n"); +} + +static void gatt_write_cb(struct bt_conn *conn, uint8_t err, + struct bt_gatt_write_params *params) +{ + if ((err != BT_ATT_ERR_SUCCESS) && (params->handle != unauthorized_chrc_handle)) { + FAIL("Write failed on authorized characteristics: 0x%02X\n", err); + } + + if ((err != BT_ATT_ERR_AUTHORIZATION) && (params->handle == unauthorized_chrc_handle)) { + FAIL("Write failed on unauthorized characteristics: 0x%02X\n", err); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_write_complete); +} + +static void gatt_write(uint16_t handle) +{ + static struct bt_gatt_write_params write_params; + int err; + + printk("Writing to chrc\n"); + + write_params.data = chrc_data; + write_params.length = sizeof(chrc_data); + write_params.func = gatt_write_cb; + write_params.handle = handle; + + UNSET_FLAG(flag_write_complete); + + err = bt_gatt_write(g_conn, &write_params); + if (err != 0) { + FAIL("bt_gatt_write failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_write_complete); + printk("success\n"); +} + +static void gatt_cp_write(void) +{ + static struct bt_gatt_write_params write_params; + int err; + uint8_t cp_write_data[] = {0x00}; + + printk("Writing to CP chrc\n"); + + write_params.data = cp_write_data; + write_params.length = sizeof(cp_write_data); + write_params.func = gatt_write_cb; + write_params.handle = cp_chrc_handle; + + UNSET_FLAG(flag_write_complete); + + err = bt_gatt_write(g_conn, &write_params); + if (err != 0) { + FAIL("bt_gatt_write failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_write_complete); + printk("success\n"); +} + +static uint8_t gatt_read_cb(struct bt_conn *conn, uint8_t err, + struct bt_gatt_read_params *params, + const void *data, uint16_t length) +{ + if ((err != BT_ATT_ERR_SUCCESS) && + (params->single.handle != unauthorized_chrc_handle)) { + FAIL("Read failed on authorized characteristics: 0x%02X\n", err); + + if ((length != CHRC_SIZE) || (memcmp(data, chrc_data, length) != 0)) { + FAIL("chrc data different than expected", err); + } + } + + if ((err != BT_ATT_ERR_AUTHORIZATION) && + (params->single.handle == unauthorized_chrc_handle)) { + FAIL("Read failed on unauthorized characteristics: 0x%02X\n", err); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_read_complete); + + return 0; +} + +static void gatt_read(uint16_t handle) +{ + static struct bt_gatt_read_params read_params; + int err; + + printk("Reading chrc\n"); + + read_params.func = gatt_read_cb; + read_params.handle_count = 1; + read_params.single.handle = handle; + read_params.single.offset = 0; + + UNSET_FLAG(flag_read_complete); + + err = bt_gatt_read(g_conn, &read_params); + if (err != 0) { + FAIL("bt_gatt_read failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_read_complete); + printk("success\n"); +} + +static void gatt_interact(uint16_t handle) +{ + gatt_write(handle); + gatt_read(handle); + gatt_cp_write(); +} + +static void test_main(void) +{ + int err; + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth discover failed (err %d)\n", err); + } + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err != 0) { + FAIL("Scanning failed to start (err %d)\n", err); + } + + printk("Scanning successfully started\n"); + + WAIT_FOR_FLAG(flag_is_connected); + + gatt_discover(); + + printk("Interacting with the unhandled characteristic\n"); + gatt_interact(unhandled_chrc_handle); + + printk("Interacting with the unauthorized characteristic\n"); + gatt_interact(unauthorized_chrc_handle); + + printk("Interacting with the authorized characteristic\n"); + gatt_interact(authorized_chrc_handle); + + PASS("GATT client Passed\n"); +} + +static const struct bst_test_instance test_vcs[] = { + { + .test_id = "gatt_client", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main + }, + BSTEST_END_MARKER +}; + +struct bst_test_list *test_gatt_client_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_vcs); +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c new file mode 100644 index 000000000000..d5dd5e0e0a76 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +extern enum bst_result_t bst_result; + +CREATE_FLAG(flag_is_chrc_ctx_validated); + +static struct bt_conn *g_conn; + +static void connected(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err != 0) { + FAIL("Failed to connect to %s (%u)\n", addr, err); + return; + } + + printk("Connected to %s\n", addr); + + g_conn = bt_conn_ref(conn); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != g_conn) { + return; + } + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Disconnected: %s (reason 0x%02x)\n", addr, reason); + + bt_conn_unref(g_conn); + + g_conn = NULL; +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +struct test_chrc_ctx { + uint16_t auth_read_cnt; + uint16_t read_cnt; + uint16_t auth_write_cnt; + uint16_t write_cnt; + uint8_t data[CHRC_SIZE]; +}; + +static ssize_t read_test_chrc(struct test_chrc_ctx *chrc_ctx, + struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + chrc_ctx->read_cnt++; + + return bt_gatt_attr_read(conn, attr, buf, len, offset, + (void *)chrc_ctx->data, + sizeof(chrc_ctx->data)); +} + +static ssize_t write_test_chrc(struct test_chrc_ctx *chrc_ctx, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + chrc_ctx->write_cnt++; + + if (len != sizeof(chrc_ctx->data)) { + printk("Invalid chrc length\n"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + } + + if (offset != 0) { + printk("Invalid chrc offset and length\n"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + if (flags != 0) { + FAIL("Invalid flags %u\n", flags); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + (void)memcpy(chrc_ctx->data, buf, len); + + return len; +} + +static struct test_chrc_ctx unhandled_chrc_ctx; + +static ssize_t read_test_unhandled_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&unhandled_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_unhandled_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("unhandled chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&unhandled_chrc_ctx, buf, len, offset, flags); +} + +static struct test_chrc_ctx unauthorized_chrc_ctx; + +static ssize_t read_test_unauthorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&unauthorized_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_unauthorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("unauthorized chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&unauthorized_chrc_ctx, buf, len, offset, flags); +} + +static struct test_chrc_ctx authorized_chrc_ctx; + +static ssize_t read_test_authorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&authorized_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_authorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("authorized chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&authorized_chrc_ctx, buf, len, offset, flags); +} + +static const struct test_chrc_ctx zeroed_chrc_ctx; + +static bool unhandled_chrc_operation_validate(void) +{ + if (memcmp(&unauthorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&authorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((unhandled_chrc_ctx.read_cnt != 1) && (unhandled_chrc_ctx.write_cnt != 1)) { + return false; + } + + if ((unhandled_chrc_ctx.auth_read_cnt != 0) && + (unhandled_chrc_ctx.auth_write_cnt != 0)) { + return false; + } + + return true; +} + +static bool unauthorized_chrc_operation_validate(void) +{ + if (memcmp(&unhandled_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&authorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((unauthorized_chrc_ctx.read_cnt != 0) && (unauthorized_chrc_ctx.write_cnt != 0)) { + return false; + } + + if ((unauthorized_chrc_ctx.auth_read_cnt != 1) && + (unauthorized_chrc_ctx.auth_write_cnt != 1)) { + return false; + } + + return true; +} + +static bool authorized_chrc_operation_validate(void) +{ + if (memcmp(&unhandled_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&unauthorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((authorized_chrc_ctx.read_cnt != 1) && (authorized_chrc_ctx.write_cnt != 1)) { + return false; + } + + if ((authorized_chrc_ctx.auth_read_cnt != 1) && + (authorized_chrc_ctx.auth_write_cnt != 1)) { + return false; + } + + return true; +} + +static ssize_t write_cp_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + static uint16_t cp_write_cnt; + bool pass; + char *log_str; + + if (cp_write_cnt == 0) { + pass = unhandled_chrc_operation_validate(); + log_str = "unhandled"; + } else if (cp_write_cnt == 1) { + pass = unauthorized_chrc_operation_validate(); + log_str = "unauthorized"; + } else if (cp_write_cnt == 2) { + pass = authorized_chrc_operation_validate(); + log_str = "authorized"; + } else { + FAIL("Invalid value of CP write counter %u\n", cp_write_cnt); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + if (pass) { + printk("Correct context for %s chrc\n", log_str); + } else { + FAIL("Invalid context for %s chrc\n", log_str); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + memset(&unhandled_chrc_ctx, 0, sizeof(unhandled_chrc_ctx)); + memset(&unauthorized_chrc_ctx, 0, sizeof(unauthorized_chrc_ctx)); + memset(&authorized_chrc_ctx, 0, sizeof(authorized_chrc_ctx)); + + cp_write_cnt++; + + if (cp_write_cnt == 3) { + SET_FLAG(flag_is_chrc_ctx_validated); + } + + return len; +} + +BT_GATT_SERVICE_DEFINE(test_svc, + BT_GATT_PRIMARY_SERVICE(TEST_SERVICE_UUID), + BT_GATT_CHARACTERISTIC(TEST_UNHANDLED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_unhandled_chrc, + write_test_unhandled_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_UNAUTHORIZED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_unauthorized_chrc, + write_test_unauthorized_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_AUTHORIZED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_authorized_chrc, + write_test_authorized_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_CP_CHRC_UUID, + BT_GATT_CHRC_WRITE, + BT_GATT_PERM_WRITE, + NULL, write_cp_chrc, NULL), +); + +static bool gatt_read_operation_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (bt_uuid_cmp(attr->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + unauthorized_chrc_ctx.auth_read_cnt++; + return false; + } else if (bt_uuid_cmp(attr->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + authorized_chrc_ctx.auth_read_cnt++; + return true; + } else { + return true; + } +} + +static bool gatt_write_operation_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (bt_uuid_cmp(attr->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + unauthorized_chrc_ctx.auth_write_cnt++; + return false; + } else if (bt_uuid_cmp(attr->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + authorized_chrc_ctx.auth_write_cnt++; + return true; + } else { + return true; + } +} + +static const struct bt_gatt_authorization_cb gatt_authorization_callbacks = { + .read_operation_authorize = gatt_read_operation_authorize, + .write_operation_authorize = gatt_write_operation_authorize, +}; + +static void test_main(void) +{ + int err; + const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) + }; + + err = bt_gatt_authorization_cb_register(&gatt_authorization_callbacks); + if (err) { + FAIL("Registering GATT authorization callbacks failed (err %d)\n", err); + return; + } + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth init failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); + if (err != 0) { + FAIL("Advertising failed to start (err %d)\n", err); + return; + } + + printk("Advertising successfully started\n"); + + WAIT_FOR_FLAG(flag_is_chrc_ctx_validated); + + PASS("GATT server passed\n"); +} + +static const struct bst_test_instance test_gatt_server[] = { + { + .test_id = "gatt_server", + .test_post_init_f = test_init, + .test_tick_f = test_tick, + .test_main_f = test_main + }, + BSTEST_END_MARKER +}; + +struct bst_test_list *test_gatt_server_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_gatt_server); +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/main.c b/tests/bsim/bluetooth/host/gatt/authorization/src/main.c new file mode 100644 index 000000000000..a95f0285e75a --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/main.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" + +extern struct bst_test_list *test_gatt_server_install(struct bst_test_list *tests); +extern struct bst_test_list *test_gatt_client_install(struct bst_test_list *tests); + +bst_test_install_t test_installers[] = { + test_gatt_server_install, + test_gatt_client_install, + NULL +}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh b/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh new file mode 100755 index 000000000000..edad0eb86c9d --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Copyright 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="gatt_authorization" +verbosity_level=2 +EXECUTE_TIMEOUT=120 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_gatt_authorization_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=gatt_client + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_gatt_authorization_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=gatt_server + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=60e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake index eb75debccd38..69397264edfa 100644 --- a/tests/bsim/bluetooth/ll/bis/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/bis/sysbuild.cmake @@ -16,32 +16,9 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) CACHE INTERNAL "" ) - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - - if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - endif() + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe -add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} -) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild b/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild new file mode 100644 index 000000000000..6c89fddc9f3e --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/Kconfig.sysbuild @@ -0,0 +1,14 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340bsim_nrf5340_cpunet" if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" + +config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX + int + # Let's pass the test arguments to the application MCU test + # otherwise by default they would have gone to the net core. + default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp" diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild.cmake b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake new file mode 100644 index 000000000000..a1258ecf1f2e --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) + 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 + ${APP_DIR}/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) + + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf new file mode 100644 index 000000000000..a3c8f43c71f7 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/sysbuild/hci_ipc/nrf5340_cpunet_iso_acl_group-bt_ll_sw_split.conf @@ -0,0 +1,122 @@ +CONFIG_IPC_SERVICE=y +CONFIG_MBOX=y + +CONFIG_ISR_STACK_SIZE=1024 +CONFIG_IDLE_STACK_SIZE=256 +CONFIG_MAIN_STACK_SIZE=512 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 +CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE=512 +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_CBPRINTF_REDUCED_INTEGRAL=y + +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_RESERVE=1 +CONFIG_BT_MAX_CONN=4 + +# 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 + +CONFIG_BT_BUF_EVT_RX_COUNT=16 + +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 + +# Tx/Rx Thread Stack Sizes +CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y +CONFIG_BT_HCI_TX_STACK_SIZE=1152 +CONFIG_BT_RX_STACK_SIZE=640 +CONFIG_BT_CTLR_RX_PRIO_STACK_SIZE=448 + +# Host features +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV=y +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_PER_ADV_SYNC_MAX=2 + +# Broadcast and Connected ISO +CONFIG_BT_ISO_BROADCASTER=y +CONFIG_BT_ISO_SYNC_RECEIVER=y +CONFIG_BT_ISO_CENTRAL=y +CONFIG_BT_ISO_PERIPHERAL=y + +# ISO Streams +CONFIG_BT_ISO_MAX_CHAN=4 + +# Controller +CONFIG_BT_LL_SW_SPLIT=y +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_CTLR_DTM_HCI=y + +# Rx ACL and Adv Reports +CONFIG_BT_CTLR_RX_BUFFERS=9 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 + +# Coded PHY support +CONFIG_BT_CTLR_PHY_CODED=n + +# Advertising Sets and Extended Scanning +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_SET=3 +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 +CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650 + +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_AUX_SET=3 +CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y +CONFIG_BT_CTLR_ADV_SYNC_SET=3 +CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=6 + +# Increase the below to receive interleaved advertising chains +CONFIG_BT_CTLR_SCAN_AUX_SET=1 + +CONFIG_BT_CTLR_ADV_RESERVE_MAX=n +CONFIG_BT_CTLR_CENTRAL_RESERVE_MAX=n +# CONFIG_BT_CTLR_CENTRAL_SPACING=10000 +CONFIG_BT_CTLR_CENTRAL_SPACING=0 +CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE=n +CONFIG_BT_CTLR_SCAN_UNRESERVED=n +CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH=y +CONFIG_BT_TICKER_EXT=y +CONFIG_BT_TICKER_EXT_SLOT_WINDOW_YIELD=y + +# Control Procedure +CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=9 + +# ISO Broadcaster Controller +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_PERIODIC=y +CONFIG_BT_CTLR_ADV_ISO=y +CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_ADV_ISO_STREAM_MAX=2 + +# ISO Receive Controller +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_SYNC_PERIODIC=y +CONFIG_BT_CTLR_SYNC_ISO=y +CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=2 + +# ISO Connection Oriented +CONFIG_BT_CTLR_CENTRAL_ISO=y +CONFIG_BT_CTLR_PERIPHERAL_ISO=y +CONFIG_BT_CTLR_CONN_ISO_SDU_LEN_MAX=251 +CONFIG_BT_CTLR_CONN_ISO_PDU_LEN_MAX=251 +CONFIG_BT_CTLR_CONN_ISO_STREAMS=4 +CONFIG_BT_CTLR_CONN_ISO_STREAMS_PER_GROUP=4 + +# ISO Transmissions +CONFIG_BT_CTLR_ISO_TX_BUFFERS=18 +CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=251 +CONFIG_BT_CTLR_ISOAL_SOURCES=4 + +# ISO Receptions +CONFIG_BT_CTLR_ISO_RX_BUFFERS=8 +CONFIG_BT_CTLR_ISOAL_SINKS=4 + +# Tx Power Dynamic Control +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake index 2294fd5bb5e4..4dfa34ef5192 100644 --- a/tests/bsim/bluetooth/ll/conn/sysbuild.cmake +++ b/tests/bsim/bluetooth/ll/conn/sysbuild.cmake @@ -11,32 +11,9 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) BOARD ${SB_CONFIG_NET_CORE_BOARD} ) - # For the simulated board, the application core build will produce the final executable - # for that, we give it the path to the netcore image - set(NET_LIBRARY_PATH ${CMAKE_BINARY_DIR}/${NET_APP}/zephyr/zephyr.elf) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS=\"${NET_LIBRARY_PATH}\"\n" - ) - - if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL "")) - set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG - "CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n" - ) - endif() + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) - # Let's build the net core library first - add_dependencies(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) endif() -# Let's meet the expectation of finding the final executable in zephyr/zephyr.exe -add_custom_target(final_executable - ALL - COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/zephyr.exe - ${CMAKE_BINARY_DIR}/zephyr/zephyr.exe - DEPENDS ${DEFAULT_IMAGE} -) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/tests/bsim/bluetooth/mesh/README.rst b/tests/bsim/bluetooth/mesh/README.rst index 787b0084f0b5..1ae78887b719 100644 --- a/tests/bsim/bluetooth/mesh/README.rst +++ b/tests/bsim/bluetooth/mesh/README.rst @@ -1,7 +1,7 @@ -Bluetooth mesh BabbleSim tests +Bluetooth Mesh BabbleSim tests ############################## -This directory contains a set of high level system tests for the Bluetooth mesh +This directory contains a set of high level system tests for the Bluetooth Mesh subsystem. The tests run on the BabbleSim simulator, using the BabbleSim test framework. @@ -10,7 +10,7 @@ subfolder of test_scripts contains tests for a specific module in the Bluetooth mesh subsystem, and each folder has a corresponding test_.c under the src/ directory containing the necessary test harnesses to execute the tests. -There's only a single test application for all the Bluetooth mesh BabbleSim +There's only a single test application for all the Bluetooth Mesh BabbleSim tests. The test application is built from this directory, and includes all test harnesses in every build. The overlying bsim test framework selects the harness to use at runtime, using the test identifiers passed in the test scripts. @@ -18,7 +18,7 @@ to use at runtime, using the test identifiers passed in the test scripts. Running the tests ***************** -The Bluetooth mesh tests have no extra requirements, and can be run using the +The Bluetooth Mesh tests have no extra requirements, and can be run using the procedure described in the parent folder. To only run the mesh tests, set ``SEARCH_PATH`` to point to this folder before @@ -57,13 +57,13 @@ Then separately, call Framework ********* -The Bluetooth mesh BabbleSim tests mainly operate on the test framework for the +The Bluetooth Mesh BabbleSim tests mainly operate on the test framework for the BabbleSim platform, but with some mesh specific additions: mesh_test.sh ============= -All test scripts in the Bluetooth mesh BabbleSim test suite follow a common +All test scripts in the Bluetooth Mesh BabbleSim test suite follow a common pattern for running a single test across N devices with different test harnesses. ``mesh_test.sh`` is sourced in each test script, and its ``RunTest`` function is called once in each script with the following parameters: @@ -113,6 +113,6 @@ has been called - otherwise, it will fail. The Bluetooth stack must be initialized in the ``test_main_f`` function of the harness, as the previous callbacks are all executed in hardware threads. -The Bluetooth mesh tests include the entire Bluetooth host and controller +The Bluetooth Mesh tests include the entire Bluetooth host and controller subsystems, so timing requirements should generally be kept fairly liberal to avoid regressions on changes in the underlying layers. diff --git a/tests/bsim/bluetooth/mesh/overlay_gatt.conf b/tests/bsim/bluetooth/mesh/overlay_gatt.conf index f94a26d623f0..7660313b7006 100644 --- a/tests/bsim/bluetooth/mesh/overlay_gatt.conf +++ b/tests/bsim/bluetooth/mesh/overlay_gatt.conf @@ -6,3 +6,4 @@ CONFIG_BT_MESH_LOW_POWER=n CONFIG_BT_MESH_FRIEND=n CONFIG_BT_CENTRAL=y CONFIG_BT_MESH_PROXY_CLIENT=y +CONFIG_BT_MESH_PROXY_SOLICITATION=y diff --git a/tests/bsim/bluetooth/mesh/overlay_pst.conf b/tests/bsim/bluetooth/mesh/overlay_pst.conf index 6a56ec8065b4..6730b9ee2337 100644 --- a/tests/bsim/bluetooth/mesh/overlay_pst.conf +++ b/tests/bsim/bluetooth/mesh/overlay_pst.conf @@ -19,4 +19,6 @@ CONFIG_BT_MESH_SEQ_STORE_RATE=1 CONFIG_BT_MESH_RPL_STORE_TIMEOUT=1 CONFIG_BT_MESH_STORE_TIMEOUT=1 CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT=1 +CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST=200 +CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT=400 CONFIG_BT_MESH_COMP_PST_BUF_SIZE=600 diff --git a/tests/bsim/bluetooth/mesh/prj.conf b/tests/bsim/bluetooth/mesh/prj.conf index b0738c4fa05c..e9c719de6d73 100644 --- a/tests/bsim/bluetooth/mesh/prj.conf +++ b/tests/bsim/bluetooth/mesh/prj.conf @@ -15,7 +15,7 @@ CONFIG_BT_BROADCASTER=y CONFIG_BT_CTLR_DUP_FILTER_LEN=0 CONFIG_BT_CTLR_PRIVACY=n -# Bluetooth mesh configuration +# Bluetooth Mesh configuration CONFIG_BT_MESH=y CONFIG_BT_MESH_LOG_LEVEL_DBG=y CONFIG_BT_MESH_RELAY=y @@ -37,7 +37,7 @@ CONFIG_BT_MESH_LABEL_COUNT=3 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=y +CONFIG_BT_MESH_PROVISIONEE=y CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_CDB_NODE_COUNT=4 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y diff --git a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf index ab6066e01bf4..fd0c953226b0 100644 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf @@ -15,7 +15,7 @@ CONFIG_BT_BROADCASTER=y CONFIG_BT_CTLR_DUP_FILTER_LEN=0 CONFIG_BT_CTLR_PRIVACY=n -# Bluetooth mesh configuration +# Bluetooth Mesh configuration CONFIG_BT_MESH=y CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_LOG_LEVEL_DBG=y @@ -39,7 +39,7 @@ CONFIG_BT_MESH_LABEL_COUNT=3 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=y +CONFIG_BT_MESH_PROVISIONEE=y CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_CDB_NODE_COUNT=4 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y diff --git a/tests/bsim/bluetooth/mesh/src/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index a5c8694947b8..3dcaa5f784aa 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -1,5 +1,5 @@ /** @file - * @brief Common functionality for Bluetooth mesh BabbleSim tests. + * @brief Common functionality for Bluetooth Mesh BabbleSim tests. */ /* diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index b8b10fd7634c..6967aa6d71c1 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -60,6 +60,7 @@ static const struct { uint8_t div; int32_t period_ms; } test_period[] = { + { BT_MESH_PUB_PERIOD_100MS(1), 0, 100 }, { BT_MESH_PUB_PERIOD_100MS(5), 0, 500 }, { BT_MESH_PUB_PERIOD_SEC(2), 0, 2000 }, { BT_MESH_PUB_PERIOD_10SEC(1), 0, 10000 }, @@ -101,11 +102,15 @@ static bool publish_allow; static int model1_update(const struct bt_mesh_model *model) { - model->pub->msg->data[1]++; + if (!publish_allow) { + return -1; + } + model->pub->msg->data[1]++; LOG_DBG("New pub: n: %d t: %d", model->pub->msg->data[1], k_uptime_get_32()); + k_sem_give(&publish_sem); - return publish_allow ? k_sem_give(&publish_sem), 0 : -1; + return 0; } static int test_msgf_handler(const struct bt_mesh_model *model, @@ -522,6 +527,92 @@ static void msgf_publish(void) bt_mesh_model_publish(model); } +static void pub_delayable_check(int32_t interval, uint8_t count) +{ + int64_t timestamp = k_uptime_get(); + int err; + + for (size_t j = 0; j < count; j++) { + /* Every new publication will release semaphore in the update handler and the time + * between two consecutive publications will be measured. + */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Send timed out"); + } + + int32_t time_delta = k_uptime_delta(×tamp); + int32_t pub_delta = time_delta - interval; + + LOG_DBG("Send time: %d delta: %d pub_delta: %d", (int32_t)timestamp, time_delta, + pub_delta); + + if (j == 0) { + /* The first delta will be between the messages published manually and next + * publication (or retransmission). So the time difference should not be + * longer than 500 - 20 + 10 (margin): + * + * |---|-------|--------|-------|----> + * M1 20ms tx(M1) 500ms + * update() + */ + ASSERT_IN_RANGE(pub_delta, 0, 510); + } else { + /* Time difference between the consequtive update callback calls should be + * within a small margin like without random delay as the callbacks should + * be called at the regular interval or immediately (if it passed the next + * period time). + */ + ASSERT_IN_RANGE(pub_delta, 0, 10); + } + } +} + +static void recv_delayable_check(int32_t interval, uint8_t count) +{ + int64_t timestamp; + int err; + + /* The measurement starts by the first received message. */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Recv timed out"); + } + + timestamp = k_uptime_get(); + + for (size_t j = 0; j < count; j++) { + /* Every new received message will release semaphore in the message handler and + * the time between two consecutive publications will be measured. + */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Recv timed out"); + } + + int32_t time_delta = k_uptime_delta(×tamp); + /* First message can be delayed up to 500ms, others for up to 50ms. */ + int32_t upper_delay = j == 0 ? 500 : 50; + + /* + * Lower boundary: tx2 - tx1 + interval + * |---|-------|---------------|-------|-----> + * M1 tx1(50ms/500ms) M2 tx2(20ms) + * + * Upper boundary: tx2 - tx1 + interval + * |---|-------|--------|-----------|-----> + * M1 tx1(20ms) M2 tx2(50ms/500ms) + */ + int32_t lower_boundary = 20 - upper_delay + interval; + int32_t upper_boundary = upper_delay - 20 + interval; + + LOG_DBG("Recv time: %d delta: %d boundaries: %d/%d", (int32_t)timestamp, time_delta, + lower_boundary, upper_boundary); + ASSERT_IN_RANGE(time_delta, lower_boundary - RX_JITTER_MAX, + upper_boundary + RX_JITTER_MAX); + } +} + static void pub_jitter_check(int32_t interval, uint8_t count) { int64_t timestamp = k_uptime_get(); @@ -578,8 +669,8 @@ static void recv_jitter_check(int32_t interval, uint8_t count) jitter = MAX(pub_delta, jitter); - LOG_DBG("Recv time: %d delta: %d jitter: %d", (int32_t)timestamp, time_delta, - jitter); + LOG_DBG("Recv time: %d delta: %d jitter: %d, j: %d", (int32_t)timestamp, time_delta, + jitter, j); } LOG_INF("Recv jitter: %d", jitter); @@ -589,17 +680,19 @@ static void recv_jitter_check(int32_t interval, uint8_t count) /* Test publish period states by publishing a message and checking interval between update handler * calls. */ -static void test_tx_period(void) +static void tx_period(bool delayable) { const struct bt_mesh_model *model = &models[2]; - bt_mesh_test_cfg_set(NULL, 60); + bt_mesh_test_cfg_set(NULL, 70); bt_mesh_device_setup(&prov, &local_comp); provision(UNICAST_ADDR1); common_configure(UNICAST_ADDR1); k_sem_init(&publish_sem, 0, 1); + model->pub->delayable = delayable; + for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) { pub_param_set(test_period[i].period, 0); @@ -611,7 +704,11 @@ static void test_tx_period(void) /* Start publishing messages and measure jitter. */ msgf_publish(); publish_allow = true; - pub_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + if (delayable) { + pub_delayable_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } else { + pub_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } /* Disable periodic publication before the next test iteration. */ publish_allow = false; @@ -626,9 +723,9 @@ static void test_tx_period(void) /* Receive a periodically published message and check publication period by measuring interval * between message handler calls. */ -static void test_rx_period(void) +static void rx_period(bool delayable) { - bt_mesh_test_cfg_set(NULL, 60); + bt_mesh_test_cfg_set(NULL, 70); bt_mesh_device_setup(&prov, &local_comp); provision(UNICAST_ADDR2); common_configure(UNICAST_ADDR2); @@ -636,16 +733,40 @@ static void test_rx_period(void) k_sem_init(&publish_sem, 0, 1); for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) { - recv_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + if (delayable) { + recv_delayable_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } else { + recv_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } } PASS(); } +static void test_tx_period(void) +{ + tx_period(false); +} + +static void test_rx_period(void) +{ + rx_period(false); +} + +static void test_tx_period_delayable(void) +{ + tx_period(true); +} + +static void test_rx_period_delayable(void) +{ + rx_period(true); +} + /* Test publish retransmit interval and count states by publishing a message and checking interval * between update handler calls. */ -static void test_tx_transmit(void) +static void tx_transmit(bool delayable) { const struct bt_mesh_model *model = &models[2]; uint8_t status; @@ -672,6 +793,7 @@ static void test_tx_transmit(void) publish_allow = true; model->pub->retr_update = true; + model->pub->delayable = delayable; for (size_t i = 0; i < ARRAY_SIZE(test_transmit); i++) { pub_param_set(0, test_transmit[i]); @@ -683,7 +805,11 @@ static void test_tx_transmit(void) /* Start publishing messages and measure jitter. */ msgf_publish(); - pub_jitter_check(interval, count); + if (delayable) { + pub_delayable_check(interval, count); + } else { + pub_jitter_check(interval, count); + } /* Let the receiver hit the first semaphore. */ k_sleep(K_SECONDS(1)); @@ -695,7 +821,7 @@ static void test_tx_transmit(void) /* Receive a published message and check retransmission interval by measuring interval between * message handler calls. */ -static void test_rx_transmit(void) +static void rx_transmit(bool delayable) { bt_mesh_test_cfg_set(NULL, 60); bt_mesh_device_setup(&prov, &local_comp); @@ -708,12 +834,36 @@ static void test_rx_transmit(void) int32_t interval = BT_MESH_PUB_TRANSMIT_INT(test_transmit[i]); int count = BT_MESH_PUB_TRANSMIT_COUNT(test_transmit[i]); - recv_jitter_check(interval, count); + if (delayable) { + recv_delayable_check(interval, count); + } else { + recv_jitter_check(interval, count); + } } PASS(); } +static void test_tx_transmit(void) +{ + tx_transmit(false); +} + +static void test_rx_transmit(void) +{ + rx_transmit(false); +} + +static void test_tx_transmit_delayable(void) +{ + tx_transmit(true); +} + +static void test_rx_transmit_delayable(void) +{ + rx_transmit(true); +} + /* Cancel one of messages to be published and check that the next one is published when next period * starts. */ @@ -841,6 +991,13 @@ static const struct bst_test_instance test_access[] = { TEST_CASE(tx, cancel, "Access: Cancel a message during publication"), TEST_CASE(rx, cancel, "Access: Receive published messages except cancelled"), + TEST_CASE(tx, period_delayable, "Access: Test delayable periodic publication"), + TEST_CASE(rx, period_delayable, "Access: Receive delayable periodic publication"), + + TEST_CASE(tx, transmit_delayable, "Access: Test delayable publication with retransmission"), + TEST_CASE(rx, transmit_delayable, "Access: Receive delayable publication with" + " retransmissions"), + BSTEST_END_MARKER }; diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 073651ae8439..47851fc72f4a 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -7,7 +7,6 @@ #include #include #include "mesh_test.h" -#include "mesh/adv.h" #include "mesh/net.h" #include "mesh/mesh.h" #include "mesh/foundation.h" @@ -78,25 +77,25 @@ static void adv_init(void) ASSERT_OK_MSG(bt_mesh_adv_enable(), "Mesh adv init failed"); } -static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmit) +static void allocate_all_array(struct bt_mesh_adv **adv, size_t num_adv, uint8_t xmit) { - for (int i = 0; i < num_buf; i++) { - *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + for (int i = 0; i < num_adv; i++) { + *adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!*buf, "Out of buffers\n"); - buf++; + ASSERT_FALSE_MSG(!*adv, "Out of advs\n"); + adv++; } } static void verify_adv_queue_overflow(void) { - struct net_buf *dummy_buf; + struct bt_mesh_adv *dummy_adv; /* Verity Queue overflow */ - dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + dummy_adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_TRUE_MSG(!dummy_buf, "Unexpected extra buffer\n"); + ASSERT_TRUE_MSG(!dummy_adv, "Unexpected extra adv\n"); } static bool check_delta_time(uint8_t transmit, uint64_t interval) @@ -157,12 +156,12 @@ static void single_end_cb(int err, void *cb_data) static void realloc_end_cb(int err, void *cb_data) { - struct net_buf *buf = (struct net_buf *)cb_data; + struct bt_mesh_adv *adv = (struct bt_mesh_adv *)cb_data; ASSERT_EQUAL(0, err); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); + ASSERT_FALSE_MSG(!adv, "Out of advs\n"); k_sem_give(&observer_sem); } @@ -305,13 +304,13 @@ static void rx_xmit_adv(void) static void send_order_start_cb(uint16_t duration, int err, void *user_data) { - struct net_buf *buf = (struct net_buf *)user_data; + struct bt_mesh_adv *adv = (struct bt_mesh_adv *)user_data; ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err); - ASSERT_EQUAL(2, buf->len); + ASSERT_EQUAL(2, adv->b.len); - uint8_t current = buf->data[0]; - uint8_t previous = buf->data[1]; + uint8_t current = adv->b.data[0]; + uint8_t previous = adv->b.data[1]; LOG_INF("tx start: current(%d) previous(%d)", current, previous); @@ -321,10 +320,7 @@ static void send_order_start_cb(uint16_t duration, int err, void *user_data) static void send_order_end_cb(int err, void *user_data) { - struct net_buf *buf = (struct net_buf *)user_data; - ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err); - ASSERT_TRUE_MSG(!buf->data, "Data not cleared!\n"); seq_checker++; LOG_INF("tx end: seq(%d)", seq_checker); @@ -380,19 +376,19 @@ static void receive_order(int expect_adv) ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err); } -static void send_adv_buf(struct net_buf *buf, uint8_t curr, uint8_t prev) +static void send_adv_buf(struct bt_mesh_adv *adv, uint8_t curr, uint8_t prev) { send_cb.start = send_order_start_cb; send_cb.end = send_order_end_cb; - (void)net_buf_add_u8(buf, curr); - (void)net_buf_add_u8(buf, prev); + (void)net_buf_simple_add_u8(&adv->b, curr); + (void)net_buf_simple_add_u8(&adv->b, prev); - bt_mesh_adv_send(buf, &send_cb, buf); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &send_cb, adv); + bt_mesh_adv_unref(adv); } -static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) +static void send_adv_array(struct bt_mesh_adv **adv, size_t num_buf, bool reverse) { uint8_t previous; int i; @@ -405,13 +401,13 @@ static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) i = num_buf - 1; } while ((!reverse && i < num_buf) || (reverse && i >= 0)) { - send_adv_buf(*buf, (uint8_t)i, previous); + send_adv_buf(*adv, (uint8_t)i, previous); previous = (uint8_t)i; if (!reverse) { - buf++; + adv++; i++; } else { - buf--; + adv--; i--; } } @@ -419,24 +415,24 @@ static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) static void test_tx_cb_single(void) { - struct net_buf *buf; + struct bt_mesh_adv *adv; int err; bt_init(); adv_init(); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(2, 20), K_NO_WAIT); - ASSERT_FALSE_MSG(!buf, "Out of buffers\n"); + ASSERT_FALSE_MSG(!adv, "Out of advs\n"); send_cb.start = single_start_cb; send_cb.end = single_end_cb; - net_buf_add_mem(buf, txt_msg, sizeof(txt_msg)); + net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg)); seq_checker = 0; tx_timestamp = k_uptime_get(); - bt_mesh_adv_send(buf, &send_cb, (void *)cb_msg); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &send_cb, (void *)cb_msg); + bt_mesh_adv_unref(adv); err = k_sem_take(&observer_sem, K_SECONDS(1)); ASSERT_OK_MSG(err, "Didn't call end tx cb."); @@ -457,37 +453,37 @@ static void test_rx_xmit(void) static void test_tx_cb_multi(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; int err; bt_init(); adv_init(); - /* Allocate all network buffers. */ - allocate_all_array(buf, ARRAY_SIZE(buf), BT_MESH_TRANSMIT(2, 20)); + /* Allocate all network advs. */ + allocate_all_array(adv, ARRAY_SIZE(adv), BT_MESH_TRANSMIT(2, 20)); - /* Start single adv to reallocate one network buffer in callback. - * Check that the buffer is freed before cb is triggered. + /* Start single adv to reallocate one network adv in callback. + * Check that the adv is freed before cb is triggered. */ send_cb.start = NULL; send_cb.end = realloc_end_cb; - net_buf_add_mem(buf[0], txt_msg, sizeof(txt_msg)); + net_buf_simple_add_mem(&(adv[0]->b), txt_msg, sizeof(txt_msg)); - bt_mesh_adv_send(buf[0], &send_cb, buf[0]); - net_buf_unref(buf[0]); + bt_mesh_adv_send(adv[0], &send_cb, adv[0]); + bt_mesh_adv_unref(adv[0]); err = k_sem_take(&observer_sem, K_SECONDS(1)); - ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates buffer one more time."); + ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates adv one more time."); - /* Start multi advs to check that all buffers are sent and cbs are triggered. */ + /* Start multi advs to check that all advs are sent and cbs are triggered. */ send_cb.start = seq_start_cb; send_cb.end = seq_end_cb; seq_checker = 0; for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) { - net_buf_add_le32(buf[i], i); - bt_mesh_adv_send(buf[i], &send_cb, (void *)(intptr_t)i); - net_buf_unref(buf[i]); + net_buf_simple_add_le32(&(adv[i]->b), i); + bt_mesh_adv_send(adv[i], &send_cb, (void *)(intptr_t)i); + bt_mesh_adv_unref(adv[i]); } err = k_sem_take(&observer_sem, K_SECONDS(10)); @@ -530,10 +526,10 @@ static void test_tx_proxy_mixin(void) * Advertising the proxy service should be resumed after * finishing advertising the message. */ - struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + struct bt_mesh_adv *adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, BT_MESH_TRANSMIT(5, 20), K_NO_WAIT); - net_buf_add_mem(buf, txt_msg, sizeof(txt_msg)); - bt_mesh_adv_send(buf, NULL, NULL); + net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg)); + bt_mesh_adv_send(adv, NULL, NULL); k_sleep(K_MSEC(150)); /* Let the tester to measure an interval between advertisements again. */ @@ -577,46 +573,46 @@ static void test_rx_proxy_mixin(void) static void test_tx_send_order(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; uint8_t xmit = BT_MESH_TRANSMIT(2, 20); bt_init(); adv_init(); /* Verify sending order */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); verify_adv_queue_overflow(); - send_adv_array(&buf[0], ARRAY_SIZE(buf), false); + send_adv_array(&adv[0], ARRAY_SIZE(adv), false); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), "Didn't call the last end tx cb."); - /* Verify buffer allocation/deallocation after sending */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + /* Verify adv allocation/deallocation after sending */ + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); verify_adv_queue_overflow(); for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) { - net_buf_unref(buf[i]); - buf[i] = NULL; + bt_mesh_adv_unref(adv[i]); + adv[i] = NULL; } - /* Check that it possible to add just one net buf. */ - allocate_all_array(buf, 1, xmit); + /* Check that it possible to add just one net adv. */ + allocate_all_array(adv, 1, xmit); PASS(); } static void test_tx_reverse_order(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; uint8_t xmit = BT_MESH_TRANSMIT(2, 20); bt_init(); adv_init(); /* Verify reversed sending order */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); - send_adv_array(&buf[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(buf), true); + send_adv_array(&adv[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(adv), true); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), @@ -627,31 +623,31 @@ static void test_tx_reverse_order(void) static void test_tx_random_order(void) { - struct net_buf *buf[3]; + struct bt_mesh_adv *adv[3]; uint8_t xmit = BT_MESH_TRANSMIT(0, 20); bt_init(); adv_init(); /* Verify random order calls */ - num_adv_sent = ARRAY_SIZE(buf); + num_adv_sent = ARRAY_SIZE(adv); previous_checker = 0xff; - buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n"); - buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + ASSERT_FALSE_MSG(!adv[0], "Out of advs\n"); + adv[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!buf[1], "Out of buffers\n"); + ASSERT_FALSE_MSG(!adv[1], "Out of advs\n"); - send_adv_buf(buf[0], 0, 0xff); + send_adv_buf(adv[0], 0, 0xff); - buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, xmit, K_NO_WAIT); - ASSERT_FALSE_MSG(!buf[2], "Out of buffers\n"); + ASSERT_FALSE_MSG(!adv[2], "Out of advs\n"); - send_adv_buf(buf[2], 2, 0); + send_adv_buf(adv[2], 2, 0); - send_adv_buf(buf[1], 1, 2); + send_adv_buf(adv[1], 1, 2); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index e93c2301e46d..e5f7d515da7f 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -6,7 +6,6 @@ #include #include #include "mesh_test.h" -#include "mesh/adv.h" #include "mesh/net.h" #include "mesh/beacon.h" #include "mesh/mesh.h" @@ -32,7 +31,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define BEACON_TYPE_PRIVATE 0x02 #endif -static uint8_t test_net_key_secondary[16] = { 0xca, 0x11, 0xab, 0x1e }; +static uint8_t test_net_key_2[16] = { 0xca, 0x11, 0xab, 0x1e }; static struct { uint8_t primary[16]; uint8_t secondary[16]; @@ -335,6 +334,7 @@ static struct { uint8_t random[13]; uint64_t pp_hash; uint64_t pp_random; + uint64_t net_id; bt_addr_le_t adv_addr; #endif bool (*process_cb)(const uint8_t *net_id, void *ctx); @@ -626,7 +626,7 @@ static void test_tx_kr_old_key(void) * the new Net Key. The node shall set Key Refresh phase to 2. The beacon interval shall * be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x03, 0x0001); + beacon_create(&buf, test_net_key_2, 0x03, 0x0001); send_beacon(&buf); ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); @@ -646,7 +646,7 @@ static void test_tx_kr_old_key(void) /* Try the same with the new Net Key. Now the node shall change Key Refresh phase to 0. The * beacon interval shall be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x02, 0x0001); + beacon_create(&buf, test_net_key_2, 0x02, 0x0001); send_beacon(&buf); ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); @@ -666,7 +666,7 @@ static void test_tx_kr_old_key(void) /* Do the same, but secure beacon with the new Net Key. Now the node shall change IV Update * flag to 0. The beacon interval shall be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x00, 0x0001); + beacon_create(&buf, test_net_key_2, 0x00, 0x0001); send_beacon(&buf); ASSERT_FALSE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); ASSERT_TRUE(wait_for_beacon(beacon_scan_cb, BEACON_INTERVAL + 1, NULL, NULL)); @@ -687,7 +687,7 @@ static void test_rx_kr_old_key(void) bt_mesh_test_setup(); bt_mesh_iv_update_test(true); - err = bt_mesh_cfg_cli_net_key_update(0, cfg->addr, 0, test_net_key_secondary, &status); + err = bt_mesh_cfg_cli_net_key_update(0, cfg->addr, 0, test_net_key_2, &status); if (err || status) { FAIL("Net Key update failed (err %d, status %u)", err, status); } @@ -1542,60 +1542,73 @@ static void test_tx_priv_beacon_cache(void) #if IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) +static uint8_t test_net_key_3[16] = {0x12, 0x54, 0xab, 0x1e}; + +#define UNTIL_UPTIME(time) (k_uptime_get() > (time) ? K_NO_WAIT : K_MSEC((time) - k_uptime_get())) +#define BEACON_TYPE_NET_ID 0 +#define BEACON_TYPE_NODE_ID 1 #define BEACON_TYPE_PRIVATE_NET_ID 2 #define BEACON_TYPE_PRIVATE_NODE_ID 3 #define BEACON_TYPE_PRIVATE_LEN 28 #define TEST_NET_IDX1 0 #define TEST_NET_IDX2 1 +#define TEST_NET_IDX3 2 #define MAX_TIMEOUT ((CONFIG_BT_MESH_NODE_ID_TIMEOUT * 1000) / 6) #define PP_NET_ID_WAIT_TIME 610 /*seconds*/ #define PP_NODE_ID_WAIT_TIME 80 /*seconds*/ #define PP_MULT_NET_ID_WAIT_TIME 50 /*seconds*/ +#define PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME 151 /*seconds*/ -struct pp_netkey_ctx { +struct netkey_ctx { uint8_t *net_key; uint8_t net_id[8]; + uint8_t net_idx; struct bt_mesh_key id_key; }; -static struct pp_netkey_ctx pp_net0 = {.net_key = (uint8_t *)test_net_key}; -static struct pp_netkey_ctx pp_net1 = {.net_key = (uint8_t *)test_net_key_secondary}; +static struct netkey_ctx pp_net0 = {.net_key = (uint8_t *)test_net_key, .net_idx = 0}; +static struct netkey_ctx pp_net1 = {.net_key = (uint8_t *)test_net_key_2, .net_idx = 1}; +static struct netkey_ctx pp_net2 = {.net_key = (uint8_t *)test_net_key_3, .net_idx = 2}; struct priv_test_ctx { uint8_t beacon_type; uint16_t *node_id_addr; }; -static void pp_netkey_ctx_init(struct pp_netkey_ctx *net) +static void pp_netkey_ctx_init(struct netkey_ctx *net) { ASSERT_OK_MSG(bt_mesh_identity_key(net->net_key, &net->id_key), "Failed to generate ID key"); ASSERT_OK_MSG(bt_mesh_k3(net->net_key, net->net_id), "Failed to generate Net ID"); } -static bool pp_type_check(uint16_t expected_beacon, uint8_t adv_type, struct net_buf_simple *buf) +static uint8_t proxy_adv_type_get(uint8_t adv_type, struct net_buf_simple *buf) { - if (adv_type != BT_GAP_ADV_TYPE_ADV_IND || buf->len != BEACON_TYPE_PRIVATE_LEN) { - return false; + uint8_t type; + uint8_t len = buf->len; + + if (adv_type != BT_GAP_ADV_TYPE_ADV_IND || len < 12) { + return 0xFF; } - /* Remove Header */ (void)net_buf_simple_pull_mem(buf, 11); - - uint8_t beacon_type = net_buf_simple_pull_u8(buf); - - if (beacon_type != expected_beacon) { - return false; + type = net_buf_simple_pull_u8(buf); + /* BEACON_TYPE_NET_ID is 20 bytes long, while the three other accepted types are 28 bytes*/ + if (len != ((type == BEACON_TYPE_NET_ID) ? 20 : 28)) { + return 0xFF; } - return true; + return type; } -static uint64_t pp_hash_calc(struct pp_netkey_ctx *net, uint64_t random, uint16_t *addr) +static uint64_t proxy_adv_hash_calc(struct netkey_ctx *net, uint64_t random, uint16_t *addr, + bool is_priv) { uint64_t hash; - uint8_t tmp[16] = {0, 0, 0, 0, 0, 3}; + uint8_t tmp[16] = {0}; + + tmp[5] = is_priv ? 3 : 0; if (addr) { memcpy(&tmp[6], &random, 8); @@ -1617,7 +1630,7 @@ static bool pp_beacon_check(const uint8_t *net_id, void *ctx) struct priv_test_ctx *test_ctx = (struct priv_test_ctx *)ctx; ASSERT_EQUAL(beacon.pp_hash, - pp_hash_calc(&pp_net0, beacon.pp_random, test_ctx->node_id_addr)); + proxy_adv_hash_calc(&pp_net0, beacon.pp_random, test_ctx->node_id_addr, true)); if (memcmp(beacon.adv_addr.a.val, last_beacon_adv_addr.a.val, BT_ADDR_SIZE) == 0) { return false; @@ -1633,15 +1646,58 @@ static void priv_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type { struct priv_test_ctx *ctx = (struct priv_test_ctx *)beacon.user_ctx; - if (!pp_type_check(ctx->beacon_type, adv_type, buf)) { + if (proxy_adv_type_get(adv_type, buf) != ctx->beacon_type) { /* Wrong message type */ return; } bt_addr_le_copy(&beacon.adv_addr, addr); - beacon.pp_hash = net_buf_simple_pull_le64(buf); - beacon.pp_random = net_buf_simple_pull_le64(buf); + if (ctx->beacon_type == BEACON_TYPE_NET_ID) { + beacon.net_id = net_buf_simple_pull_le64(buf); + } else { + beacon.pp_hash = net_buf_simple_pull_le64(buf); + beacon.pp_random = net_buf_simple_pull_le64(buf); + } + + if (!beacon.process_cb || beacon.process_cb(NULL, beacon.user_ctx)) { + k_sem_give(&observer_sem); + } +} + +struct proxy_adv_beacon { + uint8_t evt_type; + uint8_t net_idx; + int64_t rx_timestamp; + union { + uint64_t net_id; + struct { + uint64_t hash; + uint64_t random; + } enc; + } ctx; +}; + +static void proxy_adv_scan_all_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, + struct net_buf_simple *buf) +{ + struct proxy_adv_beacon *beac = (struct proxy_adv_beacon *)beacon.user_ctx; + + beac->evt_type = proxy_adv_type_get(adv_type, buf); + if (beac->evt_type == 0xFF) { + /* Not a related beacon type */ + return; + } + + bt_addr_le_copy(&beacon.adv_addr, addr); + beac->rx_timestamp = k_uptime_get(); + + if (beac->evt_type == BEACON_TYPE_NET_ID) { + beac->ctx.net_id = net_buf_simple_pull_le64(buf); + } else { + beac->ctx.enc.hash = net_buf_simple_pull_le64(buf); + beac->ctx.enc.random = net_buf_simple_pull_le64(buf); + } if (!beacon.process_cb || beacon.process_cb(NULL, beacon.user_ctx)) { k_sem_give(&observer_sem); @@ -1657,11 +1713,11 @@ static void rx_priv_common_init(uint16_t wait) ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed"); } -static void tx_priv_common_init(uint16_t wait) +static void tx_proxy_adv_common_init(uint16_t wait, const struct bt_mesh_test_cfg *cfg) { bt_mesh_test_cfg_set(NULL, wait); bt_mesh_device_setup(&prov, &prb_comp); - provision(&tx_cfg); + provision(cfg); /* Disable GATT proxy */ ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), @@ -1670,7 +1726,7 @@ static void tx_priv_common_init(uint16_t wait) static void test_tx_priv_net_id(void) { - tx_priv_common_init(PP_NET_ID_WAIT_TIME); + tx_proxy_adv_common_init(PP_NET_ID_WAIT_TIME, &tx_cfg); /* Enable private GATT proxy */ ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), @@ -1709,7 +1765,7 @@ static void test_tx_priv_node_id(void) { enum bt_mesh_feat_state state; - tx_priv_common_init(PP_NODE_ID_WAIT_TIME); + tx_proxy_adv_common_init(PP_NODE_ID_WAIT_TIME, &tx_cfg); /* Start first node advertisement */ ASSERT_OK_MSG(bt_mesh_subnet_priv_node_id_set(TEST_NET_IDX1, BT_MESH_NODE_IDENTITY_RUNNING), @@ -1762,16 +1818,10 @@ static void test_rx_priv_node_id(void) static void test_tx_priv_multi_net_id(void) { - tx_priv_common_init(PP_MULT_NET_ID_WAIT_TIME); - - /* TODO: This should be removed as soon as - * SNB/proxy service advertising issue has - * been resolved. - */ - bt_mesh_beacon_set(false); + tx_proxy_adv_common_init(PP_MULT_NET_ID_WAIT_TIME, &tx_cfg); /* Add second network */ - ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_secondary), + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), "Failed to add second subnet"); /* Enable private GATT proxy */ @@ -1781,6 +1831,246 @@ static void test_tx_priv_multi_net_id(void) PASS(); } +static void proxy_adv_subnet_find(struct proxy_adv_beacon *beac, struct netkey_ctx **nets, + uint8_t net_cnt) +{ + for (size_t i = 0; i < net_cnt; i++) { + + switch (beac->evt_type) { + case BEACON_TYPE_NET_ID: + if (!memcmp(nets[i]->net_id, &beac->ctx.net_id, 8)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_NODE_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + (uint16_t *)&tx_cfg.addr, false)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_PRIVATE_NET_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + NULL, true)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_PRIVATE_NODE_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + (uint16_t *)&tx_cfg.addr, true)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + + default: + FAIL("Unexpected beacon type"); + break; + } + } + + FAIL("Could not find matching subnet for incoming proxy adv beacon"); +} + +static const char *const proxy_adv_str[] = {"Net_ID", "Node_ID", "Priv_Net_ID", "Priv_Node_ID"}; +struct expected_proxy_adv_evt { + uint8_t evt_type; + uint8_t net_idx; + uint16_t evt_cnt; + struct { + int64_t after; + int64_t before; + } time; +}; + +static void proxy_adv_register_evt(struct proxy_adv_beacon *beac, + struct expected_proxy_adv_evt *exp_evts, uint8_t cnt) +{ + for (int i = 0; i < cnt; i++) { + if ((exp_evts[i].evt_cnt) && (beac->evt_type == exp_evts[i].evt_type) && + (beac->net_idx == exp_evts[i].net_idx) && + (beac->rx_timestamp >= exp_evts[i].time.after) && + (beac->rx_timestamp <= exp_evts[i].time.before)) { + exp_evts[i].evt_cnt--; + } + } +} + +static void proxy_adv_confirm_evt(struct expected_proxy_adv_evt *exp_evts, uint8_t cnt) +{ + bool missing_evts = false; + + for (int i = 0; i < cnt; i++) { + if (exp_evts[i].evt_cnt) { + LOG_ERR("Missing %d expected %s events in period %llums-%llums", + exp_evts[i].evt_cnt, proxy_adv_str[exp_evts[i].evt_type], + exp_evts[i].time.after, exp_evts[i].time.before); + missing_evts = true; + } + } + + if (missing_evts) { + FAIL("Test failed due to missing events"); + } +} + +static void proxy_adv_scan_all(struct netkey_ctx **nets, uint16_t net_cnt, + struct expected_proxy_adv_evt *exp_evt, uint16_t exp_evt_cnt, + int64_t timeout) +{ + struct proxy_adv_beacon beac; + + while (k_uptime_get() < timeout) { + + ASSERT_TRUE(wait_for_beacon(proxy_adv_scan_all_cb, 2, NULL, &beac)); + proxy_adv_subnet_find(&beac, nets, net_cnt); + proxy_adv_register_evt(&beac, exp_evt, exp_evt_cnt); + + /** We want to monitor an even distribution of adv events. + * To ensure this, we wait a little less than the minimum + * proxy adv period (1 second) before scanning for the next + * evt. + */ + k_sleep(K_MSEC(990)); + } + + proxy_adv_confirm_evt(exp_evt, exp_evt_cnt); +} + +#define PROXY_ADV_MULTI_CHECKPOINT_1 20000 +#define PROXY_ADV_MULTI_CHECKPOINT_2 50000 +#define PROXY_ADV_MULTI_CHECKPOINT_3 110000 +#define PROXY_ADV_MULTI_CHECKPOINT_4 130000 +#define PROXY_ADV_MULTI_CHECKPOINT_END 150000 + +static void test_tx_proxy_adv_multi_subnet_coex(void) +{ + tx_proxy_adv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME, &tx_cfg); + + /* Enable GATT proxy */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to Enable gatt proxy"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_1)); + /* Add second and third network */ + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), + "Failed to add second subnet"); + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX3, test_net_key_3), + "Failed to add third subnet"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_2)); + /* Start Node Identity on second network */ + bt_mesh_proxy_identity_start(bt_mesh_subnet_get(TEST_NET_IDX2), false); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_3)); + /* Prepare for solicitation */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), + "Failed to Enable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_od_priv_proxy_set(20), "Failed to set OD priv proxy state"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_4)); + /* Re-enable GATT proxy and remove second and third network */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to Enable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_subnet_del(TEST_NET_IDX2), "Failed to delete subnet"); + ASSERT_OK_MSG(bt_mesh_subnet_del(TEST_NET_IDX3), "Failed to delete subnet"); + + PASS(); +} + +static const struct bt_mesh_test_cfg solicit_trigger_cfg = { + .addr = 0x0003, + .dev_key = { 0x03 }, +}; + +static void test_tx_proxy_adv_solicit_trigger(void) +{ + tx_proxy_adv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME, &solicit_trigger_cfg); + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), + "Failed to add second subnet"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_3)); + + /* Solicit first and second network */ + ASSERT_OK_MSG(bt_mesh_proxy_solicit(TEST_NET_IDX1), + "Failed to start solicitation"); + ASSERT_OK_MSG(bt_mesh_proxy_solicit(TEST_NET_IDX2), + "Failed to start solicitation"); + + PASS(); +} + +static void test_rx_proxy_adv_multi_subnet_coex(void) +{ + rx_priv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME); + pp_netkey_ctx_init(&pp_net1); + pp_netkey_ctx_init(&pp_net2); + + struct netkey_ctx *nets[] = {&pp_net0, &pp_net1, &pp_net2}; + struct expected_proxy_adv_evt exp_evt[] = { + /** A single subnet is active on the device with GATT Proxy + * enabled. Verify that the single subnet has exclusive + * access to the adv medium. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 19, + .time = {.after = 0, .before = PROXY_ADV_MULTI_CHECKPOINT_1}}, + + /** Two additional subnets are added to the device. + * Check that the subnets are sharing the adv medium, + * advertising NET_ID beacons. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 1, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 2, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + + /** The second subnet enables Node Identity. Check that NODE_ID + * is advertised by this subnet, and that the two others + * continues to advertise NET_ID. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 17, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + {.evt_type = BEACON_TYPE_NODE_ID, .net_idx = 1, .evt_cnt = 17, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 2, .evt_cnt = 17, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + + /** The first and second subnet gets solicited. Check that + * PRIVATE_NET_ID is advertised by these subnet, + */ + {.evt_type = BEACON_TYPE_PRIVATE_NET_ID, .net_idx = 0, .evt_cnt = 9, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_3, + .before = PROXY_ADV_MULTI_CHECKPOINT_4}}, + {.evt_type = BEACON_TYPE_PRIVATE_NET_ID, .net_idx = 1, .evt_cnt = 9, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_3, + .before = PROXY_ADV_MULTI_CHECKPOINT_4}}, + + /** Second and third subnet are disabled. Verify that the single + * subnet has exclusive access to the adv medium. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 19, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_4, + .before = PROXY_ADV_MULTI_CHECKPOINT_END}}, + }; + + proxy_adv_scan_all(nets, ARRAY_SIZE(nets), exp_evt, ARRAY_SIZE(exp_evt), + PROXY_ADV_MULTI_CHECKPOINT_END); + PASS(); +} + static void test_rx_priv_multi_net_id(void) { rx_priv_common_init(PP_MULT_NET_ID_WAIT_TIME); @@ -1794,7 +2084,7 @@ static void test_rx_priv_multi_net_id(void) uint16_t itr = 4; static uint8_t old_idx = 0xff; static struct { - struct pp_netkey_ctx *net; + struct netkey_ctx *net; uint16_t recv_cnt; int64_t start; } net_ctx[2] = { @@ -1809,7 +2099,7 @@ static void test_rx_priv_multi_net_id(void) for (size_t i = 0; i < ARRAY_SIZE(net_ctx); i++) { if (beacon.pp_hash == - pp_hash_calc(net_ctx[i].net, beacon.pp_random, NULL)) { + proxy_adv_hash_calc(net_ctx[i].net, beacon.pp_random, NULL, true)) { if (old_idx == 0xff) { /* Received first Net ID advertisment */ old_idx = i; @@ -1820,8 +2110,8 @@ static void test_rx_priv_multi_net_id(void) /* Verify last Net ID adv result */ ASSERT_IN_RANGE(k_uptime_get() - net_ctx[old_idx].start, - MAX_TIMEOUT - 1000, MAX_TIMEOUT); - ASSERT_IN_RANGE(net_ctx[old_idx].recv_cnt, 9, 10); + MAX_TIMEOUT - 1000, MAX_TIMEOUT + 1000); + ASSERT_IN_RANGE(net_ctx[old_idx].recv_cnt, 9, 12); net_ctx[old_idx].recv_cnt = 0; old_idx = i; @@ -1938,6 +2228,8 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(tx, priv_node_id, "Private Proxy: advertise Node ID"), TEST_CASE(tx, priv_multi_net_id, "Private Proxy: advertise multiple Net ID"), TEST_CASE(tx, priv_gatt_proxy, "Private Proxy: Send Private Beacons over GATT"), + TEST_CASE(tx, proxy_adv_multi_subnet_coex, "Proxy Adv: Multi subnet coex proxy adv"), + TEST_CASE(tx, proxy_adv_solicit_trigger, "Proxy Adv: Trigger Solicitation"), #endif #endif @@ -1958,6 +2250,7 @@ static const struct bst_test_instance test_beacon[] = { TEST_CASE(rx, priv_node_id, "Private Proxy: scan for Node ID"), TEST_CASE(rx, priv_multi_net_id, "Private Proxy: scan for multiple Net ID"), TEST_CASE(rx, priv_gatt_proxy, "Private Proxy: Receive Private Beacons over GATT"), + TEST_CASE(rx, proxy_adv_multi_subnet_coex, "Proxy Adv: Multi subnet coex proxy adv"), #endif #endif BSTEST_END_MARKER diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index 4258ff77c625..0d3a69da2fc9 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -6,9 +6,9 @@ #include "mesh_test.h" #include "dfu_blob_common.h" #include "friendship_common.h" +#include "mesh/adv.h" #include "mesh/blob.h" #include "argparse.h" -#include "mesh/adv.h" #define LOG_MODULE_NAME test_blob diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 06f7248a6adf..1b54e873cc5b 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -6,7 +6,6 @@ #include "mesh_test.h" #include "mesh/dfd_srv_internal.h" #include "mesh/dfu_slot.h" -#include "mesh/adv.h" #include "mesh/dfu.h" #include "mesh/blob.h" #include "argparse.h" diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index f2c98778a3b5..3d0e8010c753 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -28,7 +28,6 @@ #define LOG_MODULE_NAME mesh_prov #include -#include "mesh/adv.h" #include "mesh/rpr.h" LOG_MODULE_REGISTER(LOG_MODULE_NAME); diff --git a/tests/bsim/bluetooth/mesh/src/test_scanner.c b/tests/bsim/bluetooth/mesh/src/test_scanner.c index 12557b7e1b2a..a63284701df3 100644 --- a/tests/bsim/bluetooth/mesh/src/test_scanner.c +++ b/tests/bsim/bluetooth/mesh/src/test_scanner.c @@ -6,7 +6,6 @@ #include #include "mesh_test.h" #include "mesh/net.h" -#include "mesh/adv.h" #include "mesh/mesh.h" #include "mesh/foundation.h" diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh new file mode 100755 index 000000000000..5ecd4a061de8 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +RunTest mesh_access_pub_period_delayable_retr \ + access_tx_period_delayable access_rx_period_delayable + +conf=prj_mesh1d1_conf +RunTest mesh_access_pub_period_delayable_retr_1d1 \ + access_tx_period_delayable access_rx_period_delayable + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_access_pub_period_delayable_retr_psa \ + access_tx_period_delayable access_rx_period_delayable diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh new file mode 100755 index 000000000000..0e966288db0e --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +RunTest mesh_access_pub_transmit_delayable_retr \ + access_tx_transmit_delayable access_rx_transmit_delayable + +conf=prj_mesh1d1_conf +RunTest mesh_access_pub_transmit_delayable_retr_1d1 \ + access_tx_transmit_delayable access_rx_transmit_delayable + +conf=prj_mesh1d1_conf +overlay=overlay_psa_conf +RunTest mesh_access_pub_transmit_delayable_retr_psa \ + access_tx_transmit_delayable access_rx_transmit_delayable diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh new file mode 100755 index 000000000000..42863a134588 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Proxy advertisement Coex + +# This test verifies correct Proxy advertisement behavior for a device +# where the Proxy adv requirements changes over time, both for single +# and multiple subnets. The TX device is the DUT in this instance, while +# the RX device scans and verifies that the correct proxy adv messages of +# the different subnets is sent within the expected time delta. + +# Note 1: The maximum allowed timeslot for a subnet to advertise proxy +# in this scenario is 10 seconds when there is more than one subnet that +# has active proxy adv work. This is reflected in the scanning criteria +# on the RX device. + +# Note 2: The expected message received count for each event is based on +# what would be a reasonable/acceptable to receive within a given time +# window. The Mesh Protocol specification does not specify exactly the +# timing for Proxy ADV messages. + +# Note 3: The proxy transmitting device mandates emitting of the secure +# network beacons. This allows to check that proxy goes back to normal +# behavior after the device advertises the secure network beacons. + +# Test procedure: +# 1. (0-20 seconds) A single subnet is active on the TX device with GATT +# Proxy enabled. RX device verifies that the single subnet has exclusive +# access to the adv medium. +# 2. (20-50 seconds) Two additional subnets are added to the TX device. RX +# device checks that the subnets are sharing the adv medium, advertising +# NET_ID beacons. +# 3. (50-110 seconds) The second subnet enables Node Identity. RX device +# checks that NODE_ID is advertised by this subnet, and that the two +# others continues to advertise NET_ID. +# 4. (110-130 seconds) The first and second subnet gets solicited. RX device +# checks that PRIVATE_NET_ID is advertised by these subnets. +# 5. (130-150 seconds) The second and third subnet are disabled on the TX +# device. RX device verifies that the single subnet has exclusive access +# to the adv medium again. + + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf +RunTest proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_multi_subnet_coex \ + beacon_rx_proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_solicit_trigger + +conf=prj_mesh1d1_conf +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_multi_subnet_coex \ + beacon_rx_proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_solicit_trigger diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml index 9b9c25511c4e..c5dbda1913f3 100644 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -3,8 +3,6 @@ tests: drivers.regulator.build: - tags: - - drivers - - regulator + tags: drivers regulator build_only: true platform_allow: native_posix diff --git a/tests/drivers/console_switching/CMakeLists.txt b/tests/drivers/console_switching/CMakeLists.txt new file mode 100644 index 000000000000..3ba70cc081e5 --- /dev/null +++ b/tests/drivers/console_switching/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(uart_console_switching) + +target_sources(app PRIVATE + src/main.c + ) diff --git a/tests/drivers/console_switching/boards/qemu_riscv64.overlay b/tests/drivers/console_switching/boards/qemu_riscv64.overlay new file mode 100644 index 000000000000..47bd79451899 --- /dev/null +++ b/tests/drivers/console_switching/boards/qemu_riscv64.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &devmux0; + zephyr,shell_uart = &devmux0; + }; + + euart0: uart_emul0 { + compatible = "zephyr,uart-emul"; + current-speed = <0>; + status = "okay"; + }; + + euart1: uart_emul1 { + compatible = "zephyr,uart-emul"; + current-speed = <0>; + status = "okay"; + }; + + devmux0: dev_mux_0 { + compatible = "zephyr,devmux"; + devices = <&uart0 &euart0 &euart1>; + zephyr,mutable; + status = "okay"; + }; + + devmux1: dev_mux_1 { + compatible = "zephyr,devmux"; + devices = <&uart0 &euart0 &euart1>; + zephyr,mutable; + selected = <2>; + status = "okay"; + }; +}; diff --git a/tests/drivers/console_switching/prj.conf b/tests/drivers/console_switching/prj.conf new file mode 100644 index 000000000000..fcdd67928c4a --- /dev/null +++ b/tests/drivers/console_switching/prj.conf @@ -0,0 +1,9 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_CONSOLE_SUBSYS=y +CONFIG_CONSOLE_GETLINE=y +CONFIG_DEVICE_MUTABLE=y +CONFIG_DEVMUX=y +CONFIG_UART_EMUL=y diff --git a/tests/drivers/console_switching/src/main.c b/tests/drivers/console_switching/src/main.c new file mode 100644 index 000000000000..95cde150c9be --- /dev/null +++ b/tests/drivers/console_switching/src/main.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define BUF_SIZE 32 + +/* array of const struct device* */ +#define PHANDLE_TO_DEVICE(node_id, prop, idx) DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)) +static const struct device *devs[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_DEVICE, (,))}; + +/* array of names, e.g. "euart0" */ +#define PHANDLE_TO_NAME(node_id, prop, idx) DT_NODE_FULL_NAME(DT_PHANDLE_BY_IDX(node_id, prop, idx)) +static const char *const name[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_NAME, (,))}; + +/* array of greetings, e.g. "Hello, euart0!" */ +#define PHANDLE_TO_TEXT(node_id, prop, idx) \ + "Hello, " DT_NODE_FULL_NAME(DT_PHANDLE_BY_IDX(node_id, prop, idx)) "!" +static const char *const text[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_TEXT, (,))}; + +ZTEST(console_switching, test_write) +{ + size_t normal_uart = DT_PROP(DT_NODELABEL(devmux0), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + /* for each uart_emul device */ + for (size_t i = 0, j = 0, N = ARRAY_SIZE(devs); i < 2 * N; i++, j++, j %= N) { + if (j == normal_uart) { + /* skip testing non-emul uart */ + continue; + } + + int ret[4]; + char buf[BUF_SIZE] = {0}; + + /* write text[j] to dev[j] */ + ret[0] = devmux_select_set(devmux_dev, j); + printk("%s", text[j]); + ret[1] = uart_emul_get_tx_data(devs[j], buf, ARRAY_SIZE(buf)); + ret[2] = devmux_select_set(devmux_dev, normal_uart); + + zassert_ok(ret[0], "Failed to select devmux %zu", j); + zassert_ok(ret[2], "Switching back to selection %zu failed", normal_uart); + + /* verify that text[j] was written to dev[j] */ + TC_PRINT("wrote '%s' to %s\n", buf, name[j]); + + zassert_equal(ret[1], strlen(text[j]), "Only wrote %zu/%zu bytes of '%s'", + ret[1], strlen(text[j]), text[j]); + zassert_equal(0, strcmp(text[j], buf), "Strings '%s' and '%s' do not match", + text[j], buf); + } +} + +ZTEST(console_switching, test_read) +{ + size_t normal_uart = DT_PROP(DT_NODELABEL(devmux0), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + /* for each uart_emul device */ + for (size_t i = 0, j = 0, N = ARRAY_SIZE(devs); i < 2 * N; i++, j++, j %= N) { + if (j == normal_uart) { + /* skip testing non-emul uart */ + continue; + } + + int ret[4]; + char buf[BUF_SIZE] = {0}; + + /* read text[j] from dev[j] */ + ret[0] = devmux_select_set(devmux_dev, j); + console_getline_init(); + ret[1] = uart_emul_put_rx_data(devs[j], (uint8_t *)text[j], strlen(text[j])); + ret[3] = uart_emul_put_rx_data(devs[j], "\n", 1); + snprintf(buf, BUF_SIZE, "%s", console_getline()); + ret[2] = devmux_select_set(devmux_dev, normal_uart); + + zassert_ok(ret[0], "Failed to select devmux %zu", j); + zassert_ok(ret[2], "Switching back to selection %zu failed", normal_uart); + + /* verify that text[j] was written to dev[j] */ + TC_PRINT("read '%s' from %s\n", buf, name[j]); + + zassert_equal(ret[1], strlen(text[j]), "Only put %zu/%zu bytes of '%s'", + ret[1], strlen(text[j]), text[j]); + zassert_equal(0, strcmp(text[j], buf), "Strings '%s' and '%s' do not match", + text[j], buf); + } +} + +static void *setup(void) +{ + size_t selected = DT_PROP(DT_NODELABEL(devmux1), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux1)); + + /* ensure that non-default initial selection via DT works */ + zassert_equal(devmux_select_get(devmux_dev), selected); + + return NULL; +} + +static void before(void *arg) +{ + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + zassert_ok(devmux_select_set(devmux_dev, 0)); + zassert_ok(devmux_select_get(devmux_dev)); + + for (size_t i = 1; i < ARRAY_SIZE(devs); ++i) { + uart_emul_flush_tx_data(devs[i]); + } +} + +ZTEST_SUITE(console_switching, NULL, setup, before, NULL, NULL); diff --git a/tests/drivers/console_switching/testcase.yaml b/tests/drivers/console_switching/testcase.yaml new file mode 100644 index 000000000000..0d24b5e596e6 --- /dev/null +++ b/tests/drivers/console_switching/testcase.yaml @@ -0,0 +1,16 @@ +common: + tags: + - drivers + - console + - emul + platform_allow: + - qemu_riscv64 + integration_platforms: + - qemu_riscv64 + +tests: + drivers.console_switching: {} + drivers.console_switching.user: + tags: userspace + extra_configs: + - CONFIG_USERSPACE=y diff --git a/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay b/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay index eabb26ebda6f..a67f25e46c08 100644 --- a/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay +++ b/tests/drivers/flash/common/boards/nrf52840dk_mx25r_high_perf.overlay @@ -1,5 +1,9 @@ /delete-node/ &qspi; +&gpio0 { + gpio-reserved-ranges = <0 2>, <6 1>, <8 3>, <18 6>; +}; + &spi2 { compatible = "nordic,nrf-spim"; status = "okay"; diff --git a/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf new file mode 100644 index 000000000000..821a5e77e5b5 --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf b/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf new file mode 100644 index 000000000000..821a5e77e5b5 --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf b/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf new file mode 100644 index 000000000000..821a5e77e5b5 --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index 4e73617ba41e..79d75ca9b132 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -14,9 +14,6 @@ #define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor) #elif defined(CONFIG_SPI_NOR) #define TEST_AREA_DEV_NODE DT_INST(0, jedec_spi_nor) -#elif defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) -/* SoC embedded NVM */ -#define TEST_AREA slot1_ns_partition #else #define TEST_AREA storage_partition #endif diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index f7ee0b7fc6d0..88ce0a40e07d 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -21,7 +21,7 @@ tests: - OVERLAY_CONFIG=boards/nrf52840_flash_qspi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_mx25l51245g.overlay harness_config: - fixture: external_flash + fixture: external_flash_mx25l51245g integration_platforms: - nrf52840dk_nrf52840 drivers.flash.common.soc_flash_nrf: @@ -38,7 +38,7 @@ tests: drivers.flash.common.tfm_ns: build_only: true filter: (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE - and dt_label_with_parent_compat_enabled("slot1_ns_partition", "fixed-partitions")) + and dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions")) integration_platforms: - nrf9161dk_nrf9161_ns drivers.flash.common.stm32: @@ -78,11 +78,15 @@ tests: extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor.overlay + harness_config: + fixture: external_flash_mx25v1635f drivers.flash.common.spi_nor_wp_hold: platform_allow: nrf52840dk_nrf52840 extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_flash_spi.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_spi_nor_wp_hold.overlay + harness_config: + fixture: external_flash_mx25v1635f drivers.flash.common.sam0: platform_allow: - atsamd20_xpro diff --git a/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..97702240047c --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + + / { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio1 10 0>; + in-gpios = <&gpio1 11 0>; + }; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt new file mode 100644 index 000000000000..1079605a2b41 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(gpio_ite_it8xxx2_v2) + +target_include_directories(app PRIVATE + include +) + +zephyr_include_directories( + include + ${ZEPHYR_BASE}/soc/riscv/ite_ec/common + ${ZEPHYR_BASE}/soc/riscv/ite_ec/it8xxx2 +) + +target_sources(app + PRIVATE + src/main.c +) diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig new file mode 100644 index 000000000000..bb5e43e8e20b --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig @@ -0,0 +1,12 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config SOC_IT8XXX2_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN + bool + default n +config HAS_ITE_INTC + bool + default y diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay new file mode 100644 index 000000000000..7f22c83ffb11 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + intc: interrupt-controller@f03f00 { + compatible = "vnd,intc"; + #address-cells = <0>; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0x00f03f00 0x0100>; + }; + + gpioa: gpio@f01601 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01601 1 /* GPDR (set) */ + 0x00f01618 1 /* GPDMR (get) */ + 0x00f01630 1 /* GPOTR */ + 0x00f01648 1 /* P18SCR */ + 0x00f01660 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = <9 IRQ_TYPE_LEVEL_HIGH + 2 IRQ_TYPE_LEVEL_HIGH + 3 IRQ_TYPE_LEVEL_HIGH + 4 IRQ_TYPE_LEVEL_HIGH + 5 IRQ_TYPE_LEVEL_HIGH + 6 IRQ_TYPE_LEVEL_HIGH + 7 IRQ_TYPE_LEVEL_HIGH + 8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&intc>; + wuc-base = <0xf01b20 0xf01b20 0xf01b20 0xf01b1c + 0xf01b1c 0xf01b1c 0xf01b1c 0xf01b24>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; +}; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h new file mode 100644 index 000000000000..d3c1f7c827eb --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h @@ -0,0 +1,20 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <../soc/riscv/ite_ec/common/chip_chipregs.h> + +/* + * Macros for emulated hardware registers access. + */ +#undef ECREG +#undef ECREG_u16 +#undef ECREG_u32 +#define ECREG(x) (*((volatile unsigned char *)fake_ecreg((intptr_t)x))) +#define ECREG_u16(x) (*((volatile unsigned short *)fake_ecreg((intptr_t)x))) +#define ECREG_u32(x) (*((volatile unsigned long *)fake_ecreg((intptr_t)x))) + +unsigned int *fake_ecreg(intptr_t r); +uint8_t ite_intc_get_irq_num(void); diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h new file mode 100644 index 000000000000..ab921224676c --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags); +int arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags); +typedef struct z_thread_stack_element k_thread_stack_t; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf new file mode 100644 index 000000000000..cf7d90e583ca --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf @@ -0,0 +1,9 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_GPIO_ITE_IT8XXX2_V2=y +CONFIG_GPIO=y +CONFIG_DYNAMIC_INTERRUPTS=y +CONFIG_GPIO_GET_CONFIG=y diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c new file mode 100644 index 000000000000..4272fbe42f95 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c @@ -0,0 +1,460 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define MY_GPIO DT_NODELABEL(gpioa) + +const struct device *const gpio_dev = DEVICE_DT_GET(MY_GPIO); +static struct { + uint8_t fake; + uint8_t gpdmr; + uint8_t gpdr; + uint8_t gpotr; + uint8_t p18scr; + uint8_t wuemr, wuesr, wubemr; + uint8_t gpcr[DT_REG_SIZE_BY_IDX(MY_GPIO, 4)]; + bool clear_gpcr_before_read; +} registers; +static int callback_called; +static struct gpio_callback callback_struct; + +/* These values must match what is set in the dts overlay. */ +#define TEST_PIN 1 +#define TEST_IRQ DT_IRQ_BY_IDX(MY_GPIO, TEST_PIN, irq) +#define TEST_MASK DT_PROP_BY_IDX(MY_GPIO, wuc_mask, TEST_PIN) + +DEFINE_FFF_GLOBALS; + +uint8_t ite_intc_get_irq_num(void) +{ + return posix_get_current_irq(); +} + +unsigned int *fake_ecreg(intptr_t r) +{ + switch (r) { + case DT_REG_ADDR_BY_IDX(MY_GPIO, 0): /* GPDR */ + return (unsigned int *)®isters.gpdr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 1): /* GPDMR */ + return (unsigned int *)®isters.gpdmr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 2): /* GPOTR */ + return (unsigned int *)®isters.gpotr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 3): /* P18SCR */ + return (unsigned int *)®isters.p18scr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN): + return (unsigned int *)®isters.wuemr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN) + 1: + return (unsigned int *)®isters.wuesr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN) + 3: + return (unsigned int *)®isters.wubemr; + } + if (r >= DT_REG_ADDR_BY_IDX(MY_GPIO, 4) && + r < DT_REG_ADDR_BY_IDX(MY_GPIO, 4) + DT_REG_SIZE_BY_IDX(MY_GPIO, 4)) { + if (registers.clear_gpcr_before_read) { + registers.gpcr[r - DT_REG_ADDR_BY_IDX(MY_GPIO, 4)] = 0; + } + return (unsigned int *)®isters.gpcr[r - DT_REG_ADDR_BY_IDX(MY_GPIO, 4)]; + } + zassert_unreachable("Register access: %x", r); + return (unsigned int *)®isters.fake; +} + +static void callback(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) +{ + callback_called++; + zexpect_equal(pins, BIT(TEST_PIN)); +} + +static void before_test(void *fixture) +{ + callback_called = 0; + memset(®isters, 0, sizeof(registers)); +} + +static void after_test(void *fixture) +{ + if (callback_struct.handler != NULL) { + zassert_ok(gpio_remove_callback(gpio_dev, &callback_struct)); + } + callback_struct.handler = NULL; +} + +ZTEST_SUITE(gpio_ite_it8xxx2_v2, NULL, NULL, before_test, after_test, NULL); + +ZTEST(gpio_ite_it8xxx2_v2, test_get_active_high) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + zassert_false(gpio_pin_get(gpio_dev, TEST_PIN)); + registers.gpdmr = BIT(TEST_PIN); + zassert_true(gpio_pin_get(gpio_dev, TEST_PIN)); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_get_active_low) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_LOW)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + zassert_true(gpio_pin_get(gpio_dev, TEST_PIN)); + registers.gpdmr = BIT(TEST_PIN); + zassert_false(gpio_pin_get(gpio_dev, TEST_PIN)); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_rising) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_enable_disable) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + registers.gpdmr = 0; + + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_MODE_DISABLED)); + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt, should be ignored */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + /* Clear the missed interrupt */ + posix_sw_clear_pending_IRQ(TEST_IRQ); + registers.gpdmr = 0; + + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 2, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_falling) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_INACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, TEST_MASK, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_both) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_BOTH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, TEST_MASK, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, TEST_MASK, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + registers.gpdmr &= ~BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 2, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_level_active) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zassert_equal(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_LEVEL_ACTIVE), + -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, 0, "wuesr=%x", registers.wuesr); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_level_inactive) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zassert_equal(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_LEVEL_INACTIVE), + -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, 0, "wuesr=%x", registers.wuesr); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_set_active_high) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT_INACTIVE | GPIO_ACTIVE_HIGH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, true)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, false)); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_port_toggle_bits(gpio_dev, BIT(TEST_PIN))); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 0; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 255)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 255; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 0)); + zexpect_equal(registers.gpdr, (uint8_t)~BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + + registers.gpdr = BIT(TEST_PIN); + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_HIGH, "flags=%x", flags); + registers.gpdr = 0; + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_set_active_low) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT_INACTIVE | GPIO_ACTIVE_LOW)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, true)); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, false)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_port_toggle_bits(gpio_dev, BIT(TEST_PIN))); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + registers.gpdr = 255; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 255)); + zexpect_equal(registers.gpdr, (uint8_t)~BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 0; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 0)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + + registers.gpdr = 0; + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW, "flags=%x", flags); + registers.gpdr = BIT(TEST_PIN); + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_HIGH, "flags=%x", flags); +} + +/* The next few tests just verify that the registers are set as expected on configure. */ + +ZTEST(gpio_ite_it8xxx2_v2, test_open_source) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OPEN_SOURCE), -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], 0, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_open_drain_output) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT | GPIO_OPEN_DRAIN)); + zexpect_equal(registers.gpotr, BIT(TEST_PIN), "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW | GPIO_OPEN_DRAIN, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_pull_up_input) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_PULL_UP)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], + GPCR_PORT_PIN_MODE_INPUT | GPCR_PORT_PIN_MODE_PULLUP, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | GPIO_PULL_UP, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_pull_down_input) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_PULL_DOWN)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], + GPCR_PORT_PIN_MODE_INPUT | GPCR_PORT_PIN_MODE_PULLDOWN, "gpcr[%d]=%x", + TEST_PIN, registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | GPIO_PULL_DOWN, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_disconnected_tristate_supported) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_DISCONNECTED)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_TRISTATE, "gpcr[%d]=%x", + TEST_PIN, registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_PULL_UP | GPIO_PULL_DOWN | GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3, + "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_disconnected_tristate_unsupported) +{ + registers.clear_gpcr_before_read = true; + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_DISCONNECTED), -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_1P8V) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_1P8)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, BIT(TEST_PIN)); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_1P8, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_3P3V) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_5V) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_5P0), + -EINVAL); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], 0, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml new file mode 100644 index 000000000000..67cc43b474ba --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml @@ -0,0 +1,14 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +tests: + gpio.gpio_ite_it8xxx2_v2: + tags: + - drivers + - gpio + depends_on: gpio + platform_allow: + - native_sim + integration_platforms: + - native_sim diff --git a/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..8b82825a0f28 --- /dev/null +++ b/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* i2s-node0 is the transmitter/receiver */ + +/ { + aliases { + i2s-node0 = &i2s20; + }; +}; + +&pinctrl { + i2s20_default_alt: i2s20_default_alt { + group1 { + psels = , + , + , + ; + }; + }; +}; + +&i2s20 { + status = "okay"; + pinctrl-0 = <&i2s20_default_alt>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..8b82825a0f28 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* i2s-node0 is the transmitter/receiver */ + +/ { + aliases { + i2s-node0 = &i2s20; + }; +}; + +&pinctrl { + i2s20_default_alt: i2s20_default_alt { + group1 { + psels = , + , + , + ; + }; + }; +}; + +&i2s20 { + status = "okay"; + pinctrl-0 = <&i2s20_default_alt>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..f2e84b72f9b3 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spi00_default: spi00_default { + group1 { + psels = , + , + ; + }; + }; + + spi00_sleep: spi00_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; + +&spi00 { + status = "okay"; + pinctrl-0 = <&spi00_default>; + pinctrl-1 = <&spi00_sleep>; + pinctrl-names = "default", "sleep"; + overrun-character = <0x00>; + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = ; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = ; + }; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..033aab401ac0 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + chosen { + zephyr,console = &uart20; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/drivers/uart/uart_async_api/testcase.yaml b/tests/drivers/uart/uart_async_api/testcase.yaml index e9914d48d99c..3c5f2d5583e9 100644 --- a/tests/drivers/uart/uart_async_api/testcase.yaml +++ b/tests/drivers/uart/uart_async_api/testcase.yaml @@ -13,6 +13,7 @@ tests: harness_config: fixture: gpio_loopback depends_on: gpio + tags: bsim_skip_CI drivers.uart.wide: filter: CONFIG_UART_CONSOLE and CONFIG_SERIAL_SUPPORT_ASYNC and not CONFIG_UART_MCUX_LPUART harness: ztest @@ -25,6 +26,15 @@ tests: platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi + drivers.uart.async_api.nrf_uarte_legacy: + platform_allow: nrf52840dk_nrf52840 nrf52_bsim + filter: CONFIG_SERIAL_SUPPORT_ASYNC + harness: ztest + harness_config: + fixture: gpio_loopback + depends_on: gpio + extra_configs: + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.async_api.nrf_uart: filter: CONFIG_UART_CONSOLE and CONFIG_SERIAL_SUPPORT_ASYNC harness: ztest diff --git a/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..945b8628e7a6 --- /dev/null +++ b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; + hw-flow-control; +}; + +counter_dev: &timer00 { + status = "okay"; +}; + +&grtc { + interrupts = <228 2>; +}; diff --git a/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml b/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml index 65848e6603ee..c2196c1058d5 100644 --- a/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml +++ b/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml @@ -18,22 +18,22 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_fifo: extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=y - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_async_api: extra_configs: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_async_api_const: extra_args: TEST_CONST_BUFFER=1 @@ -41,22 +41,9 @@ tests: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - - CONFIG_UART_0_ENHANCED_POLL_OUT=n - - CONFIG_UART_ASYNC_TX_CACHE_SIZE=2 - - drivers.uart.uart_mix_poll_async_api_low_power: - extra_configs: - - CONFIG_UART_ASYNC_API=y - - CONFIG_UART_0_INTERRUPT_DRIVEN=n - - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_0_TX_CACHE_SIZE=2 + tags: bsim_skip_CI # We skip a few tests to save CI time, as they give little extra coverage drivers.uart.uart_mix_poll_with_ppi: extra_configs: @@ -75,18 +62,29 @@ tests: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=y - drivers.uart.uart_mix_poll_async_api_with_ppi_low_power: + drivers.uart.legacy.uart_mix_poll: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=n + - CONFIG_UART_ASYNC_API=n + - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y + + drivers.uart.legacy.uart_mix_poll_fifo: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + - CONFIG_UART_0_INTERRUPT_DRIVEN=y + - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y + + drivers.uart.legacy.uart_mix_poll_async_api: extra_configs: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y + - CONFIG_UART_0_ENHANCED_POLL_OUT=n - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y diff --git a/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..033aab401ac0 --- /dev/null +++ b/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + chosen { + zephyr,console = &uart20; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/drivers/uart/uart_pm/testcase.yaml b/tests/drivers/uart/uart_pm/testcase.yaml index efb76ecf2c14..4d71ed881cd2 100644 --- a/tests/drivers/uart/uart_pm/testcase.yaml +++ b/tests/drivers/uart/uart_pm/testcase.yaml @@ -13,12 +13,14 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.no_rxpin: extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y extra_args: DTC_OVERLAY_FILE="boards/nrf52840dk_nrf52840.overlay;nrf_rx_disable.overlay" drivers.uart.pm.enhanced_poll: @@ -26,6 +28,7 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.int_driven: extra_configs: @@ -33,6 +36,7 @@ tests: - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.int_driven.enhanced_poll: extra_configs: @@ -40,6 +44,7 @@ tests: - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.async: extra_configs: @@ -50,6 +55,7 @@ tests: - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.async.enhanced_poll: extra_configs: @@ -60,3 +66,4 @@ tests: - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 000000000000..aa2789dd45e8 --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt30 { + status = "okay"; +}; diff --git a/tests/kernel/context/src/main.c b/tests/kernel/context/src/main.c index 2e3ad1a36c9e..a138e012280d 100644 --- a/tests/kernel/context/src/main.c +++ b/tests/kernel/context/src/main.c @@ -72,11 +72,10 @@ extern const int32_t z_sys_timer_irq_for_test; #endif -/* Cortex-M1, Nios II, and RISCV without CONFIG_RISCV_HAS_CPU_IDLE - * do have a power saving instruction, so k_cpu_idle() returns immediately +/* Cortex-M1 and Nios II do have a power saving instruction, so k_cpu_idle() + * returns immediately */ -#if !defined(CONFIG_CPU_CORTEX_M1) && !defined(CONFIG_NIOS2) && \ - (!defined(CONFIG_RISCV) || defined(CONFIG_RISCV_HAS_CPU_IDLE)) +#if !defined(CONFIG_CPU_CORTEX_M1) && !defined(CONFIG_NIOS2) #define HAS_POWERSAVE_INSTRUCTION #endif diff --git a/tests/kernel/gen_isr_table/testcase.yaml b/tests/kernel/gen_isr_table/testcase.yaml index cd8c95e2584e..4ee3ad00ac9c 100644 --- a/tests/kernel/gen_isr_table/testcase.yaml +++ b/tests/kernel/gen_isr_table/testcase.yaml @@ -53,7 +53,7 @@ tests: platform_exclude: - m2gl025_miv - adp_xc7k_ae350 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_GEN_IRQ_VECTOR_TABLE=y arch.interrupt.gen_isr_table.riscv_no_direct: @@ -61,18 +61,18 @@ tests: arch_allow: - riscv32 - riscv64 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_GEN_IRQ_VECTOR_TABLE=n arch.interrupt.gen_isr_table.bit_shift_2nd_level: platform_allow: qemu_riscv32 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_1ST_LEVEL_INTERRUPT_BITS=10 - CONFIG_2ND_LEVEL_INTERRUPT_BITS=10 arch.interrupt.gen_isr_table.bit_shift_3rd_level: platform_allow: qemu_riscv32 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_MULTI_LEVEL_INTERRUPTS=y - CONFIG_2ND_LEVEL_INTERRUPTS=y diff --git a/tests/kernel/sched/schedule_api/prj.conf b/tests/kernel/sched/schedule_api/prj.conf index fe5125047e32..785e9a3987ba 100644 --- a/tests/kernel/sched/schedule_api/prj.conf +++ b/tests/kernel/sched/schedule_api/prj.conf @@ -7,3 +7,4 @@ CONFIG_MAX_THREAD_BYTES=5 CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/kernel/sched/schedule_api/prj_dumb.conf b/tests/kernel/sched/schedule_api/prj_dumb.conf index c0ddfbd7c3fe..a1d0cf6dced3 100644 --- a/tests/kernel/sched/schedule_api/prj_dumb.conf +++ b/tests/kernel/sched/schedule_api/prj_dumb.conf @@ -5,3 +5,4 @@ CONFIG_SCHED_DUMB=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/kernel/sched/schedule_api/prj_multiq.conf b/tests/kernel/sched/schedule_api/prj_multiq.conf index 18d04dd8656f..77b3a49fd34f 100644 --- a/tests/kernel/sched/schedule_api/prj_multiq.conf +++ b/tests/kernel/sched/schedule_api/prj_multiq.conf @@ -5,3 +5,4 @@ CONFIG_SCHED_MULTIQ=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index 77d1b06dbb2e..d1a7235a84cf 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -34,6 +34,11 @@ tests: # -std=c++98) cpp.main.cpp98: arch_exclude: posix + # Exclude nRF54L15 and nRF54H20 as Nordic HAL is not compatible with C++98. + platform_exclude: + - nrf54l15pdk_nrf54l15_cpuapp + - nrf54h20pdk_nrf54h20_cpuapp + - nrf54h20pdk_nrf54h20_cpurad build_only: true extra_configs: - CONFIG_STD_CPP98=y diff --git a/tests/lib/newlib/heap_listener/prj.conf b/tests/lib/newlib/heap_listener/prj.conf index e5a5dc6df4c1..7282777ff1ca 100644 --- a/tests/lib/newlib/heap_listener/prj.conf +++ b/tests/lib/newlib/heap_listener/prj.conf @@ -1,3 +1,4 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n CONFIG_NEWLIB_LIBC_HEAP_LISTENER=y diff --git a/tests/misc/iterable_sections/CMakeLists.txt b/tests/misc/iterable_sections/CMakeLists.txt index 24472eb85749..1a187eace6d8 100644 --- a/tests/misc/iterable_sections/CMakeLists.txt +++ b/tests/misc/iterable_sections/CMakeLists.txt @@ -12,9 +12,11 @@ zephyr_iterable_section(NAME test_ram GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} zephyr_iterable_section(NAME test_ram2 GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME test_ram_named GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME test_ram_numeric NUMERIC GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +zephyr_iterable_section(NAME ramn_alt GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_linker_sources(SECTIONS sections-rom.ld) zephyr_iterable_section(NAME test_rom KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom2 KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom_named KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom_numeric NUMERIC KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) +zephyr_iterable_section(NAME romn_alt KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) diff --git a/tests/misc/iterable_sections/sections-ram.ld b/tests/misc/iterable_sections/sections-ram.ld index c7c86a8d97c8..96454fb282d6 100644 --- a/tests/misc/iterable_sections/sections-ram.ld +++ b/tests/misc/iterable_sections/sections-ram.ld @@ -4,3 +4,4 @@ ITERABLE_SECTION_RAM(test_ram, 4) ITERABLE_SECTION_RAM(test_ram2, 4) ITERABLE_SECTION_RAM(test_ram_named, 4) ITERABLE_SECTION_RAM_NUMERIC(test_ram_numeric, 4) +ITERABLE_SECTION_RAM(ramn_alt, 4) diff --git a/tests/misc/iterable_sections/sections-rom.ld b/tests/misc/iterable_sections/sections-rom.ld index c837cbfbc4b1..525c480c7bf7 100644 --- a/tests/misc/iterable_sections/sections-rom.ld +++ b/tests/misc/iterable_sections/sections-rom.ld @@ -4,3 +4,4 @@ ITERABLE_SECTION_ROM(test_rom, 4) ITERABLE_SECTION_ROM(test_rom2, 4) ITERABLE_SECTION_ROM(test_rom_named, 4) ITERABLE_SECTION_ROM_NUMERIC(test_rom_numeric, 4) +ITERABLE_SECTION_ROM(romn_alt, 4) diff --git a/tests/misc/iterable_sections/src/main.c b/tests/misc/iterable_sections/src/main.c index e5d697b8a807..a2dde51bd23f 100644 --- a/tests/misc/iterable_sections/src/main.c +++ b/tests/misc/iterable_sections/src/main.c @@ -44,6 +44,12 @@ const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_10) = {0x03}; const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_11) = {0x04}; const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_3) = {0x02}; +#define NAMED_ALT_EXPECT 0x4273 + +/* alternate naming */ +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, R, ramn_42) = {0x42}; +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, W, ramn_73) = {0x73}; + /** * * @brief Test iterable in read write section. @@ -89,6 +95,13 @@ ZTEST(iterable_sections, test_ram) } zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%x)", out); + + out = 0; + STRUCT_SECTION_FOREACH_ALTERNATE(ramn_alt, test_ram_named, t) { + out = (out << 8) | t->i; + } + + zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out); } struct test_rom { @@ -126,6 +139,10 @@ const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_10) = {0x30}; const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_11) = {0x40}; const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_3) = {0x20}; +/* alternate naming */ +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, R, romn_73) = {0x73}; +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, O, romn_42) = {0x42}; + /** * * @brief Test iterable in read only section. @@ -161,6 +178,13 @@ ZTEST(iterable_sections, test_rom) } zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out); + + out = 0; + STRUCT_SECTION_FOREACH_ALTERNATE(romn_alt, test_rom_named, t) { + out = (out << 8) | t->i; + } + + zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out); } ZTEST_SUITE(iterable_sections, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/lib/coap/src/main.c b/tests/net/lib/coap/src/main.c index c9d0456d3329..d1903dea10c1 100644 --- a/tests/net/lib/coap/src/main.c +++ b/tests/net/lib/coap/src/main.c @@ -779,7 +779,7 @@ ZTEST(coap, test_retransmit_second_round) zassert_not_null(pending, "No free pending"); r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, - CONFIG_COAP_MAX_RETRANSMIT); + NULL); zassert_equal(r, 0, "Could not initialize packet"); /* We "send" the packet the first time here */ @@ -1718,4 +1718,57 @@ ZTEST(coap, test_coap_packet_set_path) COAP_OPTION_URI_PATH); } +ZTEST(coap, test_transmission_parameters) +{ + struct coap_packet cpkt; + struct coap_pending *pending; + struct coap_transmission_parameters params; + uint8_t *data = data_buf[0]; + int r; + uint16_t id; + + params = coap_get_transmission_parameters(); + zassert_equal(params.ack_timeout, CONFIG_COAP_INIT_ACK_TIMEOUT_MS, "Wrong ACK timeout"); + zassert_equal(params.coap_backoff_percent, CONFIG_COAP_BACKOFF_PERCENT, + "Wrong backoff percent"); + zassert_equal(params.max_retransmission, CONFIG_COAP_MAX_RETRANSMIT, + "Wrong max retransmission value"); + + params.ack_timeout = 1000; + params.coap_backoff_percent = 150; + params.max_retransmission = 2; + + coap_set_transmission_parameters(¶ms); + + id = coap_next_id(); + + r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, + COAP_TYPE_CON, 0, coap_next_token(), + COAP_METHOD_GET, id); + zassert_equal(r, 0, "Could not initialize packet"); + + pending = coap_pending_next_unused(pendings, NUM_PENDINGS); + zassert_not_null(pending, "No free pending"); + + params.ack_timeout = 3000; + params.coap_backoff_percent = 250; + params.max_retransmission = 3; + + r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, + ¶ms); + zassert_equal(r, 0, "Could not initialize packet"); + + zassert_equal(pending->params.ack_timeout, 3000, "Wrong ACK timeout"); + zassert_equal(pending->params.coap_backoff_percent, 250, "Wrong backoff percent"); + zassert_equal(pending->params.max_retransmission, 3, "Wrong max retransmission value"); + + r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, + NULL); + zassert_equal(r, 0, "Could not initialize packet"); + + zassert_equal(pending->params.ack_timeout, 1000, "Wrong ACK timeout"); + zassert_equal(pending->params.coap_backoff_percent, 150, "Wrong backoff percent"); + zassert_equal(pending->params.max_retransmission, 2, "Wrong max retransmission value"); +} + ZTEST_SUITE(coap, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/lib/coap_client/CMakeLists.txt b/tests/net/lib/coap_client/CMakeLists.txt index 2e94112f0b06..cb86d78f611c 100644 --- a/tests/net/lib/coap_client/CMakeLists.txt +++ b/tests/net/lib/coap_client/CMakeLists.txt @@ -27,3 +27,5 @@ add_compile_definitions(CONFIG_COAP_LOG_LEVEL=4) add_compile_definitions(CONFIG_COAP_INIT_ACK_TIMEOUT_MS=200) add_compile_definitions(CONFIG_COAP_CLIENT_MAX_REQUESTS=2) add_compile_definitions(CONFIG_COAP_CLIENT_MAX_INSTANCES=2) +add_compile_definitions(CONFIG_COAP_MAX_RETRANSMIT=4) +add_compile_definitions(CONFIG_COAP_BACKOFF_PERCENT=200) diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index e1240c5e2ed4..7d99c738950c 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -378,7 +378,7 @@ ZTEST(coap_client, test_get_request) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -409,7 +409,7 @@ ZTEST(coap_client, test_resend_request) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(300)); set_socket_events(ZSOCK_POLLIN); @@ -441,7 +441,7 @@ ZTEST(coap_client, test_echo_option) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -472,7 +472,7 @@ ZTEST(coap_client, test_echo_option_next_req) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -487,7 +487,7 @@ ZTEST(coap_client, test_echo_option_next_req) client_request.len = strlen(payload); LOG_INF("Send next request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -516,7 +516,7 @@ ZTEST(coap_client, test_get_no_path) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_equal(ret, -EINVAL, "Get request without path"); } @@ -541,7 +541,7 @@ ZTEST(coap_client, test_send_large_data) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -563,6 +563,11 @@ ZTEST(coap_client, test_no_response) .payload = NULL, .len = 0 }; + struct coap_transmission_parameters params = { + .ack_timeout = 200, + .coap_backoff_percent = 200, + .max_retransmission = 0 + }; client_request.payload = short_payload; client_request.len = strlen(short_payload); @@ -571,7 +576,7 @@ ZTEST(coap_client, test_no_response) LOG_INF("Send request"); clear_socket_events(); - ret = coap_client_req(&client, 0, &address, &client_request, 0); + ret = coap_client_req(&client, 0, &address, &client_request, ¶ms); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(300)); @@ -601,7 +606,7 @@ ZTEST(coap_client, test_separate_response) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -632,10 +637,10 @@ ZTEST(coap_client, test_multiple_requests) set_socket_events(ZSOCK_POLLIN); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(5)); @@ -660,6 +665,11 @@ ZTEST(coap_client, test_unmatching_tokens) .payload = NULL, .len = 0 }; + struct coap_transmission_parameters params = { + .ack_timeout = 200, + .coap_backoff_percent = 200, + .max_retransmission = 0 + }; client_request.payload = short_payload; client_request.len = strlen(short_payload); @@ -667,7 +677,7 @@ ZTEST(coap_client, test_unmatching_tokens) z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_unmatching; LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, 0); + ret = coap_client_req(&client, 0, &address, &client_request, ¶ms); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -675,4 +685,5 @@ ZTEST(coap_client, test_unmatching_tokens) k_sleep(K_MSEC(1)); clear_socket_events(); k_sleep(K_MSEC(500)); + zassert_equal(last_response_code, -ETIMEDOUT, "Unexpected response"); } diff --git a/tests/net/lib/coap_server/common/src/main.c b/tests/net/lib/coap_server/common/src/main.c index 7af940c53609..20c4b7c03177 100644 --- a/tests/net/lib/coap_server/common/src/main.c +++ b/tests/net/lib/coap_server/common/src/main.c @@ -48,7 +48,7 @@ COAP_RESOURCE_DEFINE(resource_1, service_A, { }); static uint16_t service_B_port; -COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, COAP_SERVICE_AUTOSTART); +COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, 0); static const char * const resource_2_path[] = { "res2", "sub", NULL }; COAP_RESOURCE_DEFINE(resource_2, service_B, { @@ -132,7 +132,7 @@ ZTEST(coap_service, test_COAP_SERVICE_FOREACH) zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART); } else if (svc == &service_B) { have_service_B = 1; - zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART); + zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0); } else if (svc == &service_C) { have_service_C = 1; zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0); diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md index bda38924d266..7df931203aad 100644 --- a/tests/net/lib/lwm2m/interop/README.md +++ b/tests/net/lib/lwm2m/interop/README.md @@ -125,9 +125,17 @@ Tests are written from test spec; |---------|------|-----| |LightweightM2M-1.1-int-0 - Client Initiated Bootstrap |:white_check_mark:| | |LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK) |:white_check_mark:| | +|LightweightM2M-1.1-int-2 - Client Initiated Bootstrap Full (Cert) | |testcase not implemented | +|LightweightM2M-1.1-int-3 – Simple Bootstrap from Smartcard |:large_orange_diamond:|We don't have any smartcard support.| +|LightweightM2M-1.1-int-4 - Bootstrap Delete |:white_check_mark:| | +|LightweightM2M-1.1-int-5 - Server Initiated Bootstrap |:white_check_mark:| | +|LightweightM2M-1.1-int-6 - Bootstrap Sequence |:white_check_mark:| | +|LightweightM2M-1.1-int-7 - Fallback to bootstrap |:white_check_mark:| | +|LightweightM2M-1.1-int-8 - Bootstrap Read | |Test cannot be implemented from client side.| +|LightweightM2M-1.1-int-9 - Bootstrap and Configuration Consistency | |testcase not implemented | |LightweightM2M-1.1-int-101 - Initial Registration |:white_check_mark:| | |LightweightM2M-1.1-int-102 - Registration Update |:white_check_mark:| | -|LightweightM2M-1.1-int-103 - Deregistration |:large_orange_diamond:|We don't have "disabled" functionality in server object| +|LightweightM2M-1.1-int-103 - Deregistration |:white_check_mark:| | |LightweightM2M-1.1-int-104 - Registration Update Trigge |:white_check_mark:| | |LightweightM2M-1.1-int-105 - Discarded Register Update |:white_check_mark:| | |LightweightM2M-1.1-int-107 - Extending the lifetime of a registration |:white_check_mark:| | @@ -160,21 +168,21 @@ Tests are written from test spec; |LightweightM2M-1.1-int-232 - Querying basic information in SenML CBOR format|:white_check_mark:| | |LightweightM2M-1.1-int-233 - Setting basic information in SenML CBOR format|:white_check_mark:| | |LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format|:white_check_mark:| | -|LightweightM2M-1.1-int-235 - Read-Composite Operation on root path|:large_orange_diamond:|Root Path is not yet supported by Leshan.| +|LightweightM2M-1.1-int-235 - Read-Composite Operation on root path|:white_check_mark:| | |LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence|:white_check_mark:| | |LightweightM2M-1.1-int-237 - Read on Object without specifying Content-Type|:white_check_mark:| | |LightweightM2M-1.1-int-241 - Executable Resource: Rebooting the device|:white_check_mark:| | |LightweightM2M-1.1-int-256 - Write Operation Failure|:white_check_mark:| | |LightweightM2M-1.1-int-257 - Write-Composite Operation|:white_check_mark:| | |LightweightM2M-1.1-int-260 - Discover Command|:white_check_mark:| | -|LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource|:large_orange_diamond:|Leshan don't allow writing attributes to resource instance| +|LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource|:white_check_mark:| | |LightweightM2M-1.1-int-280 - Successful Read-Composite Operation|:white_check_mark:| | |LightweightM2M-1.1-int-281 - Partially Successful Read-Composite Operation|:white_check_mark:| | |LightweightM2M-1.1-int-301 - Observation and Notification of parameter values|:white_check_mark:| | |LightweightM2M-1.1-int-302 - Cancel Observations using Reset Operation|:white_check_mark:| | -|LightweightM2M-1.1-int-303 - Cancel observations using Observe with Cancel parameter|:large_orange_diamond:|Leshan only supports passive cancelling| +|LightweightM2M-1.1-int-303 - Cancel observations using Observe with Cancel parameter|:white_check_mark:|| |LightweightM2M-1.1-int-304 - Observe-Composite Operation|:white_check_mark:| | -|LightweightM2M-1.1-int-305 - Cancel Observation-Composite Operation|:large_orange_diamond:|Leshan only supports passive cancelling| +|LightweightM2M-1.1-int-305 - Cancel Observation-Composite Operation|:white_check_mark:| | |LightweightM2M-1.1-int-306 – Send Operation|:white_check_mark:|[~~#64290~~](https://github.com/zephyrproject-rtos/zephyr/issues/64290)| |LightweightM2M-1.1-int-307 – Muting Send|:white_check_mark:| | |LightweightM2M-1.1-int-308 - Observe-Composite and Creating Object Instance|:white_check_mark:|[~~#64634~~](https://github.com/zephyrproject-rtos/zephyr/issues/64634)| diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 07bd9a0535d1..6115e6f40e38 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -18,6 +18,9 @@ CONFIG_LWM2M=y CONFIG_LWM2M_IPSO_SUPPORT=y CONFIG_LWM2M_SHELL=y +CONFIG_LWM2M_TICKLESS=y +CONFIG_NET_SOCKETPAIR=y + #Enable Portfolio object CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y @@ -44,6 +47,11 @@ CONFIG_LWM2M_RW_OMA_TLV_SUPPORT=y CONFIG_COAP_EXTENDED_OPTIONS_LEN=y CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 +# Speed up testing, we are running in non-lossy network +CONFIG_COAP_INIT_ACK_TIMEOUT_MS=1000 +CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT=n +CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES=2 + # Use QUEUE mode by default CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 diff --git a/tests/net/lib/lwm2m/interop/pytest/conftest.py b/tests/net/lib/lwm2m/interop/pytest/conftest.py index 9ca971b85c7c..7d3ea4e7f808 100644 --- a/tests/net/lib/lwm2m/interop/pytest/conftest.py +++ b/tests/net/lib/lwm2m/interop/pytest/conftest.py @@ -27,6 +27,25 @@ logger = logging.getLogger(__name__) +class Endpoint: + def __init__(self, name: str, shell: Shell, registered: bool = False, bootstrap: bool = False): + self.name = name + self.registered = registered + self.bootstrap = bootstrap + self.shell = shell + self.last_update = 0.0 + + def check_update(self): + if not self.registered: + return + if self.last_update < time.time() - 5: + self.shell.exec_command('lwm2m update') + self.last_update = time.time() + + def __str__(self): + return self.name + + @pytest.fixture(scope='session') def leshan() -> Leshan: """ @@ -89,9 +108,8 @@ def endpoint_nosec(shell: Shell, dut: DeviceAdapter, leshan: Leshan) -> str: shell.exec_command('lwm2m write 1/0/0 -u16 1') shell.exec_command('lwm2m write 1/0/1 -u32 86400') shell.exec_command(f'lwm2m start {ep} -b 0') - dut.readlines_until(regex=f"RD Client started with endpoint '{ep}'", timeout=10.0) - yield ep + yield Endpoint(ep, shell) # All done shell.exec_command('lwm2m stop') @@ -125,7 +143,7 @@ def endpoint_bootstrap(shell: Shell, dut: DeviceAdapter, leshan: Leshan, leshan_ shell.exec_command(f'lwm2m write 0/0/5 -s {bs_passwd}') shell.exec_command(f'lwm2m start {ep} -b 1') - yield ep + yield Endpoint(ep, shell) shell.exec_command('lwm2m stop') dut.readlines_until(regex=r'.*Deregistration success', timeout=10.0) @@ -137,12 +155,16 @@ def endpoint_bootstrap(shell: Shell, dut: DeviceAdapter, leshan: Leshan, leshan_ leshan_bootstrap.delete_bs_device(ep) @pytest.fixture(scope='module') -def endpoint_registered(endpoint_bootstrap, shell: Shell, dut: DeviceAdapter) -> str: +def endpoint_registered(endpoint_bootstrap, dut: DeviceAdapter) -> str: """Fixture that returns an endpoint that is registered.""" - dut.readlines_until(regex='.*Registration Done', timeout=5.0) + if not endpoint_bootstrap.registered: + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + endpoint_bootstrap.bootstrap = True + endpoint_bootstrap.registered = True return endpoint_bootstrap -@pytest.fixture(scope='module') +@pytest.fixture(scope='function') def endpoint(endpoint_registered) -> str: """Fixture that returns an endpoint that is registered.""" + endpoint_registered.check_update() return endpoint_registered diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index 7240aae2baf8..181f15ebf613 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -62,9 +62,9 @@ def get(self, path: str): resp = self._s.get(f'{self.api_url}{path}', params=params, timeout=self.timeout) return Leshan.handle_response(resp) - def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None): + def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None, params: dict | None = None): """Send HTTP PUT query without any default parameters""" - resp = self._s.put(f'{self.api_url}{path}', data=data, headers=headers, timeout=self.timeout) + resp = self._s.put(f'{self.api_url}{path}', data=data, headers=headers, params=params, timeout=self.timeout) return Leshan.handle_response(resp) def put(self, path: str, data: str | dict, uri_options: str = ''): @@ -108,6 +108,21 @@ def write(self, endpoint: str, path: str, value: bool | int | str): rid = path.split('/')[-1] return self.put(f'/clients/{endpoint}/{path}', self._define_resource(rid, value, kind)) + def write_attributes(self, endpoint: str, path: str, attributes: dict): + """Send LwM2M Write-Attributes to given path + example: + leshan.write_attributes(endpoint, '1/2/3, {'pmin': 10, 'pmax': 40}) + """ + return self.put_raw(f'/clients/{endpoint}/{path}/attributes', params=attributes) + + def remove_attributes(self, endpoint: str, path: str, attributes: list): + """Send LwM2M Write-Attributes to given path + example: + leshan.remove_attributes(endpoint, '1/2/3, ['pmin', 'pmax']) + """ + attrs = '&'.join(attributes) + return self.put_raw(f'/clients/{endpoint}/{path}/attributes?'+ attrs) + def update_obj_instance(self, endpoint: str, path: str, resources: dict): """Update object instance""" data = self._define_obj_inst(path, resources) @@ -256,6 +271,10 @@ def parse_composite(cls, payload: dict): raise RuntimeError(f'No content received') payload = payload['content'] for path, content in payload.items(): + if path == "/": + for obj in content['objects']: + data.update(cls._decode_obj(obj)) + continue keys = [int(key) for key in path.lstrip("/").split('/')] if len(keys) == 1: data.update(cls._decode_obj(content)) @@ -370,6 +389,9 @@ def observe(self, endpoint: str, path: str): return self.post(f'/clients/{endpoint}/{path}/observe', data="") def cancel_observe(self, endpoint: str, path: str): + return self.delete_raw(f'/clients/{endpoint}/{path}/observe?active') + + def passive_cancel_observe(self, endpoint: str, path: str): return self.delete_raw(f'/clients/{endpoint}/{path}/observe') def composite_observe(self, endpoint: str, paths: list[str]): @@ -379,6 +401,10 @@ def composite_observe(self, endpoint: str, paths: list[str]): return self.parse_composite(payload) def cancel_composite_observe(self, endpoint: str, paths: list[str]): + paths = [path if path.startswith('/') else '/' + path for path in paths] + return self.delete_raw(f'/clients/{endpoint}/composite/observe?paths=' + ','.join(paths) + '&active') + + def passive_cancel_composite_observe(self, endpoint: str, paths: list[str]): paths = [path if path.startswith('/') else '/' + path for path in paths] return self.delete_raw(f'/clients/{endpoint}/composite/observe?paths=' + ','.join(paths)) diff --git a/tests/net/lib/lwm2m/interop/pytest/pytest.ini b/tests/net/lib/lwm2m/interop/pytest/pytest.ini new file mode 100644 index 000000000000..761785364d83 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +markers = + slow: marks tests as slow (deselect with '-m "not slow"') diff --git a/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py index 65561db06767..2a45669d912a 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py @@ -15,9 +15,11 @@ """ import logging +import pytest from leshan import Leshan from twister_harness import Shell from twister_harness import DeviceAdapter +from conftest import Endpoint logger = logging.getLogger(__name__) @@ -29,24 +31,69 @@ # Bootstrap Interface: [0-99] # -def verify_LightweightM2M_1_1_int_0(shell: Shell, dut: DeviceAdapter): +def verify_LightweightM2M_1_1_int_0(dut: DeviceAdapter, endpoint_bootstrap: Endpoint): """LightweightM2M-1.1-int-0 - Client Initiated Bootstrap""" - dut.readlines_until(regex='.*Bootstrap started with endpoint', timeout=5.0) - dut.readlines_until(regex='.*Bootstrap registration done', timeout=5.0) - dut.readlines_until(regex='.*Bootstrap data transfer done', timeout=5.0) + dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0) + endpoint_bootstrap.bootstrap = True -def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: str): +def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: Endpoint): """LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)""" - verify_LightweightM2M_1_1_int_0(shell, dut) + verify_LightweightM2M_1_1_int_0(dut, endpoint_bootstrap) verify_LightweightM2M_1_1_int_101(shell, dut, leshan, endpoint_bootstrap) verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint_bootstrap) -def verify_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): +def test_LightweightM2M_1_1_int_4(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): + """LightweightM2M-1.1-int-4 - Bootstrap Delete""" + shell.exec_command('lwm2m create 1/2') + shell.exec_command('lwm2m read 1/2/0') + retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0]) + assert retval == 0 + leshan.execute(endpoint, '1/0/9') + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + shell.exec_command('lwm2m read 1/2/0') + retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0]) + assert retval < 0 + logger.info('retval: %s', retval) + +def test_LightweightM2M_1_1_int_5(dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): + """LightweightM2M-1.1-int-5 - Server Initiated Bootstrap""" + leshan.execute(endpoint, '1/0/9') + dut.readlines_until(regex='.*Server Initiated Bootstrap', timeout=1) + dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0) + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + +def test_LightweightM2M_1_1_int_6(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint): + """LightweightM2M-1.1-int-6 - Bootstrap Sequence""" + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert not any("Bootstrap" in line for line in lines) + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command("lwm2m delete 1/0") + shell.exec_command("lwm2m delete 0/1") + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert any("Bootstrap" in line for line in lines) + +@pytest.mark.slow +def test_LightweightM2M_1_1_int_7(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint): + """LightweightM2M-1.1-int-7 - Fallback to bootstrap""" + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command('lwm2m write 0/1/0 -s coaps://10.10.10.10:5684') + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=600.0) + assert any("Bootstrap" in line for line in lines) + +def verify_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): """LightweightM2M-1.1-int-101 - Initial Registration""" dut.readlines_until(regex='.*Registration Done', timeout=5.0) assert leshan.get(f'/clients/{endpoint}') + endpoint.registered = True -def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): +def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: Endpoint): """LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode""" lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s')) host = lines[0] diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index 8f3acd69c7e3..4e0ae207e8df 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -44,6 +44,17 @@ def test_LightweightM2M_1_1_int_102(shell: Shell, dut: DeviceAdapter, leshan: Le assert latest["lifetime"] == lifetime shell.exec_command('lwm2m write 1/0/1 -u32 86400') +def test_LightweightM2M_1_1_int_103(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-103 - Deregistration""" + leshan.execute(endpoint, '1/0/4') + dut.readlines_until(regex='LwM2M server disabled', timeout=5.0) + dut.readlines_until(regex='Deregistration success', timeout=5.0) + # Reset timers by restarting the client + shell.exec_command('lwm2m stop') + time.sleep(1) + shell.exec_command(f'lwm2m start {endpoint}') + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + def test_LightweightM2M_1_1_int_104(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-104 - Registration Update Trigger""" shell.exec_command('lwm2m update') @@ -51,6 +62,7 @@ def test_LightweightM2M_1_1_int_104(shell: Shell, dut: DeviceAdapter, leshan: Le leshan.execute(endpoint, '1/0/8') dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) +@pytest.mark.slow def test_LightweightM2M_1_1_int_107(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-107 - Extending the lifetime of a registration""" leshan.write(endpoint, '1/0/1', 120) @@ -66,6 +78,7 @@ def test_LightweightM2M_1_1_int_108(leshan, endpoint): """LightweightM2M-1.1-int-108 - Turn on Queue Mode""" assert leshan.get(f'/clients/{endpoint}')["queuemode"] +@pytest.mark.slow def test_LightweightM2M_1_1_int_109(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-109 - Behavior in Queue Mode""" logger.debug('Wait for Queue RX OFF') @@ -169,6 +182,7 @@ def verify_setting_basic_in_format(shell, leshan, endpoint, format): verify_server_object(server_obj) # Remove Read-Only resources, so we don't end up writing those del server_obj[0][0] + del server_obj[0][13] data = { 2: 101, 3: 1010, @@ -200,13 +214,13 @@ def test_LightweightM2M_1_1_int_221(shell: Shell, leshan: Leshan, endpoint: str) """LightweightM2M-1.1-int-221 - Attempt to perform operations on Security""" assert leshan.read(endpoint, '0/0')['status'] == 'UNAUTHORIZED(401)' assert leshan.write(endpoint, '0/0/0', 'coap://localhost')['status'] == 'UNAUTHORIZED(401)' - assert leshan.put_raw(f'/clients/{endpoint}/0/attributes?pmin=10')['status'] == 'UNAUTHORIZED(401)' + assert leshan.write_attributes(endpoint, '0', {'pmin':10})['status'] == 'UNAUTHORIZED(401)' def test_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-222 - Read on Object""" resp = leshan.read(endpoint, '1') assert len(resp) == 1 - assert len(resp[1][0]) == 9 + assert len(resp[1][0]) == 11 resp = leshan.read(endpoint, '3') assert len(resp) == 1 assert len(resp[3]) == 1 @@ -216,7 +230,7 @@ def test_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str) def test_LightweightM2M_1_1_int_223(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-223 - Read on Object Instance""" resp = leshan.read(endpoint, '1/0') - assert len(resp[0]) == 9 + assert len(resp[0]) == 11 resp = leshan.read(endpoint, '3/0') assert len(resp[0]) == 15 assert resp[0][0] == 'Zephyr' @@ -280,7 +294,7 @@ def test_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: str) assert resp[3] is not None assert resp[1][0] is not None assert len(resp[3][0]) == 15 - assert len(resp[1][0]) == 9 + assert len(resp[1][0]) == 11 resp = leshan.composite_read(endpoint, ['1/0/1', '/3/0/11/0']) logger.debug(resp) @@ -365,9 +379,12 @@ def test_LightweightM2M_1_1_int_234(shell: Shell, leshan: Leshan, endpoint: str) """LightweightM2M-1.1-int-234 - Setting basic information in SenML JSON format""" setting_basic_senml(shell, leshan, endpoint, 'SENML_JSON') -@pytest.mark.skip("Leshan does not allow reading root path") -def test_LightweightM2M_1_1_int_235(): +def test_LightweightM2M_1_1_int_235(leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-235 - Read-Composite Operation on root path""" + resp = leshan.composite_read(endpoint, ['/']) + expected_keys = [1, 3, 5] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 def test_LightweightM2M_1_1_int_236(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence""" @@ -427,15 +444,12 @@ def test_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str) expected_keys = ['/3', '/3/0', '/3/0/1', '/3/0/2', '/3/0/3', '/3/0/4', '/3/0/6', '/3/0/7', '/3/0/8', '/3/0/9', '/3/0/11', '/3/0/16'] missing_keys = [key for key in expected_keys if key not in resp.keys()] assert len(missing_keys) == 0 - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=10')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=200')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3', {'pmin': 10, 'pmax': 200})['status'] == 'CHANGED(204)' resp = leshan.discover(endpoint, '3/0') assert int(resp['/3/0/6']['dim']) == 2 assert int(resp['/3/0/7']['dim']) == 2 assert int(resp['/3/0/8']['dim']) == 2 - assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?lt=1')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?gt=6')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?st=1')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0/7', {'lt': 1, 'gt': 6, 'st': 1})['status'] == 'CHANGED(204)' resp = leshan.discover(endpoint, '3/0') expected_keys = ['/3/0', '/3/0/1', '/3/0/2', '/3/0/3', '/3/0/4', '/3/0/6', '/3/0/7', '/3/0/8', '/3/0/9', '/3/0/11', '/3/0/16'] missing_keys = [key for key in expected_keys if key not in resp.keys()] @@ -449,8 +463,9 @@ def test_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str) missing_keys = [key for key in expected_keys if key not in resp.keys()] assert len(missing_keys) == 0 assert len(resp) == len(expected_keys) + # restore + leshan.remove_attributes(endpoint, '3', ['pmin', 'pmax']) -@pytest.mark.skip(reason="Leshan don't allow writing attributes to resource instance") def test_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-261 - Write-Attribute Operation on a multiple resource""" resp = leshan.discover(endpoint, '3/0/11') @@ -460,19 +475,20 @@ def test_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str) assert len(missing_keys) == 0 assert len(resp) == len(expected_keys) assert int(resp['/3/0/11']['dim']) == 1 - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=10')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=200')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/attributes?pmax=320')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?pmax=100')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?epmin=1')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/11/0/attributes?epmax=20')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3', {'pmin':10, 'pmax':200})['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0', {'pmax':320})['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0/11/0', {'pmax':100, 'epmin':1, 'epmax':20})['status'] == 'CHANGED(204)' resp = leshan.discover(endpoint, '3/0/11') logger.debug(resp) assert int(resp['/3/0/11']['pmin']) == 10 assert int(resp['/3/0/11']['pmax']) == 320 assert int(resp['/3/0/11/0']['pmax']) == 100 - assert int(resp['/3/0/11/0']['epmin']) == 1 - assert int(resp['/3/0/11/0']['epmax']) == 20 + # Note: Zephyr does not support epmin&epmax. + # Restore + leshan.remove_attributes(endpoint, '3', ['pmin', 'pmax']) + leshan.remove_attributes(endpoint, '3/0', ['pmax']) + leshan.remove_attributes(endpoint, '3/0/11/0', ['pmax']) + def test_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-280 - Successful Read-Composite Operation""" @@ -500,14 +516,14 @@ def test_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str) # Information Reporting Interface [300-399] # +@pytest.mark.slow def test_LightweightM2M_1_1_int_301(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-301 - Observation and Notification of parameter values""" pwr_src = leshan.read(endpoint, '3/0/6') logger.debug(pwr_src) assert pwr_src[6][0] == 1 assert pwr_src[6][1] == 5 - assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?pmin=5')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/3/0/7/attributes?pmax=10')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0/7', {'pmin': 5, 'pmax': 10})['status'] == 'CHANGED(204)' leshan.observe(endpoint, '3/0/7') with leshan.get_event_stream(endpoint, timeout=30) as events: shell.exec_command('lwm2m write /3/0/7/0 -u32 3000') @@ -526,6 +542,7 @@ def test_LightweightM2M_1_1_int_301(shell: Shell, leshan: Leshan, endpoint: str) assert data[3][0][7][0] == 3500 assert (start + 15) <= time.time() + 1 # Allow 1 second slack. (pMinx + pMax=15) leshan.cancel_observe(endpoint, '3/0/7') + leshan.remove_attributes(endpoint, '3/0/7', ['pmin', 'pmax']) def test_LightweightM2M_1_1_int_302(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-302 - Cancel Observations using Reset Operation""" @@ -535,21 +552,41 @@ def test_LightweightM2M_1_1_int_302(shell: Shell, dut: DeviceAdapter, leshan: Le shell.exec_command('lwm2m write /3/0/7/0 -u32 4000') data = events.next_event('NOTIFICATION') assert data[3][0][7][0] == 4000 - leshan.cancel_observe(endpoint, '3/0/7') + leshan.passive_cancel_observe(endpoint, '3/0/7') shell.exec_command('lwm2m write /3/0/7/0 -u32 3000') dut.readlines_until(regex=r'.*Observer removed for 3/0/7') with leshan.get_event_stream(endpoint) as events: shell.exec_command('lwm2m write /3/0/8/0 -u32 100') data = events.next_event('NOTIFICATION') assert data[3][0][8][0] == 100 - leshan.cancel_observe(endpoint, '3/0/8') + leshan.passive_cancel_observe(endpoint, '3/0/8') shell.exec_command('lwm2m write /3/0/8/0 -u32 50') dut.readlines_until(regex=r'.*Observer removed for 3/0/8') +def test_LightweightM2M_1_1_int_303(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-303 - Cancel observations using Observe with Cancel parameter""" + leshan.observe(endpoint, '3/0/7') + leshan.observe(endpoint, '3/0/8') + with leshan.get_event_stream(endpoint) as events: + shell.exec_command('lwm2m write /3/0/7/0 -u32 4000') + data = events.next_event('NOTIFICATION') + assert data[3][0][7][0] == 4000 + leshan.cancel_observe(endpoint, '3/0/7') + dut.readlines_until(regex=r'.*Observer removed for 3/0/7') + with leshan.get_event_stream(endpoint) as events: + shell.exec_command('lwm2m write /3/0/8/0 -u32 100') + data = events.next_event('NOTIFICATION') + assert data[3][0][8][0] == 100 + leshan.cancel_observe(endpoint, '3/0/8') + dut.readlines_until(regex=r'.*Observer removed for 3/0/8') + +@pytest.mark.slow def test_LightweightM2M_1_1_int_304(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-304 - Observe-Composite Operation""" - assert leshan.put_raw(f'/clients/{endpoint}/1/0/1/attributes?pmin=30')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/1/0/1/attributes?pmax=45')['status'] == 'CHANGED(204)' + # Need to use Configuration C.1 + shell.exec_command('lwm2m write 1/0/2 -u32 0') + shell.exec_command('lwm2m write 1/0/3 -u32 0') + assert leshan.write_attributes(endpoint, '1/0/1', {'pmin': 30, 'pmax': 45})['status'] == 'CHANGED(204)' data = leshan.composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) assert data[1][0][1] is not None assert data[3][0][11][0] is not None @@ -570,6 +607,18 @@ def test_LightweightM2M_1_1_int_304(shell: Shell, leshan: Leshan, endpoint: str) assert (start + 30) < time.time() assert (start + 45) > time.time() - 1 leshan.cancel_composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + # Restore configuration C.3 + shell.exec_command('lwm2m write 1/0/2 -u32 1') + shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '1/0/1', ['pmin', 'pmax']) + +def test_LightweightM2M_1_1_int_305(dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-305 - Cancel Observation-Composite Operation""" + leshan.composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + leshan.cancel_composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + dut.readlines_until(regex=r'.*Observer removed for 1/0/1') + dut.readlines_until(regex=r'.*Observer removed for 3/0/11/0') + dut.readlines_until(regex=r'.*Observer removed for 3/0/16') def test_LightweightM2M_1_1_int_306(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-306 - Send Operation""" @@ -590,6 +639,8 @@ def test_LightweightM2M_1_1_int_307(shell: Shell, dut: DeviceAdapter, leshan: Le shell.exec_command('lwm2m send /3/0') dut.readlines_until(regex=r'.*SEND status: 0', timeout=5.0) + +@pytest.mark.slow def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-308 - Observe-Composite and Creating Object Instance""" shell.exec_command('lwm2m delete /16/0') @@ -613,8 +664,7 @@ def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Le content_both = {16: {0: resources_a, 1: resources_b}} assert leshan.create_obj_instance(endpoint, '16/0', resources_a)['status'] == 'CREATED(201)' dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmin=30')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmax=45')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '16/0', {'pmin': 30, 'pmax': 45})['status'] == 'CHANGED(204)' data = leshan.composite_observe(endpoint, ['/16/0', '/16/1']) assert data == content_one with leshan.get_event_stream(endpoint, timeout=50) as events: @@ -630,7 +680,9 @@ def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Le # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '16/0', ['pmin','pmax']) +@pytest.mark.slow def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-309 - Observe-Composite and Deleting Object Instance""" shell.exec_command('lwm2m delete /16/0') @@ -655,8 +707,7 @@ def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Le assert leshan.create_obj_instance(endpoint, '16/0', resources_a)['status'] == 'CREATED(201)' assert leshan.create_obj_instance(endpoint, '16/1', resources_b)['status'] == 'CREATED(201)' dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) - assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmin=30')['status'] == 'CHANGED(204)' - assert leshan.put_raw(f'/clients/{endpoint}/16/0/attributes?pmax=45')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '16/0', {'pmin': 30, 'pmax': 45})['status'] == 'CHANGED(204)' data = leshan.composite_observe(endpoint, ['/16/0', '/16/1']) assert data == content_both with leshan.get_event_stream(endpoint, timeout=50) as events: @@ -672,17 +723,17 @@ def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Le # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '16/0', ['pmin', 'pmax']) +@pytest.mark.slow def test_LightweightM2M_1_1_int_310(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-310 - Observe-Composite and modification of parameter values""" # Need to use Configuration C.1 shell.exec_command('lwm2m write 1/0/2 -u32 0') shell.exec_command('lwm2m write 1/0/3 -u32 0') - # Ensure that our previous attributes are not conflicting - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmin=0')['status'] == 'CHANGED(204)' leshan.composite_observe(endpoint, ['/1/0/1', '/3/0']) with leshan.get_event_stream(endpoint, timeout=50) as events: - assert leshan.put_raw(f'/clients/{endpoint}/3/attributes?pmax=5')['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3', {'pmax': 5})['status'] == 'CHANGED(204)' start = time.time() data = events.next_event('NOTIFICATION') assert data[3][0][0] == 'Zephyr' @@ -695,6 +746,7 @@ def test_LightweightM2M_1_1_int_310(shell: Shell, leshan: Leshan, endpoint: str) # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '3', ['pmax']) def test_LightweightM2M_1_1_int_311(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-311 - Send command""" diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 706091659a59..a150f1b41cbf 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -73,6 +73,17 @@ int set_socketoptions(struct lwm2m_ctx *ctx) ret = -errno; LOG_ERR("Failed to enable TLS_DTLS_CID: %d", ret); } + + /* Allow DTLS handshake to timeout much faster. + * these tests run on TUN/TAP network, so there should be no network latency. + */ + uint32_t min = 100; + uint32_t max = 500; + + zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_HANDSHAKE_TIMEOUT_MIN, &min, + sizeof(min)); + zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_HANDSHAKE_TIMEOUT_MAX, &max, + sizeof(max)); } return lwm2m_set_default_sockopt(ctx); } @@ -119,6 +130,10 @@ static void rd_client_event(struct lwm2m_ctx *client, /* do nothing */ break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_DBG("LwM2M server disabled"); + break; + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: LOG_DBG("Bootstrap registration failure!"); break; diff --git a/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf b/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf new file mode 100644 index 000000000000..c735e1a8a2d6 --- /dev/null +++ b/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf @@ -0,0 +1 @@ +CONFIG_TEST_EXTRA_STACK_SIZE=1024 diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c index ed26380eccd4..5d80f5d1049f 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c @@ -13,10 +13,11 @@ #include "lwm2m_rd_client.h" #include "stubs.h" -#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) #include "timer_model.h" #endif +#define LOG_LEVEL LOG_LEVEL_DBG LOG_MODULE_REGISTER(lwm2m_engine_test); DEFINE_FFF_GLOBALS; @@ -67,7 +68,7 @@ static void test_service(struct k_work *work) static void setup(void *data) { -#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) /* It is enough that some slow-down is happening on sleeps, it does not have to be * real time */ @@ -467,3 +468,70 @@ ZTEST(lwm2m_engine, test_security) zassert_equal(tls_credential_add_fake.arg1_history[2], TLS_CREDENTIAL_CA_CERTIFICATE); zassert_equal(lwm2m_engine_stop(&ctx), 0); } + +static enum lwm2m_socket_states last_state; + +static void socket_state(int fd, enum lwm2m_socket_states state) +{ + (void) fd; + last_state = state; +} + +ZTEST(lwm2m_engine, test_socket_state) +{ + int ret; + struct lwm2m_ctx ctx = { + .remote_addr.sa_family = AF_INET, + .sock_fd = -1, + .set_socket_state = socket_state, + }; + struct lwm2m_message msg1 = { + .ctx = &ctx, + .type = COAP_TYPE_CON, + }; + struct lwm2m_message msg2 = msg1; + struct lwm2m_message ack = { + .ctx = &ctx, + .type = COAP_TYPE_ACK, + }; + + sys_slist_init(&ctx.pending_sends); + ret = lwm2m_engine_start(&ctx); + zassert_equal(ret, 0); + + /* One confimable in queue, should cause ONE_RESPONSE status */ + coap_pendings_count_fake.return_val = 1; + sys_slist_append(&ctx.pending_sends, &msg1.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONE_RESPONSE); + + /* More than one messages in queue, not empty, should cause ONGOING */ + coap_pendings_count_fake.return_val = 2; + sys_slist_append(&ctx.pending_sends, &msg1.node); + sys_slist_append(&ctx.pending_sends, &msg2.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING); + + /* Last out, while waiting for ACK to both, should still cause ONGOING */ + coap_pendings_count_fake.return_val = 2; + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING); + + /* Only one Ack transmiting, nothing expected back -> LAST */ + coap_pendings_count_fake.return_val = 0; + sys_slist_append(&ctx.pending_sends, &ack.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_LAST); + + /* Socket suspended (as in QUEUE_RX_OFF), should cause NO_DATA */ + ret = lwm2m_socket_suspend(&ctx); + zassert_equal(ret, 0); + zassert_equal(last_state, LWM2M_SOCKET_STATE_NO_DATA); + + ret = lwm2m_engine_stop(&ctx); + zassert_equal(ret, 0); +} diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 5db155f1e290..0958d75a54a7 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -19,6 +19,7 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *); DEFINE_FAKE_VOID_FUNC(lwm2m_registry_lock); DEFINE_FAKE_VOID_FUNC(lwm2m_registry_unlock); DEFINE_FAKE_VALUE_FUNC(bool, coap_pending_cycle, struct coap_pending *); +DEFINE_FAKE_VALUE_FUNC(size_t, coap_pendings_count, struct coap_pending *, size_t); DEFINE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct observe_node *, void *); DEFINE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t, @@ -41,6 +42,7 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t); DEFINE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t); +DEFINE_FAKE_VOID_FUNC(engine_update_tx_time); static sys_slist_t obs_obj_path_list = SYS_SLIST_STATIC_INIT(&obs_obj_path_list); sys_slist_t *lwm2m_obs_obj_path_list(void) diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h index 7b8ca481f851..67c4cde883de 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h @@ -28,6 +28,7 @@ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_resume); DECLARE_FAKE_VALUE_FUNC(struct lwm2m_message *, find_msg, struct coap_pending *, struct coap_reply *); DECLARE_FAKE_VOID_FUNC(coap_pending_clear, struct coap_pending *); +DECLARE_FAKE_VALUE_FUNC(size_t, coap_pendings_count, struct coap_pending *, size_t); DECLARE_FAKE_VOID_FUNC(lwm2m_reset_message, struct lwm2m_message *, bool); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *); DECLARE_FAKE_VOID_FUNC(lwm2m_registry_lock); @@ -56,6 +57,7 @@ DECLARE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, socklen_t); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t); +DECLARE_FAKE_VOID_FUNC(engine_update_tx_time); #define DO_FOREACH_FAKE(FUNC) \ do { \ @@ -63,6 +65,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void FUNC(lwm2m_rd_client_resume) \ FUNC(find_msg) \ FUNC(coap_pending_clear) \ + FUNC(coap_pendings_count) \ FUNC(lwm2m_reset_message) \ FUNC(lwm2m_send_message_async) \ FUNC(lwm2m_registry_lock) \ @@ -85,6 +88,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void FUNC(z_impl_zsock_connect) \ FUNC(lwm2m_security_mode) \ FUNC(z_impl_zsock_setsockopt) \ + FUNC(engine_update_tx_time) \ } while (0) #endif /* STUBS_H */ diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 931f6f15904e..1d6a4e584faf 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -21,7 +21,7 @@ DEFINE_FFF_GLOBALS; /* Maximum number of iterations within the state machine of RD Client * service that is waited for until a possible event occurs */ -static const uint8_t RD_CLIENT_MAX_LOOKUP_ITERATIONS = 100; +#define RD_CLIENT_MAX_LOOKUP_ITERATIONS 500 FAKE_VOID_FUNC(show_lwm2m_event, enum lwm2m_rd_client_event); FAKE_VOID_FUNC(show_lwm2m_observe, enum lwm2m_observe_event); @@ -97,6 +97,9 @@ static void lwm2m_event_cb(struct lwm2m_ctx *client, enum lwm2m_rd_client_event case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF"); break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_INF("*** LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED"); + break; case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED"); break; @@ -165,6 +168,7 @@ static void my_suite_before(void *data) lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; coap_packet_append_option_fake.custom_fake = NULL; + stub_lwm2m_server_disable(false); } static void my_suite_after(void *data) @@ -198,8 +202,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -207,6 +209,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -228,8 +231,6 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -237,6 +238,7 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -249,14 +251,13 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -273,16 +274,17 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_timeout_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); - zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR), NULL); } ZTEST(lwm2m_rd_client, test_start_registration_fail) @@ -291,8 +293,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -302,8 +302,15 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), + NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR), + NULL); } ZTEST(lwm2m_rd_client, test_start_registration_update) @@ -312,8 +319,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -321,6 +326,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -335,8 +341,6 @@ ZTEST(lwm2m_rd_client, test_rx_off) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -344,6 +348,7 @@ ZTEST(lwm2m_rd_client, test_rx_off) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -359,8 +364,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -368,6 +371,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -384,8 +388,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -393,6 +395,7 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); test_prepare_pending_message_cb(&message_reply_timeout_cb_default); @@ -415,8 +418,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -424,6 +425,7 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -439,8 +441,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -449,6 +449,8 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) coap_packet_append_option_fake.custom_fake = NULL; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -482,8 +484,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -491,6 +491,7 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); zassert_true(!lwm2m_rd_client_is_suspended(&ctx), NULL); @@ -517,8 +518,6 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -527,6 +526,7 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); zassert_true(lwm2m_rd_client_pause() == 0, NULL); @@ -544,8 +544,6 @@ ZTEST(lwm2m_rd_client, test_socket_error) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -554,6 +552,7 @@ ZTEST(lwm2m_rd_client, test_socket_error) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -569,8 +568,6 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -579,6 +576,7 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -608,8 +606,6 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -617,6 +613,7 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; @@ -638,8 +635,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_timeout_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -651,6 +646,7 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), NULL); } @@ -661,8 +657,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -674,27 +668,224 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), NULL); } -ZTEST(lwm2m_rd_client, test_bootstrap_no_srv_fallback_to_register) +ZTEST(lwm2m_rd_client, test_bootstrap_no_srv) { struct lwm2m_ctx ctx; (void)memset(&ctx, 0x0, sizeof(ctx)); + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; - zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server_stop) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), + NULL); + wait_for_service(1); + zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server_connect) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), + NULL); + + wait_for_service(500); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + stub_lwm2m_server_disable(false); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_fallback_to_bootstrap) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_no_srv_fallback_to_bootstrap) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_changed; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; + stub_lwm2m_server_disable(true); + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + stub_lwm2m_server_disable(false); + engine_bootstrap_finish(); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_start_stop_ignore_engine_fault) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + test_prepare_pending_message_cb(&message_reply_cb_default); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_engine_context_init_fake.custom_fake = lwm2m_engine_context_init_fake1; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default; + lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default; + lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); + + int c = show_lwm2m_event_fake.call_count; + + test_throw_network_error_from_engine(EIO); + wait_for_service(10); + zassert_equal(show_lwm2m_event_fake.call_count, c, + "Should not enter any other state and throw an event"); +} + +ZTEST(lwm2m_rd_client, test_start_suspend_ignore_engine_fault) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + test_prepare_pending_message_cb(&message_reply_cb_default); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_engine_context_init_fake.custom_fake = lwm2m_engine_context_init_fake1; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default; + lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default; + lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + zassert_true(lwm2m_rd_client_pause() == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED), NULL); + + int c = show_lwm2m_event_fake.call_count; + + test_throw_network_error_from_engine(EIO); + wait_for_service(10); + zassert_equal(show_lwm2m_event_fake.call_count, c, + "Should not enter any other state and throw an event"); } diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index 41789e203405..621057f84969 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -86,6 +86,10 @@ int lwm2m_get_u32_val(const struct lwm2m_obj_path *path, uint32_t *val) /* subsys/net/lib/lwm2m/lwm2m_engine.h */ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); +int lwm2m_socket_start_fake_fail(struct lwm2m_ctx *client_ctx) +{ + return -1; +} DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); @@ -93,6 +97,16 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_init, struct lwm2m_ctx *); +struct lwm2m_ctx *client_ctx_fake; +void lwm2m_engine_context_init_fake1(struct lwm2m_ctx *client_ctx) +{ + client_ctx_fake = client_ctx; +} +void test_throw_network_error_from_engine(int err) +{ + client_ctx_fake->fault_cb(err); +} + DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *); char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr) @@ -102,6 +116,24 @@ char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr) DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t); +DEFINE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t); +DEFINE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps); + +static bool srv_disabled; +bool lwm2m_server_select(uint16_t *obj_inst_id) +{ + if (obj_inst_id) { + *obj_inst_id = 0; + } + return !srv_disabled; +} + +void stub_lwm2m_server_disable(bool disable) +{ + srv_disabled = disable; +} k_work_handler_t service; int64_t next; @@ -163,9 +195,13 @@ void test_lwm2m_engine_start_service(void) void test_lwm2m_engine_stop_service(void) { + struct k_work_sync sync; + pending_message_cb = NULL; + pending_message = NULL; running = false; k_work_cancel(&service_work); + k_work_flush(&service_work, &sync); } /* subsys/net/lib/lwm2m/lwm2m_message_handling.h */ diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h index 620e4d8fc124..0a3ce31d9e84 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h @@ -54,21 +54,31 @@ int lwm2m_get_u32_val(const struct lwm2m_obj_path *path, uint32_t *val); /* subsys/net/lib/lwm2m/lwm2m_engine.h */ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); +int lwm2m_socket_start_fake_fail(struct lwm2m_ctx *client_ctx); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_init, struct lwm2m_ctx *); +void lwm2m_engine_context_init_fake1(struct lwm2m_ctx *client_ctx); +void test_throw_network_error_from_engine(int err); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *); char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); -DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t); +DECLARE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t); +DECLARE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps); + + void wait_for_service(uint16_t cycles); void test_lwm2m_engine_start_service(void); void test_lwm2m_engine_stop_service(void); +void stub_lwm2m_server_disable(bool disable); /* subsys/net/lib/lwm2m/lwm2m_message_handling.h */ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_init_message, struct lwm2m_message *); diff --git a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c index d4c0a7757a6b..8e99f666b7f2 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -203,16 +203,6 @@ ZTEST(lwm2m_registry, test_get_set) zassert_equal(strlen(buf), 0); } -ZTEST(lwm2m_registry, test_missing_u64) -{ - /* This data type is missing, so use S64 resource instead */ - uint64_t u64 = 123; - - zassert_equal(lwm2m_set_u64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), u64), 0); - zassert_equal(lwm2m_get_u64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), &u64), 0); - zassert_equal(u64, 123); -} - ZTEST(lwm2m_registry, test_temp_sensor) { int ret; diff --git a/tests/subsys/jwt/src/tls_config/user-tls-conf.h b/tests/subsys/jwt/src/tls_config/user-tls-conf.h index 035f2b062ecb..0d95ee80ac09 100644 --- a/tests/subsys/jwt/src/tls_config/user-tls-conf.h +++ b/tests/subsys/jwt/src/tls_config/user-tls-conf.h @@ -3,3 +3,4 @@ #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE #define MBEDTLS_PLATFORM_TIME_ALT +#define MBEDTLS_PLATFORM_MS_TIME_ALT diff --git a/tests/subsys/llext/hello_world/CMakeLists.txt b/tests/subsys/llext/hello_world/CMakeLists.txt index 1a16d4be26b5..6519075e2f4e 100644 --- a/tests/subsys/llext/hello_world/CMakeLists.txt +++ b/tests/subsys/llext/hello_world/CMakeLists.txt @@ -6,11 +6,26 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(hello_world) # TODO check which architecture is being used -set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb") +if(CONFIG_ARM) + set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb") -add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext - COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c -o ${PROJECT_BINARY_DIR}/hello_world.llext ${PROJECT_SOURCE_DIR}/hello_world.c -) + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c + -o ${PROJECT_BINARY_DIR}/hello_world.llext + ${PROJECT_SOURCE_DIR}/hello_world.c + ) +elseif(CONFIG_XTENSA) + set(CMAKE_C_FLAGS "-shared" "-fPIC" "-nostdlib" "-nodefaultlibs") + + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} + -o ${PROJECT_BINARY_DIR}/hello_world.pre.llext + ${PROJECT_SOURCE_DIR}/hello_world.c + COMMAND ${CROSS_COMPILE}strip -R .xt.* + -o ${PROJECT_BINARY_DIR}/hello_world.llext + ${PROJECT_BINARY_DIR}/hello_world.pre.llext + ) +endif() set(HELLO_WORLD_LLEXT ${PROJECT_BINARY_DIR}/hello_world.llext PARENT_SCOPE) diff --git a/tests/subsys/llext/src/test_llext_simple.c b/tests/subsys/llext/src/test_llext_simple.c index ef0e62b93b5a..557697f576c4 100644 --- a/tests/subsys/llext/src/test_llext_simple.c +++ b/tests/subsys/llext/src/test_llext_simple.c @@ -9,8 +9,11 @@ #include #include -#ifdef CONFIG_ARM /* ARMV7 */ -const static uint8_t hello_world_elf[] __aligned(4) = { +#if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA) +#ifndef CONFIG_LLEXT_STORAGE_WRITABLE +const +#endif +static uint8_t hello_world_elf[] __aligned(4) = { #include "hello_world.inc" }; #endif @@ -24,7 +27,7 @@ const static uint8_t hello_world_elf[] __aligned(4) = { */ ZTEST(llext, test_llext_simple) { - const char name[16] = {'h', 'e', 'l', 'l', 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const char name[16] = "hello"; struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(hello_world_elf, ARRAY_SIZE(hello_world_elf)); struct llext_loader *loader = &buf_loader.loader; diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index 79d8f5a1fd9a..2747edf8d0c8 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -9,3 +9,10 @@ tests: # Broken platforms platform_exclude: - nuvoton_pfm_m487 # See #63167 + llext.simple.xtensa: + arch_allow: xtensa + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=y + # Broken platforms + platform_exclude: + - qemu_xtensa_mmu # ELF sections are read-only, and without peek() .text copy isn't executable diff --git a/tests/subsys/logging/log_backend_uart/prj.conf b/tests/subsys/logging/log_backend_uart/prj.conf index ef6894f355ea..c8615a65adb4 100644 --- a/tests/subsys/logging/log_backend_uart/prj.conf +++ b/tests/subsys/logging/log_backend_uart/prj.conf @@ -9,3 +9,8 @@ CONFIG_LOG=y CONFIG_LOG_BACKEND_UART=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_PRINTK=n +# +# Disable all potential other default backends +CONFIG_LOG_BACKEND_NATIVE_POSIX=n +CONFIG_LOG_BACKEND_RTT=n +CONFIG_LOG_BACKEND_XTENSA_SIM=n diff --git a/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay index 394facef7bb2..30402e6e9d27 100644 --- a/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay +++ b/tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay @@ -1,34 +1,11 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + /* - * Pins 2 and 3 must be connected to each other on the STMOD+1 connector to - * loopback RX/TX. + * The Arduino D0 and D1 must be connected to each other to loopback RX/TX. */ -/ { - aliases { - test-uart = &usart2; - }; -}; - -&gpioh { - misc_fixed_usart2 { - gpio-hog; - gpios = <13 GPIO_ACTIVE_HIGH>; - output-high; - }; -}; - -&gpdma1 { - status = "okay"; -}; - -&usart2 { - pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3 &usart2_rts_pa1 &usart2_cts_pa0>; - pinctrl-names = "default"; - current-speed = <115200>; - - dmas = <&gpdma1 0 27 STM32_DMA_PERIPH_TX - &gpdma1 1 26 STM32_DMA_PERIPH_RX>; +dut: &usart3 { + dmas = <&gpdma1 0 29 STM32_DMA_PERIPH_TX + &gpdma1 1 28 STM32_DMA_PERIPH_RX>; dma-names = "tx", "rx"; - - status = "okay"; }; diff --git a/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay index 2d47b0f07442..777aebd8d3b9 100644 --- a/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -1,37 +1,31 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + /* - * Pins P1.10 and P1.11 must be connected to each other to loopback RX/TX. + * Pins P0.4 and P0.5 must be connected to each other to loopback RX/TX. */ -/ { - aliases { - test-uart = &uart1; - }; -}; - -&uart1 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&uart1_default>; - pinctrl-1 = <&uart1_sleep>; - hw-flow-control; - pinctrl-names = "default", "sleep"; -}; - &pinctrl { - uart1_default: uart1_default { + uart1_default_alt: uart1_default_alt { group1 { - psels = ; - }; - group2 { - psels = ; + psels = , + ; }; }; - uart1_sleep: uart1_sleep { + uart1_sleep_alt: uart1_sleep_alt { group1 { - psels = , - ; + psels = , + ; low-power-enable; }; }; }; + +dut: &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart1_default_alt>; + pinctrl-1 = <&uart1_sleep_alt>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/subsys/modem/backends/uart/src/main.c b/tests/subsys/modem/backends/uart/src/main.c index 8a6c4c2813a7..dffc203bb213 100644 --- a/tests/subsys/modem/backends/uart/src/main.c +++ b/tests/subsys/modem/backends/uart/src/main.c @@ -28,7 +28,7 @@ /*************************************************************************************************/ /* Mock pipe */ /*************************************************************************************************/ -static const struct device *uart = DEVICE_DT_GET(DT_ALIAS(test_uart)); +static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(dut)); static struct modem_backend_uart uart_backend; static struct modem_pipe *pipe; K_SEM_DEFINE(receive_ready_sem, 0, 1); diff --git a/tests/subsys/modem/backends/uart/testcase.yaml b/tests/subsys/modem/backends/uart/testcase.yaml index 626ca639f757..54d8a6b94703 100644 --- a/tests/subsys/modem/backends/uart/testcase.yaml +++ b/tests/subsys/modem/backends/uart/testcase.yaml @@ -1,21 +1,19 @@ # Copyright (c) 2023 Trackunit Corporation # SPDX-License-Identifier: Apache-2.0 +common: + harness: ztest + harness_config: + fixture: gpio_loopback + platform_allow: + - b_u585i_iot02a + - nrf5340dk_nrf5340_cpuapp + tests: modem.backends.uart.async: - tags: modem_backend - harness: ztest - platform_allow: - - b_u585i_iot02a - - nrf5340dk_nrf5340_cpuapp extra_configs: - CONFIG_UART_ASYNC_API=y modem.backends.uart.isr: - tags: modem_backend - harness: ztest - platform_allow: - - b_u585i_iot02a - - nrf5340dk_nrf5340_cpuapp extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/west.yml b/west.yml index 148471091948..df31231332b2 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 56e0b052dff311c2f8eb08c6804e60fc79feb56f + revision: b55cfbbf0221d709560c2e438beef66842ada272 path: modules/hal/nordic groups: - hal @@ -277,7 +277,7 @@ manifest: revision: 7c61a4cec26402d20c845c95dcad0e39dcd319f8 path: modules/lib/gui/lvgl - name: mbedtls - revision: 7053083b0cff8462464e3cbb826e87852fc03da6 + revision: 66ed2279d6222056af172c188eaf4dcfed481032 path: modules/crypto/mbedtls groups: - crypto @@ -295,13 +295,13 @@ manifest: groups: - tools - name: nrf_hw_models - revision: a715dcc179f1a71f51c574165958b72fe932ae3f + revision: 52d0b4b7b7431d8da6222cc3b17a8afdcb099baf path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread - revision: 193e77e40ec2387d458eaebd1e03902d86f484a5 + revision: 7761b81d23b10b3d5ee21b8504c67535cde10896 path: modules/lib/openthread - name: percepio path: modules/debug/percepio @@ -322,7 +322,7 @@ manifest: groups: - crypto - name: trusted-firmware-m - revision: 33c0f47bcb19721a5c33e6fe1eee9225d00bb5bc + revision: 58d0b5367f0fada9dbaddad1e08e302aeb044863 path: modules/tee/tf-m/trusted-firmware-m groups: - tee