diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 52d384e92fdf3f..d75e759499d4cc 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -34,7 +34,7 @@ jobs: runs-on: group: zephyr-runner-v2-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' env: ZEPHYR_TOOLCHAIN_VARIANT: zephyr diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 77a36a0c9317e8..95d68acf47a491 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -12,7 +12,7 @@ jobs: runs-on: group: zephyr-runner-v2-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' strategy: fail-fast: false diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 19c50aba9b4b9d..8bf4d2289ebd39 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -14,7 +14,7 @@ jobs: runs-on: group: zephyr-runner-v2-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' strategy: fail-fast: false diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index e8d53405257e93..c50625a1879eac 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -18,6 +18,9 @@ env: # so we fetch that through pip. CMAKE_VERSION: 3.20.5 DOXYGEN_VERSION: 1.9.6 + # Job count is set to 2 less than the vCPU count of 16 because the total available RAM is 32GiB + # and each sphinx-build process may use more than 2GiB of RAM. + JOB_COUNT: 14 jobs: doc-file-check: @@ -50,6 +53,8 @@ jobs: scripts/dts/ doc/requirements.txt .github/workflows/doc-build.yml + scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py + scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py doc-build-html: name: "Documentation Build (HTML)" @@ -130,7 +135,11 @@ jobs: else DOC_TARGET="html" fi - DOC_TAG=${DOC_TAG} SPHINXOPTS_EXTRA="-q -t publish" make -C doc ${DOC_TARGET} + + DOC_TAG=${DOC_TAG} \ + SPHINXOPTS="-j ${JOB_COUNT} -W --keep-going -T" \ + SPHINXOPTS_EXTRA="-q -t publish" \ + make -C doc ${DOC_TARGET} # API documentation coverage python3 -m coverxygen --xml-dir doc/_build/html/doxygen/xml/ --src-dir include/ --output doc-coverage.info @@ -208,7 +217,7 @@ jobs: - name: install-pkgs run: | apt-get update - apt-get install -y python3-pip python3-venv ninja-build doxygen graphviz librsvg2-bin + apt-get install -y python3-pip python3-venv ninja-build doxygen graphviz librsvg2-bin imagemagick - name: cache-pip uses: actions/cache@v4 @@ -243,7 +252,10 @@ jobs: DOC_TAG="development" fi - DOC_TAG=${DOC_TAG} SPHINXOPTS="-q -j auto" LATEXMKOPTS="-quiet -halt-on-error" make -C doc pdf + DOC_TAG=${DOC_TAG} \ + SPHINXOPTS="-q -j ${JOB_COUNT}" \ + LATEXMKOPTS="-quiet -halt-on-error" \ + make -C doc pdf - name: upload-build if: always() diff --git a/.github/workflows/errno.yml b/.github/workflows/errno.yml index 593fe916deb698..b1f7e6f4e62508 100644 --- a/.github/workflows/errno.yml +++ b/.github/workflows/errno.yml @@ -10,7 +10,7 @@ jobs: check-errno: runs-on: ubuntu-22.04 container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.11 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.13 steps: - name: Apply container owner mismatch workaround diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index ede9f52602eedf..5b39c94a9c0096 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -26,7 +26,7 @@ jobs: group: zephyr-runner-v2-linux-x64-4xlarge if: github.repository_owner == 'zephyrproject-rtos' container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' strategy: fail-fast: false diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 40f9fe04c2dde8..c2e44c830d05d5 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -25,7 +25,7 @@ jobs: runs-on: group: zephyr-runner-v2-linux-x64-4xlarge container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' outputs: subset: ${{ steps.output-services.outputs.subset }} @@ -129,7 +129,7 @@ jobs: needs: twister-build-prep if: needs.twister-build-prep.outputs.size != 0 container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.11.20240324 + image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601 options: '--entrypoint /bin/bash' strategy: fail-fast: false diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index edec21e28d393c..1176afc7299079 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -24,7 +24,7 @@ jobs: python-version: ['3.10', '3.11', '3.12'] os: [ubuntu-22.04] container: - image: ghcr.io/zephyrproject-rtos/ci:v0.26.11 + image: ghcr.io/zephyrproject-rtos/ci:v0.26.13 steps: - name: Apply Container Owner Mismatch Workaround diff --git a/.gitignore b/.gitignore index 053e78e3842311..66441114df2914 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,10 @@ *.swp *.swo *~ -.\#* + +# Emacs \#*\# + build*/ !doc/build/ !scripts/build @@ -27,6 +29,8 @@ outdir outdir-* scripts/basic/fixdep scripts/gen_idt/gen_idt +coverage-report +doc-coverage.info doc/_build doc/doxygen doc/xml @@ -53,6 +57,7 @@ venv .venv .DS_Store .clangd +new.info # CI output compliance.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index c6b173501495f9..d4dd40cf66f39f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,11 +111,6 @@ zephyr_library_named(zephyr) if(CONFIG_LEGACY_GENERATED_INCLUDE_PATH) zephyr_include_directories(${PROJECT_BINARY_DIR}/include/generated/zephyr) - message(WARNING " - Warning: CONFIG_LEGACY_GENERATED_INCLUDE_PATH is currently enabled by default - so that user applications can continue to use the legacy include paths for the - generated headers. This Kconfig will be deprecated and eventually removed in - the future releases.") endif() zephyr_include_directories( @@ -1888,6 +1883,21 @@ if(CONFIG_BUILD_OUTPUT_INFO_HEADER) ) endif() +if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) + #slidgen must be the first post-build command to be executed + #on the Zephyr ELF to ensure that all other commands, such as + #binary file generation, are operating on a preparated ELF. + list(PREPEND + post_build_commands + COMMAND ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/llext_prepare_exptab.py + --elf-file ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} + --slid-listing ${PROJECT_BINARY_DIR}/slid_listing.txt + -vvv + ) + +endif() + if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") set(check_init_priorities_input $,${BYPRODUCT_KERNEL_EXE_NAME},${BYPRODUCT_KERNEL_ELF_NAME}> @@ -2129,9 +2139,8 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -DAPPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} - -DINTERFACE_INCLUDE_DIRECTORIES="$,:>" + -DINTERFACE_INCLUDE_DIRECTORIES="$" -Dllext_edk_file=${llext_edk_file} - -DAUTOCONF_H=${AUTOCONF_H} -Dllext_cflags="${llext_edk_cflags}" -Dllext_edk_name=${CONFIG_LLEXT_EDK_NAME} -DWEST_TOPDIR=${WEST_TOPDIR} diff --git a/CODEOWNERS b/CODEOWNERS index ab9b5bd47559b0..0526619f0ad29c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -26,8 +26,6 @@ /soc/arm/infineon_xmc/ @parthitce /soc/arm/silabs_exx32/efm32pg1b/ @rdmeneze /soc/arm/silabs_exx32/efr32mg21/ @l-alfred -/soc/arm/st_stm32/ @erwango -/soc/arm/st_stm32/*/power.c @FRASTM /soc/arm/st_stm32/stm32mp1/ @arnopo /soc/arm/st_stm32/stm32h7/*stm32h735* @benediktibk /soc/arm/st_stm32/stm32l4/*stm32l451* @benediktibk @@ -55,8 +53,6 @@ /boards/arm/acn52832/ @sven-hm /boards/arm/arduino_mkrzero/ @soburi /boards/arm/bbc_microbit_v2/ @LingaoM -/boards/arm/bl5340_dvk/ @lairdjm -/boards/arm/bl65*/ @lairdjm /boards/arm/blackpill_f401ce/ @coderkalyan /boards/arm/blackpill_f411ce/ @coderkalyan /boards/arm/bt*10/ @greg-leach @@ -67,7 +63,6 @@ /boards/arm/cy8ckit_062s4/ @DaWei8823 /boards/arm/cy8ckit_062_wifi_bt/ @ifyall @npal-cy /boards/arm/cy8cproto_062_4343w/ @ifyall @npal-cy -/boards/arm/disco_l475_iot1/ @erwango /boards/arm/efm32pg_stk3401a/ @rdmeneze /boards/arm/faze/ @mbittan @simonguinot /boards/arm/frdm*/ @mmahadevan108 @dleach02 @@ -77,7 +72,6 @@ /boards/arm/ip_k66f/ @parthitce @lmajewski /boards/arm/legend/ @mbittan @simonguinot /boards/arm/lpcxpresso*/ @mmahadevan108 @dleach02 -/boards/arm/mg100/ @rerickson1 /boards/arm/mimx8mm_evk/ @Mani-Sadhasivam /boards/arm/mimx8mm_phyboard_polis @pefech /boards/arm/mimxrt*/ @mmahadevan108 @dleach02 @@ -85,10 +79,8 @@ /boards/arm/msp_exp432p401r_launchxl/ @Mani-Sadhasivam /boards/arm/npcx7m6fb_evb/ @MulinChao @ChiHuaL /boards/arm/nrf*/ @carlescufi @lemrey -/boards/arm/nucleo*/ @erwango @ABOSTM @FRASTM /boards/arm/nucleo_f401re/ @idlethread /boards/arm/nuvoton_pfm_m487/ @ssekar15 -/boards/arm/pinnacle_100_dvk/ @rerickson1 /boards/arm/qemu_cortex_a9/ @ibirnbaum /boards/arm/qemu_cortex_r*/ @stephanosio /boards/arm/qemu_cortex_m*/ @ioannisg @stephanosio @@ -106,14 +98,13 @@ /boards/arm/sensortile_box/ @avisconti /boards/arm/steval_fcu001v1/ @Navin-Sankar /boards/arm/stm32l1_disco/ @karlp -/boards/arm/stm32*_disco/ @erwango @ABOSTM @FRASTM /boards/arm/stm32h735g_disco/ @benediktibk /boards/arm/stm32f3_disco/ @ydamigos -/boards/arm/stm32*_eval/ @erwango @ABOSTM @FRASTM /boards/arm/rcar_*/ @aaillet /boards/arm/ubx_bmd345eval_nrf52840/ @Navin-Sankar @brec-u-blox /boards/arm/nrf5340_audio_dk_nrf5340 @koffes @alexsven @erikrobstad @rick1082 @gWacey /boards/arm/stm32_min_dev/ @sidcha +/boards/ezurio/* @rerickson1 /boards/riscv/rv32m1_vega/ @dleach02 /boards/riscv/adp_xc7k_ae350/ @cwshu @kevinwang821020 @jimmyzhe /boards/riscv/longan_nano/ @soburi @@ -152,7 +143,6 @@ /drivers/*/*cc13xx_cc26xx* @bwitherspoon /drivers/*/*gd32* @nandojve /drivers/*/*mcux* @mmahadevan108 @dleach02 -/drivers/*/*stm32* @erwango @ABOSTM @FRASTM /drivers/*/*native_posix* @aescolar @daor-oti /drivers/*/*lpc11u6x* @mbittan @simonguinot /drivers/*/*npcx* @MulinChao @ChiHuaL @@ -231,7 +221,6 @@ /drivers/gpio/*b91* @andy-liu-telink /drivers/gpio/*lmp90xxx* @henrikbrixandersen /drivers/gpio/*nct38xx* @MulinChao @ChiHuaL -/drivers/gpio/*stm32* @erwango /drivers/gpio/*eos_s3* @fkokosinski @kgugala /drivers/gpio/*rcar* @aaillet /drivers/gpio/*esp32* @sylvioalves @@ -374,7 +363,6 @@ /drivers/timer/*xlnx_psttc* @wjliang @stephanosio /drivers/timer/*cc13xx_cc26xx_rtc* @vanti /drivers/timer/*cavs* @dcpleung -/drivers/timer/*stm32_lptim* @FRASTM /drivers/timer/*leon_gptimer* @julius-barendt /drivers/timer/*mips_cp0* @frantony /drivers/timer/*rcar_cmt* @aaillet @@ -424,7 +412,6 @@ /dts/arm64/renesas/ @lorc @xakep-amatop /dts/arm/quicklogic/ @fkokosinski @kgugala /dts/arm/seeed_studio/ @str4t0m -/dts/arm/st/ @erwango /dts/arm/st/h7/*stm32h735* @benediktibk /dts/arm/st/l4/*stm32l451* @benediktibk /dts/arm/ti/cc13?2* @bwitherspoon @@ -478,7 +465,6 @@ /dts/bindings/*/nxp*s32* @manuargue /dts/bindings/*/openisa* @dleach02 /dts/bindings/*/raspberrypi*pico* @yonsch -/dts/bindings/*/st* @erwango /dts/bindings/sensor/ams* @alexanderwachter /dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda /dts/bindings/*/andes* @cwshu @kevinwang821020 @jimmyzhe diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index c0122d065defa9..0dfcbda4a129f3 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -438,6 +438,7 @@ Bluetooth Audio: - larsgk - pin-zephyr - niym-ot + - jthm-ot files: - subsys/bluetooth/audio/ - include/zephyr/bluetooth/audio/ @@ -446,6 +447,7 @@ Bluetooth Audio: - tests/bsim/bluetooth/audio_samples/ - tests/bluetooth/shell/audio.conf - tests/bluetooth/tester/overlay-le-audio.conf + - tests/bluetooth/tester/src/audio/ - doc/connectivity/bluetooth/api/audio/ - samples/bluetooth/bap*/ - samples/bluetooth/hap*/ @@ -1250,6 +1252,7 @@ Release Notes: collaborators: - decsny - lmajewski + - pdgendt files: - drivers/ethernet/ - include/zephyr/dt-bindings/ethernet/ @@ -1843,7 +1846,7 @@ Release Notes: - dts/bindings/sensor/ - include/zephyr/drivers/sensor/ - include/zephyr/dt-bindings/sensor/ - - doc/hardware/peripherals/sensor.rst + - doc/hardware/peripherals/sensor/ - tests/drivers/build_all/sensor/ labels: - "area: Sensors" @@ -2325,16 +2328,16 @@ Memory Management: tests: - mem_mgmt -Laird Connectivity platforms: +Ezurio platforms: status: maintained maintainers: - rerickson1 collaborators: - greg-leach files: - - boards/lairdconnect/ + - boards/ezurio/ labels: - - "platform: Laird Connectivity" + - "platform: Ezurio" Linker Scripts: status: maintained @@ -2585,9 +2588,11 @@ Networking: files-exclude: - doc/connectivity/networking/api/gptp.rst - doc/connectivity/networking/api/ieee802154.rst + - doc/connectivity/networking/api/ptp.rst - doc/connectivity/networking/api/wifi.rst - include/zephyr/net/gptp.h - include/zephyr/net/ieee802154*.h + - include/zephyr/net/ptp.h - include/zephyr/net/wifi*.h - include/zephyr/net/buf.h - include/zephyr/net/dhcpv4*.h @@ -2603,6 +2608,7 @@ Networking: - subsys/net/lib/coap/ - subsys/net/lib/config/ieee802154* - subsys/net/lib/lwm2m/ + - subsys/net/lib/ptp/ - subsys/net/lib/tls_credentials/ - subsys/net/lib/dhcpv4/ - tests/net/dhcpv4/ @@ -2758,6 +2764,20 @@ Networking: tests: - net.mqtt_sn +"Networking: PTP": + status: maintained + maintainers: + - awojasinski + files: + - doc/connectivity/networking/api/ptp.rst + - include/zephyr/net/ptp.h + - subsys/net/lib/ptp/ + - samples/net/ptp/ + labels: + - "area: Networking" + tests: + - sample.net.ptp + "Networking: Native IEEE 802.15.4": status: maintained maintainers: @@ -2980,6 +3000,7 @@ Sensor Subsystem: - doc/services/sensing/ - subsys/sensing/ - samples/subsys/sensing/ + - tests/subsys/sensing/ labels: - "area: Sensor Subsystem" tests: @@ -3096,11 +3117,13 @@ State machine framework: - sambhurst collaborators: - keith-zephyr + - glenn-andrews files: - doc/services/smf/ - include/zephyr/smf.h - lib/smf/ - tests/lib/smf/ + - samples/subsys/smf/ labels: - "area: State Machine Framework" tests: @@ -3115,16 +3138,18 @@ ADI Platforms: - microbuilder files: - boards/adi/ - - drivers/*/max* + - drivers/*/*max* - drivers/*/*max*/ - drivers/dac/dac_ltc* - drivers/ethernet/eth_adin* - drivers/mdio/mdio_adin* - drivers/regulator/regulator_adp5360* - drivers/sensor/adi/ + - dts/arm/adi/ - dts/bindings/*/adi,* - dts/bindings/*/lltc,* - dts/bindings/*/maxim,* + - soc/adi/ labels: - "platform: ADI" @@ -3172,6 +3197,8 @@ Synopsys Platforms: - scripts/west_commands/tests/test_mdb.py - scripts/west_commands/runners/nsim.py - cmake/emu/nsim.cmake + - drivers/serial/uart_hostlink.c + - drivers/serial/Kconfig.hostlink labels: - "platform: Synopsys" @@ -3233,8 +3260,13 @@ Raspberry Pi Pico Platforms: labels: - "platform: Raspberry Pi Pico" -SiLabs Platforms: - status: odd fixes +Silabs Platforms: + status: maintained + maintainers: + - jhedberg + collaborators: + - jerome-pouiller + - asmellby files: - soc/silabs/ - boards/silabs/ @@ -3242,7 +3274,7 @@ SiLabs Platforms: - dts/bindings/*/silabs* - drivers/*/*_gecko* labels: - - "platform: SiLabs" + - "platform: Silabs" Intel Platforms (X86): status: maintained @@ -3530,6 +3562,8 @@ Renesas SmartBond Platforms: - ioannis-karachalios - andrzej-kaczmarek - blauret + collaborators: + - ydamigos files: - boards/renesas/da14*/ - drivers/*/*smartbond* @@ -3609,6 +3643,7 @@ STM32 Platforms: - FRASTM - gautierg-st - GeorgeCGV + - marwaiehm-st files: - boards/st/ - drivers/*/*stm32*.c @@ -3788,6 +3823,7 @@ RTIO: - teburd collaborators: - yperess + - ubieda files: - samples/subsys/rtio/ - include/zephyr/rtio/ @@ -4424,6 +4460,7 @@ West: collaborators: - blauret - andrzej-kaczmarek + - ydamigos files: [] labels: - "platform: Renesas" @@ -4438,15 +4475,19 @@ West: - "platform: Raspberry Pi Pico" "West project: hal_silabs": - status: odd fixes + status: maintained + maintainers: + - jhedberg collaborators: + - jerome-pouiller + - asmellby - sateeshkotapati - yonsch - mnkp files: - modules/Kconfig.silabs labels: - - "platform: SiLabs" + - "platform: Silabs" "West project: hal_st": status: maintained @@ -4463,9 +4504,8 @@ West: - erwango collaborators: - FRASTM - - ABOSTM - gautierg-st - - Desvauxm-st + - marwaiehm-st files: - modules/Kconfig.stm32 labels: @@ -4601,7 +4641,7 @@ West: - nordicjm files: - modules/Kconfig.mcuboot - - tests/boot/test_mcuboot/ + - tests/boot/ labels: - "area: MCUBoot" diff --git a/SDK_VERSION b/SDK_VERSION index e35e56114f44cc..74aaa3f38cfe82 100644 --- a/SDK_VERSION +++ b/SDK_VERSION @@ -1 +1 @@ -0.16.5-1 +0.16.8 diff --git a/arch/Kconfig b/arch/Kconfig index f3e4f14dfbc89f..15d8fc0653bb43 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -24,6 +24,7 @@ config ARC imply XIP select ARCH_HAS_THREAD_LOCAL_STORAGE select ARCH_SUPPORTS_ROM_START + select ARCH_HAS_DIRECTED_IPIS help ARC architecture @@ -50,6 +51,7 @@ config ARM64 select USE_SWITCH_SUPPORTED select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD select BARRIER_OPERATIONS_ARCH + select ARCH_HAS_DIRECTED_IPIS help ARM64 (AArch64) architecture @@ -115,6 +117,7 @@ config RISCV select USE_SWITCH_SUPPORTED select USE_SWITCH select SCHED_IPI_SUPPORTED if SMP + select ARCH_HAS_DIRECTED_IPIS select BARRIER_OPERATIONS_BUILTIN imply XIP help @@ -129,6 +132,7 @@ config XTENSA select ARCH_HAS_CODE_DATA_RELOCATION select ARCH_HAS_TIMING_FUNCTIONS select ARCH_MEM_DOMAIN_DATA if USERSPACE + select ARCH_HAS_DIRECTED_IPIS help Xtensa architecture @@ -746,6 +750,13 @@ config ARCH_HAS_RESERVED_PAGE_FRAMES memory mappings. The architecture will need to implement arch_reserved_pages_update(). +config ARCH_HAS_DIRECTED_IPIS + bool + help + This hidden configuration should be selected by the architecture if + it has an implementation for arch_sched_directed_ipi() which allows + for IPIs to be directed to specific CPUs. + config CPU_HAS_DCACHE bool help @@ -781,7 +792,7 @@ config ARCH_MAPS_ALL_RAM virtual addresses elsewhere, this is limited to only management of the virtual address space. The kernel's page frame ontology will not consider this mapping at all; non-kernel pages will be considered free (unless marked - as reserved) and Z_PAGE_FRAME_MAPPED will not be set. + as reserved) and K_MEM_PAGE_FRAME_MAPPED will not be set. config DCLS bool "Processor is configured in DCLS mode" diff --git a/arch/arc/core/fatal.c b/arch/arc/core/fatal.c index f193c0b09f1f2b..512d1cc442c6f9 100644 --- a/arch/arc/core/fatal.c +++ b/arch/arc/core/fatal.c @@ -23,7 +23,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #ifdef CONFIG_EXCEPTION_DEBUG -static void dump_arc_esf(const z_arch_esf_t *esf) +static void dump_arc_esf(const struct arch_esf *esf) { ARC_EXCEPTION_DUMP(" r0: 0x%" PRIxPTR " r1: 0x%" PRIxPTR " r2: 0x%" PRIxPTR " r3: 0x%" PRIxPTR "", esf->r0, esf->r1, esf->r2, esf->r3); @@ -42,7 +42,7 @@ static void dump_arc_esf(const z_arch_esf_t *esf) } #endif -void z_arc_fatal_error(unsigned int reason, const z_arch_esf_t *esf) +void z_arc_fatal_error(unsigned int reason, const struct arch_esf *esf) { #ifdef CONFIG_EXCEPTION_DEBUG if (esf != NULL) { diff --git a/arch/arc/core/fault.c b/arch/arc/core/fault.c index 763ed7a2c737a8..6f9da3cd1e0e95 100644 --- a/arch/arc/core/fault.c +++ b/arch/arc/core/fault.c @@ -346,7 +346,7 @@ static void dump_exception_info(uint32_t vector, uint32_t cause, uint32_t parame * invokes the user provided routine k_sys_fatal_error_handler() which is * responsible for implementing the error handling policy. */ -void _Fault(z_arch_esf_t *esf, uint32_t old_sp) +void _Fault(struct arch_esf *esf, uint32_t old_sp) { uint32_t vector, cause, parameter; uint32_t exc_addr = z_arc_v2_aux_reg_read(_ARC_V2_EFA); diff --git a/arch/arc/core/isr_wrapper.S b/arch/arc/core/isr_wrapper.S index 3471e4d73498d0..4b486ed926da58 100644 --- a/arch/arc/core/isr_wrapper.S +++ b/arch/arc/core/isr_wrapper.S @@ -26,7 +26,7 @@ GTEXT(_isr_wrapper) GTEXT(_isr_demux) #if defined(CONFIG_PM) -GTEXT(z_pm_save_idle_exit) +GTEXT(pm_system_resume) #endif /* @@ -253,7 +253,7 @@ rirq_path: st 0, [r1, _kernel_offset_to_idle] /* zero idle duration */ PUSHR blink - jl z_pm_save_idle_exit + jl pm_system_resume POPR blink _skip_pm_save_idle_exit: diff --git a/arch/arc/core/smp.c b/arch/arc/core/smp.c index 9f8ee38a4a1055..e8463b7b53b355 100644 --- a/arch/arc/core/smp.c +++ b/arch/arc/core/smp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -130,21 +131,27 @@ static void sched_ipi_handler(const void *unused) z_sched_ipi(); } -/* arch implementation of sched_ipi */ -void arch_sched_ipi(void) +void arch_sched_directed_ipi(uint32_t cpu_bitmap) { - uint32_t i; + unsigned int i; + unsigned int num_cpus = arch_num_cpus(); - /* broadcast sched_ipi request to other cores + /* Send sched_ipi request to other cores * if the target is current core, hardware will ignore it */ - unsigned int num_cpus = arch_num_cpus(); for (i = 0U; i < num_cpus; i++) { - z_arc_connect_ici_generate(i); + if ((cpu_bitmap & BIT(i)) != 0) { + z_arc_connect_ici_generate(i); + } } } +void arch_sched_broadcast_ipi(void) +{ + arch_sched_directed_ipi(IPI_ALL_CPUS_MASK); +} + int arch_smp_init(void) { struct arc_connect_bcr bcr; @@ -188,5 +195,4 @@ int arch_smp_init(void) return 0; } -SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arc/include/kernel_arch_data.h b/arch/arc/include/kernel_arch_data.h index efe2bd7d1c6585..b0dc733446b083 100644 --- a/arch/arc/include/kernel_arch_data.h +++ b/arch/arc/include/kernel_arch_data.h @@ -36,7 +36,7 @@ extern "C" { #endif #ifdef CONFIG_ARC_HAS_SECURE -struct _irq_stack_frame { +struct arch_esf { #ifdef CONFIG_ARC_HAS_ZOL uintptr_t lp_end; uintptr_t lp_start; @@ -72,7 +72,7 @@ struct _irq_stack_frame { uintptr_t status32; }; #else -struct _irq_stack_frame { +struct arch_esf { uintptr_t r0; uintptr_t r1; uintptr_t r2; @@ -108,7 +108,7 @@ struct _irq_stack_frame { }; #endif -typedef struct _irq_stack_frame _isf_t; +typedef struct arch_esf _isf_t; diff --git a/arch/arc/include/kernel_arch_func.h b/arch/arc/include/kernel_arch_func.h index 1c46423cb4f03f..ca382a274f4b1b 100644 --- a/arch/arc/include/kernel_arch_func.h +++ b/arch/arc/include/kernel_arch_func.h @@ -62,9 +62,7 @@ extern void z_arc_userspace_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3, uint32_t stack, uint32_t size, struct k_thread *thread); -extern void z_arc_fatal_error(unsigned int reason, const z_arch_esf_t *esf); - -extern void arch_sched_ipi(void); +extern void z_arc_fatal_error(unsigned int reason, const struct arch_esf *esf); extern void z_arc_switch(void *switch_to, void **switched_from); diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf68ec6faae69b..c28cf8d29f9a46 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -35,7 +35,7 @@ config ARM_CUSTOM_INTERRUPT_CONTROLLER assumes responsibility for handling the NVIC. config ROMSTART_RELOCATION_ROM - bool + bool "Relocate rom_start region" default n help Relocates the rom_start region containing the boot-vector data and @@ -66,7 +66,7 @@ config ROMSTART_RELOCATION_ROM if ROMSTART_RELOCATION_ROM config ROMSTART_REGION_ADDRESS - hex + hex "Base address of the rom_start region" default 0x00000000 help Start address of the rom_start region. @@ -85,7 +85,7 @@ if ROMSTART_RELOCATION_ROM $(dt_nodelabel_reg_addr_hex,ocram_s_sys) config ROMSTART_REGION_SIZE - hex + hex "Size of the rom_start region" default 1 help Size of the rom_start region in KB. diff --git a/arch/arm/core/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig index 3ec57cc408e1bc..4095a277c61388 100644 --- a/arch/arm/core/cortex_a_r/Kconfig +++ b/arch/arm/core/cortex_a_r/Kconfig @@ -131,6 +131,7 @@ config AARCH32_ARMV8_R bool select ATOMIC_OPERATIONS_BUILTIN select SCHED_IPI_SUPPORTED if SMP + select ARCH_HAS_DIRECTED_IPIS help This option signifies the use of an ARMv8-R AArch32 processor implementation. diff --git a/arch/arm/core/cortex_a_r/fault.c b/arch/arm/core/cortex_a_r/fault.c index a39efeb96e0276..d792fc57da8de4 100644 --- a/arch/arm/core/cortex_a_r/fault.c +++ b/arch/arm/core/cortex_a_r/fault.c @@ -206,7 +206,7 @@ bool z_arm_fault_undef_instruction_fp(void) * * @return Returns true if the fault is fatal */ -bool z_arm_fault_undef_instruction(z_arch_esf_t *esf) +bool z_arm_fault_undef_instruction(struct arch_esf *esf) { #if defined(CONFIG_FPU_SHARING) /* @@ -243,7 +243,7 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf) * * @return Returns true if the fault is fatal */ -bool z_arm_fault_prefetch(z_arch_esf_t *esf) +bool z_arm_fault_prefetch(struct arch_esf *esf) { uint32_t reason = K_ERR_CPU_EXCEPTION; @@ -299,7 +299,7 @@ static const struct z_exc_handle exceptions[] = { * * @return true if error is recoverable, otherwise return false. */ -static bool memory_fault_recoverable(z_arch_esf_t *esf) +static bool memory_fault_recoverable(struct arch_esf *esf) { for (int i = 0; i < ARRAY_SIZE(exceptions); i++) { /* Mask out instruction mode */ @@ -321,7 +321,7 @@ static bool memory_fault_recoverable(z_arch_esf_t *esf) * * @return Returns true if the fault is fatal */ -bool z_arm_fault_data(z_arch_esf_t *esf) +bool z_arm_fault_data(struct arch_esf *esf) { uint32_t reason = K_ERR_CPU_EXCEPTION; diff --git a/arch/arm/core/cortex_a_r/irq_manage.c b/arch/arm/core/cortex_a_r/irq_manage.c index 1dca75e297ab04..48c9ede3327bb3 100644 --- a/arch/arm/core/cortex_a_r/irq_manage.c +++ b/arch/arm/core/cortex_a_r/irq_manage.c @@ -71,7 +71,7 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) } #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ -void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf); /** * diff --git a/arch/arm/core/cortex_a_r/isr_wrapper.S b/arch/arm/core/cortex_a_r/isr_wrapper.S index 0cd30e0a34313c..56fd111ea3fe4e 100644 --- a/arch/arm/core/cortex_a_r/isr_wrapper.S +++ b/arch/arm/core/cortex_a_r/isr_wrapper.S @@ -156,7 +156,7 @@ _vfp_not_enabled: * idle, this ensures that the calculation and programming of the * device for the next timer deadline is not interrupted. For * non-tickless idle, this ensures that the clearing of the kernel idle - * state is not interrupted. In each case, z_pm_save_idle_exit + * state is not interrupted. In each case, pm_system_resume * is called with interrupts disabled. */ @@ -170,7 +170,7 @@ _vfp_not_enabled: movs r1, #0 /* clear kernel idle state */ str r1, [r2, #_kernel_offset_to_idle] - bl z_pm_save_idle_exit + bl pm_system_resume _idle_state_cleared: #endif /* CONFIG_PM */ @@ -269,7 +269,7 @@ SECTION_FUNC(TEXT, _isr_wrapper) * idle, this ensures that the calculation and programming of the * device for the next timer deadline is not interrupted. For * non-tickless idle, this ensures that the clearing of the kernel idle - * state is not interrupted. In each case, z_pm_save_idle_exit + * state is not interrupted. In each case, pm_system_resume * is called with interrupts disabled. */ @@ -283,7 +283,7 @@ SECTION_FUNC(TEXT, _isr_wrapper) movs r1, #0 /* clear kernel idle state */ str r1, [r2, #_kernel_offset_to_idle] - bl z_pm_save_idle_exit + bl pm_system_resume _idle_state_cleared: #endif /* CONFIG_PM */ diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index 9e06730f91396c..0214b4715f6e99 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "boot.h" #include "zephyr/cache.h" #include "zephyr/kernel/thread_stack.h" @@ -210,7 +211,7 @@ void arch_secondary_cpu_init(void) #ifdef CONFIG_SMP -static void broadcast_ipi(unsigned int ipi) +static void send_ipi(unsigned int ipi, uint32_t cpu_bitmap) { uint32_t mpidr = MPIDR_TO_CORE(GET_MPIDR()); @@ -220,6 +221,10 @@ static void broadcast_ipi(unsigned int ipi) unsigned int num_cpus = arch_num_cpus(); for (int i = 0; i < num_cpus; i++) { + if ((cpu_bitmap & BIT(i)) == 0) { + continue; + } + uint32_t target_mpidr = cpu_map[i]; uint8_t aff0; @@ -239,10 +244,14 @@ void sched_ipi_handler(const void *unused) z_sched_ipi(); } -/* arch implementation of sched_ipi */ -void arch_sched_ipi(void) +void arch_sched_broadcast_ipi(void) { - broadcast_ipi(SGI_SCHED_IPI); + send_ipi(SGI_SCHED_IPI, IPI_ALL_CPUS_MASK); +} + +void arch_sched_directed_ipi(uint32_t cpu_bitmap) +{ + send_ipi(SGI_SCHED_IPI, cpu_bitmap); } int arch_smp_init(void) @@ -259,6 +268,4 @@ int arch_smp_init(void) return 0; } -SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); - #endif diff --git a/arch/arm/core/cortex_m/coredump.c b/arch/arm/core/cortex_m/coredump.c index 2b4a86a1bb9b2b..c688c91d9819d9 100644 --- a/arch/arm/core/cortex_m/coredump.c +++ b/arch/arm/core/cortex_m/coredump.c @@ -41,7 +41,7 @@ struct arm_arch_block { */ static struct arm_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { struct coredump_arch_hdr_t hdr = { .id = COREDUMP_ARCH_HDR_ID, diff --git a/arch/arm/core/cortex_m/fault.c b/arch/arm/core/cortex_m/fault.c index 5090381fa317d4..78b87092976f6a 100644 --- a/arch/arm/core/cortex_m/fault.c +++ b/arch/arm/core/cortex_m/fault.c @@ -146,7 +146,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); */ #if (CONFIG_FAULT_DUMP == 1) -static void fault_show(const z_arch_esf_t *esf, int fault) +static void fault_show(const struct arch_esf *esf, int fault) { PR_EXC("Fault! EXC #%d", fault); @@ -165,7 +165,7 @@ static void fault_show(const z_arch_esf_t *esf, int fault) * * For Dump level 0, no information needs to be generated. */ -static void fault_show(const z_arch_esf_t *esf, int fault) +static void fault_show(const struct arch_esf *esf, int fault) { (void)esf; (void)fault; @@ -185,7 +185,7 @@ static const struct z_exc_handle exceptions[] = { * * @return true if error is recoverable, otherwise return false. */ -static bool memory_fault_recoverable(z_arch_esf_t *esf, bool synchronous) +static bool memory_fault_recoverable(struct arch_esf *esf, bool synchronous) { #ifdef CONFIG_USERSPACE for (int i = 0; i < ARRAY_SIZE(exceptions); i++) { @@ -228,7 +228,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, * * @return error code to identify the fatal error reason */ -static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, +static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverable) { uint32_t reason = K_ERR_ARM_MEM_GENERIC; @@ -387,7 +387,7 @@ static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, * @return error code to identify the fatal error reason. * */ -static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) +static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverable) { uint32_t reason = K_ERR_ARM_BUS_GENERIC; @@ -549,7 +549,7 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) * * @return error code to identify the fatal error reason */ -static uint32_t usage_fault(const z_arch_esf_t *esf) +static uint32_t usage_fault(const struct arch_esf *esf) { uint32_t reason = K_ERR_ARM_USAGE_GENERIC; @@ -612,7 +612,7 @@ static uint32_t usage_fault(const z_arch_esf_t *esf) * * @return error code to identify the fatal error reason */ -static uint32_t secure_fault(const z_arch_esf_t *esf) +static uint32_t secure_fault(const struct arch_esf *esf) { uint32_t reason = K_ERR_ARM_SECURE_GENERIC; @@ -661,7 +661,7 @@ static uint32_t secure_fault(const z_arch_esf_t *esf) * See z_arm_fault_dump() for example. * */ -static void debug_monitor(z_arch_esf_t *esf, bool *recoverable) +static void debug_monitor(struct arch_esf *esf, bool *recoverable) { *recoverable = false; @@ -687,7 +687,7 @@ static void debug_monitor(z_arch_esf_t *esf, bool *recoverable) #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ -static inline bool z_arm_is_synchronous_svc(z_arch_esf_t *esf) +static inline bool z_arm_is_synchronous_svc(struct arch_esf *esf) { uint16_t *ret_addr = (uint16_t *)esf->basic.pc; /* SVC is a 16-bit instruction. On a synchronous SVC @@ -762,7 +762,7 @@ static inline bool z_arm_is_pc_valid(uintptr_t pc) * * @return error code to identify the fatal error reason */ -static uint32_t hard_fault(z_arch_esf_t *esf, bool *recoverable) +static uint32_t hard_fault(struct arch_esf *esf, bool *recoverable) { uint32_t reason = K_ERR_CPU_EXCEPTION; @@ -829,7 +829,7 @@ static uint32_t hard_fault(z_arch_esf_t *esf, bool *recoverable) * See z_arm_fault_dump() for example. * */ -static void reserved_exception(const z_arch_esf_t *esf, int fault) +static void reserved_exception(const struct arch_esf *esf, int fault) { ARG_UNUSED(esf); @@ -839,7 +839,7 @@ static void reserved_exception(const z_arch_esf_t *esf, int fault) } /* Handler function for ARM fault conditions. */ -static uint32_t fault_handle(z_arch_esf_t *esf, int fault, bool *recoverable) +static uint32_t fault_handle(struct arch_esf *esf, int fault, bool *recoverable) { uint32_t reason = K_ERR_CPU_EXCEPTION; @@ -893,7 +893,7 @@ static uint32_t fault_handle(z_arch_esf_t *esf, int fault, bool *recoverable) * * @param secure_esf Pointer to the secure stack frame. */ -static void secure_stack_dump(const z_arch_esf_t *secure_esf) +static void secure_stack_dump(const struct arch_esf *secure_esf) { /* * In case a Non-Secure exception interrupted the Secure @@ -918,7 +918,7 @@ static void secure_stack_dump(const z_arch_esf_t *secure_esf) * Non-Secure exception entry. */ top_of_sec_stack += ADDITIONAL_STATE_CONTEXT_WORDS; - secure_esf = (const z_arch_esf_t *)top_of_sec_stack; + secure_esf = (const struct arch_esf *)top_of_sec_stack; sec_ret_addr = secure_esf->basic.pc; } else { /* Exception during Non-Secure function call. @@ -947,11 +947,11 @@ static void secure_stack_dump(const z_arch_esf_t *secure_esf) * * @return ESF pointer on success, otherwise return NULL */ -static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_return, +static inline struct arch_esf *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_return, bool *nested_exc) { bool alternative_state_exc = false; - z_arch_esf_t *ptr_esf = NULL; + struct arch_esf *ptr_esf = NULL; *nested_exc = false; @@ -979,14 +979,14 @@ static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ret alternative_state_exc = true; /* Dump the Secure stack before handling the actual fault. */ - z_arch_esf_t *secure_esf; + struct arch_esf *secure_esf; if (exc_return & EXC_RETURN_SPSEL_PROCESS) { /* Secure stack pointed by PSP */ - secure_esf = (z_arch_esf_t *)psp; + secure_esf = (struct arch_esf *)psp; } else { /* Secure stack pointed by MSP */ - secure_esf = (z_arch_esf_t *)msp; + secure_esf = (struct arch_esf *)msp; *nested_exc = true; } @@ -997,9 +997,9 @@ static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ret * and supply it to the fault handing function. */ if (exc_return & EXC_RETURN_MODE_THREAD) { - ptr_esf = (z_arch_esf_t *)__TZ_get_PSP_NS(); + ptr_esf = (struct arch_esf *)__TZ_get_PSP_NS(); } else { - ptr_esf = (z_arch_esf_t *)__TZ_get_MSP_NS(); + ptr_esf = (struct arch_esf *)__TZ_get_MSP_NS(); } } #elif defined(CONFIG_ARM_NONSECURE_FIRMWARE) @@ -1024,10 +1024,10 @@ static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ret if (exc_return & EXC_RETURN_SPSEL_PROCESS) { /* Non-Secure stack frame on PSP */ - ptr_esf = (z_arch_esf_t *)psp; + ptr_esf = (struct arch_esf *)psp; } else { /* Non-Secure stack frame on MSP */ - ptr_esf = (z_arch_esf_t *)msp; + ptr_esf = (struct arch_esf *)msp; } } else { /* Exception entry occurred in Non-Secure stack. */ @@ -1046,11 +1046,11 @@ static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ret if (!alternative_state_exc) { if (exc_return & EXC_RETURN_MODE_THREAD) { /* Returning to thread mode */ - ptr_esf = (z_arch_esf_t *)psp; + ptr_esf = (struct arch_esf *)psp; } else { /* Returning to handler mode */ - ptr_esf = (z_arch_esf_t *)msp; + ptr_esf = (struct arch_esf *)msp; *nested_exc = true; } } @@ -1095,12 +1095,12 @@ void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, uint32_t reason = K_ERR_CPU_EXCEPTION; int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; bool recoverable, nested_exc; - z_arch_esf_t *esf; + struct arch_esf *esf; /* Create a stack-ed copy of the ESF to be used during * the fault handling process. */ - z_arch_esf_t esf_copy; + struct arch_esf esf_copy; /* Force unlock interrupts */ arch_irq_unlock(0); @@ -1123,13 +1123,13 @@ void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, /* Copy ESF */ #if !defined(CONFIG_EXTRA_EXCEPTION_INFO) - memcpy(&esf_copy, esf, sizeof(z_arch_esf_t)); + memcpy(&esf_copy, esf, sizeof(struct arch_esf)); ARG_UNUSED(callee_regs); #else /* the extra exception info is not present in the original esf * so we only copy the fields before those. */ - memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info)); + memcpy(&esf_copy, esf, offsetof(struct arch_esf, extra_info)); esf_copy.extra_info = (struct __extra_esf_info) { .callee = callee_regs, .exc_return = exc_return, diff --git a/arch/arm/core/cortex_m/irq_manage.c b/arch/arm/core/cortex_m/irq_manage.c index b72332b32e81a2..cc62386e8acad8 100644 --- a/arch/arm/core/cortex_m/irq_manage.c +++ b/arch/arm/core/cortex_m/irq_manage.c @@ -94,7 +94,7 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) #endif /* !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) */ -void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf); /** * @@ -122,7 +122,7 @@ void _arch_isr_direct_pm(void) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* Lock all interrupts. irq_lock() will on this CPU only disable those * lower than BASEPRI, which is not what we want. See comments in - * arch/arm/core/isr_wrapper.S + * arch/arm/core/cortex_m/isr_wrapper.c */ __asm__ volatile("cpsid i" : : : "memory"); #else diff --git a/arch/arm/core/fatal.c b/arch/arm/core/fatal.c index 4364d48d45d574..4532e238f05c99 100644 --- a/arch/arm/core/fatal.c +++ b/arch/arm/core/fatal.c @@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #ifdef CONFIG_EXCEPTION_DEBUG -static void esf_dump(const z_arch_esf_t *esf) +static void esf_dump(const struct arch_esf *esf) { LOG_ERR("r0/a1: 0x%08x r1/a2: 0x%08x r2/a3: 0x%08x", esf->basic.a1, esf->basic.a2, esf->basic.a3); @@ -66,7 +66,7 @@ static void esf_dump(const z_arch_esf_t *esf) } #endif /* CONFIG_EXCEPTION_DEBUG */ -void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf) +void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf) { #ifdef CONFIG_EXCEPTION_DEBUG if (esf != NULL) { @@ -102,7 +102,7 @@ void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf) * @param esf exception frame * @param callee_regs Callee-saved registers (R4-R11) */ -void z_do_kernel_oops(const z_arch_esf_t *esf, _callee_saved_t *callee_regs) +void z_do_kernel_oops(const struct arch_esf *esf, _callee_saved_t *callee_regs) { #if !(defined(CONFIG_EXTRA_EXCEPTION_INFO) && defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)) ARG_UNUSED(callee_regs); @@ -130,9 +130,9 @@ void z_do_kernel_oops(const z_arch_esf_t *esf, _callee_saved_t *callee_regs) #if !defined(CONFIG_EXTRA_EXCEPTION_INFO) z_arm_fatal_error(reason, esf); #else - z_arch_esf_t esf_copy; + struct arch_esf esf_copy; - memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info)); + memcpy(&esf_copy, esf, offsetof(struct arch_esf, extra_info)); #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* extra exception info is collected in callee_reg param * on CONFIG_ARMV7_M_ARMV8_M_MAINLINE @@ -156,7 +156,7 @@ void z_do_kernel_oops(const z_arch_esf_t *esf, _callee_saved_t *callee_regs) FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) { uint32_t *ssf_contents = ssf_ptr; - z_arch_esf_t oops_esf = { 0 }; + struct arch_esf oops_esf = { 0 }; /* TODO: Copy the rest of the register set out of ssf_ptr */ oops_esf.basic.pc = ssf_contents[3]; diff --git a/arch/arm/core/gdbstub.c b/arch/arm/core/gdbstub.c index 5386cfa619f1af..60d16b78c319c1 100644 --- a/arch/arm/core/gdbstub.c +++ b/arch/arm/core/gdbstub.c @@ -42,7 +42,7 @@ static int is_bkpt(unsigned int exc_cause) } /* Wrapper function to save and restore execution c */ -void z_gdb_entry(z_arch_esf_t *esf, unsigned int exc_cause) +void z_gdb_entry(struct arch_esf *esf, unsigned int exc_cause) { /* Disable the hardware breakpoint in case it was set */ __asm__ volatile("mcr p14, 0, %0, c0, c0, 5" ::"r"(0x0) :); diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index 52ad585b79c13c..fe5d86c822da56 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -130,12 +130,10 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) break; #endif default: - /* Either the specified `ATTR_MPU_*` attribute does not - * exists or the `REGION_*_ATTR` macro is not defined - * for that attribute. + /* Attribute other than ARM-specific is set. + * This region should not be configured in MPU. */ - LOG_ERR("Invalid attribute for the region\n"); - return -EINVAL; + continue; } #if defined(CONFIG_ARMV7_R) region_conf.size = size_to_mpu_rasr_size(region[idx].dt_size); diff --git a/arch/arm/include/cortex_a_r/exception.h b/arch/arm/include/cortex_a_r/exception.h index 7519016176c5ef..6daa9c106ee2ba 100644 --- a/arch/arm/include/cortex_a_r/exception.h +++ b/arch/arm/include/cortex_a_r/exception.h @@ -38,7 +38,7 @@ static ALWAYS_INLINE bool arch_is_in_isr(void) return (arch_curr_cpu()->nested != 0U); } -static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) +static ALWAYS_INLINE bool arch_is_in_nested_exception(const struct arch_esf *esf) { return (arch_curr_cpu()->arch.exc_depth > 1U) ? (true) : (false); } @@ -48,7 +48,7 @@ static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) * This function is used by privileged code to determine if the thread * associated with the stack frame is in user mode. */ -static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const z_arch_esf_t *esf) +static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const struct arch_esf *esf) { return ((esf->basic.xpsr & CPSR_M_Msk) == CPSR_M_USR); } diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h index 88f631ff4b487a..3486d7d4d4e02d 100644 --- a/arch/arm/include/cortex_a_r/kernel_arch_func.h +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -59,7 +59,7 @@ extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, uint32_t stack_end, uint32_t stack_start); -extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +extern void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf); #endif /* _ASMLANGUAGE */ diff --git a/arch/arm/include/cortex_m/exception.h b/arch/arm/include/cortex_m/exception.h index bf86abd77c70f5..89bdd4b83e9a28 100644 --- a/arch/arm/include/cortex_m/exception.h +++ b/arch/arm/include/cortex_m/exception.h @@ -68,7 +68,7 @@ static ALWAYS_INLINE bool arch_is_in_isr(void) * @return true if execution state was in handler mode, before * the current exception occurred, otherwise false. */ -static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) +static ALWAYS_INLINE bool arch_is_in_nested_exception(const struct arch_esf *esf) { return (esf->basic.xpsr & IPSR_ISR_Msk) ? (true) : (false); } @@ -80,7 +80,7 @@ static ALWAYS_INLINE bool arch_is_in_nested_exception(const z_arch_esf_t *esf) * @param esf the exception stack frame (unused) * @return true if the current thread was in unprivileged mode */ -static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const z_arch_esf_t *esf) +static ALWAYS_INLINE bool z_arm_preempted_thread_in_user_mode(const struct arch_esf *esf) { return z_arm_thread_is_in_user_mode(); } diff --git a/arch/arm/include/cortex_m/kernel_arch_func.h b/arch/arm/include/cortex_m/kernel_arch_func.h index 77619c9d6c4f8e..132c056c91022c 100644 --- a/arch/arm/include/cortex_m/kernel_arch_func.h +++ b/arch/arm/include/cortex_m/kernel_arch_func.h @@ -76,7 +76,7 @@ extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, uint32_t stack_end, uint32_t stack_start); -extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +extern void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf); #endif /* _ASMLANGUAGE */ diff --git a/arch/arm/include/kernel_arch_data.h b/arch/arm/include/kernel_arch_data.h index 5ad19db8f84b85..9b4ca04f66c568 100644 --- a/arch/arm/include/kernel_arch_data.h +++ b/arch/arm/include/kernel_arch_data.h @@ -42,7 +42,7 @@ extern "C" { #endif -typedef struct __esf _esf_t; +typedef struct arch_esf _esf_t; typedef struct __basic_sf _basic_sf_t; #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) typedef struct __fpu_sf _fpu_sf_t; diff --git a/arch/arm64/core/coredump.c b/arch/arm64/core/coredump.c index 399cf85e3d0f42..0176b61612ec18 100644 --- a/arch/arm64/core/coredump.c +++ b/arch/arm64/core/coredump.c @@ -13,7 +13,7 @@ #define ARCH_HDR_VER 1 /* Structure to store the architecture registers passed arch_coredump_info_dump - * As callee saved registers are not provided in z_arch_esf_t structure in Zephyr + * As callee saved registers are not provided in struct arch_esf structure in Zephyr * we just need 22 registers. */ struct arm64_arch_block { @@ -50,7 +50,7 @@ struct arm64_arch_block { */ static struct arm64_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { /* Target architecture information header */ /* Information just relevant to the python parser */ @@ -69,7 +69,7 @@ void arch_coredump_info_dump(const z_arch_esf_t *esf) /* * Copies the thread registers to a memory block that will be printed out - * The thread registers are already provided by structure z_arch_esf_t + * The thread registers are already provided by structure struct arch_esf */ arch_blk.r.x0 = esf->x0; arch_blk.r.x1 = esf->x1; diff --git a/arch/arm64/core/fatal.c b/arch/arm64/core/fatal.c index f921c4ccf5aa6e..a02ae13acf89ca 100644 --- a/arch/arm64/core/fatal.c +++ b/arch/arm64/core/fatal.c @@ -181,7 +181,7 @@ static void dump_esr(uint64_t esr, bool *dump_far) LOG_ERR(" ISS: 0x%llx", GET_ESR_ISS(esr)); } -static void esf_dump(const z_arch_esf_t *esf) +static void esf_dump(const struct arch_esf *esf) { LOG_ERR("x0: 0x%016llx x1: 0x%016llx", esf->x0, esf->x1); LOG_ERR("x2: 0x%016llx x3: 0x%016llx", esf->x2, esf->x3); @@ -196,7 +196,7 @@ static void esf_dump(const z_arch_esf_t *esf) } #ifdef CONFIG_EXCEPTION_STACK_TRACE -static void esf_unwind(const z_arch_esf_t *esf) +static void esf_unwind(const struct arch_esf *esf) { /* * For GCC: @@ -244,7 +244,7 @@ static void esf_unwind(const z_arch_esf_t *esf) #endif /* CONFIG_EXCEPTION_DEBUG */ #ifdef CONFIG_ARM64_STACK_PROTECTION -static bool z_arm64_stack_corruption_check(z_arch_esf_t *esf, uint64_t esr, uint64_t far) +static bool z_arm64_stack_corruption_check(struct arch_esf *esf, uint64_t esr, uint64_t far) { uint64_t sp, sp_limit, guard_start; /* 0x25 means data abort from current EL */ @@ -284,7 +284,7 @@ static bool z_arm64_stack_corruption_check(z_arch_esf_t *esf, uint64_t esr, uint } #endif -static bool is_recoverable(z_arch_esf_t *esf, uint64_t esr, uint64_t far, +static bool is_recoverable(struct arch_esf *esf, uint64_t esr, uint64_t far, uint64_t elr) { if (!esf) @@ -306,7 +306,7 @@ static bool is_recoverable(z_arch_esf_t *esf, uint64_t esr, uint64_t far, return false; } -void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf) +void z_arm64_fatal_error(unsigned int reason, struct arch_esf *esf) { uint64_t esr = 0; uint64_t elr = 0; @@ -379,7 +379,7 @@ void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf) * * @param esf exception frame */ -void z_arm64_do_kernel_oops(z_arch_esf_t *esf) +void z_arm64_do_kernel_oops(struct arch_esf *esf) { /* x8 holds the exception reason */ unsigned int reason = esf->x8; diff --git a/arch/arm64/core/fpu.c b/arch/arm64/core/fpu.c index 0133eed2dcaaf6..a585165b943397 100644 --- a/arch/arm64/core/fpu.c +++ b/arch/arm64/core/fpu.c @@ -159,7 +159,7 @@ void z_arm64_fpu_enter_exc(void) * simulate them and leave the FPU access disabled. This also avoids the * need for disabling interrupts in syscalls and IRQ handlers as well. */ -static bool simulate_str_q_insn(z_arch_esf_t *esf) +static bool simulate_str_q_insn(struct arch_esf *esf) { /* * Support only the "FP in exception" cases for now. @@ -221,7 +221,7 @@ static bool simulate_str_q_insn(z_arch_esf_t *esf) * don't get interrupted that is. To ensure that we mask interrupts to * the triggering exception context. */ -void z_arm64_fpu_trap(z_arch_esf_t *esf) +void z_arm64_fpu_trap(struct arch_esf *esf) { __ASSERT(read_daif() & DAIF_IRQ_BIT, "must be called with IRQs disabled"); diff --git a/arch/arm64/core/irq_manage.c b/arch/arm64/core/irq_manage.c index 4e96ce77bfa202..6344d1e3696c0f 100644 --- a/arch/arm64/core/irq_manage.c +++ b/arch/arm64/core/irq_manage.c @@ -18,7 +18,7 @@ #include #include -void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf); +void z_arm64_fatal_error(unsigned int reason, struct arch_esf *esf); #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) /* diff --git a/arch/arm64/core/mmu.c b/arch/arm64/core/mmu.c index 2260d22c101f73..946d95a56a4eb0 100644 --- a/arch/arm64/core/mmu.c +++ b/arch/arm64/core/mmu.c @@ -28,9 +28,13 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); static uint64_t xlat_tables[CONFIG_MAX_XLAT_TABLES * Ln_XLAT_NUM_ENTRIES] __aligned(Ln_XLAT_NUM_ENTRIES * sizeof(uint64_t)); -static uint16_t xlat_use_count[CONFIG_MAX_XLAT_TABLES]; +static int xlat_use_count[CONFIG_MAX_XLAT_TABLES]; static struct k_spinlock xlat_lock; +/* Usage count value range */ +#define XLAT_PTE_COUNT_MASK GENMASK(15, 0) +#define XLAT_REF_COUNT_UNIT BIT(16) + /* Returns a reference to a free table */ static uint64_t *new_table(void) { @@ -39,9 +43,9 @@ static uint64_t *new_table(void) /* Look for a free table. */ for (i = 0U; i < CONFIG_MAX_XLAT_TABLES; i++) { - if (xlat_use_count[i] == 0U) { + if (xlat_use_count[i] == 0) { table = &xlat_tables[i * Ln_XLAT_NUM_ENTRIES]; - xlat_use_count[i] = 1U; + xlat_use_count[i] = XLAT_REF_COUNT_UNIT; MMU_DEBUG("allocating table [%d]%p\n", i, table); return table; } @@ -59,31 +63,74 @@ static inline unsigned int table_index(uint64_t *pte) return i; } -/* Makes a table free for reuse. */ -static void free_table(uint64_t *table) +/* Adjusts usage count and returns current count. */ +static int table_usage(uint64_t *table, int adjustment) { unsigned int i = table_index(table); + int prev_count = xlat_use_count[i]; + int new_count = prev_count + adjustment; - MMU_DEBUG("freeing table [%d]%p\n", i, table); - __ASSERT(xlat_use_count[i] == 1U, "table still in use"); - xlat_use_count[i] = 0U; + if (IS_ENABLED(DUMP_PTE) || new_count == 0) { + MMU_DEBUG("table [%d]%p: usage %#x -> %#x\n", i, table, prev_count, new_count); + } + + __ASSERT(new_count >= 0, + "table use count underflow"); + __ASSERT(new_count == 0 || new_count >= XLAT_REF_COUNT_UNIT, + "table in use with no reference to it"); + __ASSERT((new_count & XLAT_PTE_COUNT_MASK) <= Ln_XLAT_NUM_ENTRIES, + "table PTE count overflow"); + + xlat_use_count[i] = new_count; + return new_count; } -/* Adjusts usage count and returns current count. */ -static int table_usage(uint64_t *table, int adjustment) +static inline void inc_table_ref(uint64_t *table) { - unsigned int i = table_index(table); + table_usage(table, XLAT_REF_COUNT_UNIT); +} - xlat_use_count[i] += adjustment; - __ASSERT(xlat_use_count[i] > 0, "usage count underflow"); - return xlat_use_count[i]; +static inline void dec_table_ref(uint64_t *table) +{ + int ref_unit = XLAT_REF_COUNT_UNIT; + + table_usage(table, -ref_unit); } static inline bool is_table_unused(uint64_t *table) { - return table_usage(table, 0) == 1; + return (table_usage(table, 0) & XLAT_PTE_COUNT_MASK) == 0; +} + +#ifdef CONFIG_TEST +/* Hooks to let test code peek at table states */ + +int arm64_mmu_nb_free_tables(void) +{ + int count = 0; + + for (int i = 0; i < CONFIG_MAX_XLAT_TABLES; i++) { + if (xlat_use_count[i] == 0) { + count++; + } + } + + return count; +} + +int arm64_mmu_tables_total_usage(void) +{ + int count = 0; + + for (int i = 0; i < CONFIG_MAX_XLAT_TABLES; i++) { + count += xlat_use_count[i]; + } + + return count; } +#endif /* CONFIG_TEST */ + static inline bool is_free_desc(uint64_t desc) { return (desc & PTE_DESC_TYPE_MASK) == PTE_INVALID_DESC; @@ -225,7 +272,6 @@ static uint64_t *expand_to_table(uint64_t *pte, unsigned int level) /* Link the new table in place of the pte it replaces */ set_pte_table_desc(pte, table, level); - table_usage(table, 1); return table; } @@ -300,7 +346,7 @@ static int set_mapping(struct arm_mmu_ptables *ptables, /* recursively free unused tables if any */ while (level != BASE_XLAT_LEVEL && is_table_unused(pte)) { - free_table(pte); + dec_table_ref(pte); pte = ptes[--level]; set_pte_block_desc(pte, 0, level); table_usage(pte, -1); @@ -347,8 +393,8 @@ static uint64_t *dup_table(uint64_t *src_table, unsigned int level) } dst_table[i] = src_table[i]; - if (is_table_desc(src_table[i], level)) { - table_usage(pte_desc_table(src_table[i]), 1); + if (is_table_desc(dst_table[i], level)) { + inc_table_ref(pte_desc_table(dst_table[i])); } if (!is_free_desc(dst_table[i])) { table_usage(dst_table, 1); @@ -388,8 +434,7 @@ static int privatize_table(uint64_t *dst_table, uint64_t *src_table, return -ENOMEM; } set_pte_table_desc(&dst_table[i], dst_subtable, level); - table_usage(dst_subtable, 1); - table_usage(src_subtable, -1); + dec_table_ref(src_subtable); } ret = privatize_table(dst_subtable, src_subtable, @@ -436,15 +481,14 @@ static void discard_table(uint64_t *table, unsigned int level) for (i = 0U; i < Ln_XLAT_NUM_ENTRIES; i++) { if (is_table_desc(table[i], level)) { - table_usage(pte_desc_table(table[i]), -1); discard_table(pte_desc_table(table[i]), level + 1); + dec_table_ref(pte_desc_table(table[i])); } if (!is_free_desc(table[i])) { table[i] = 0U; table_usage(table, -1); } } - free_table(table); } static int globalize_table(uint64_t *dst_table, uint64_t *src_table, @@ -497,15 +541,15 @@ static int globalize_table(uint64_t *dst_table, uint64_t *src_table, table_usage(dst_table, -1); } if (is_table_desc(src_table[i], level)) { - table_usage(pte_desc_table(src_table[i]), 1); + inc_table_ref(pte_desc_table(src_table[i])); } dst_table[i] = src_table[i]; debug_show_pte(&dst_table[i], level); if (old_table) { /* we can discard the whole branch */ - table_usage(old_table, -1); discard_table(old_table, level + 1); + dec_table_ref(old_table); } } diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index 8777c400766fce..bbb7f9634317d8 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -180,7 +181,7 @@ void arch_secondary_cpu_init(int cpu_num) #ifdef CONFIG_SMP -static void broadcast_ipi(unsigned int ipi) +static void send_ipi(unsigned int ipi, uint32_t cpu_bitmap) { uint64_t mpidr = MPIDR_TO_CORE(GET_MPIDR()); @@ -190,6 +191,10 @@ static void broadcast_ipi(unsigned int ipi) unsigned int num_cpus = arch_num_cpus(); for (int i = 0; i < num_cpus; i++) { + if ((cpu_bitmap & BIT(i)) == 0) { + continue; + } + uint64_t target_mpidr = cpu_map[i]; uint8_t aff0; @@ -209,10 +214,14 @@ void sched_ipi_handler(const void *unused) z_sched_ipi(); } -/* arch implementation of sched_ipi */ -void arch_sched_ipi(void) +void arch_sched_broadcast_ipi(void) +{ + send_ipi(SGI_SCHED_IPI, IPI_ALL_CPUS_MASK); +} + +void arch_sched_directed_ipi(uint32_t cpu_bitmap) { - broadcast_ipi(SGI_SCHED_IPI); + send_ipi(SGI_SCHED_IPI, cpu_bitmap); } #ifdef CONFIG_USERSPACE @@ -232,7 +241,7 @@ void mem_cfg_ipi_handler(const void *unused) void z_arm64_mem_cfg_ipi(void) { - broadcast_ipi(SGI_MMCFG_IPI); + send_ipi(SGI_MMCFG_IPI, IPI_ALL_CPUS_MASK); } #endif @@ -302,6 +311,5 @@ int arch_smp_init(void) return 0; } -SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index a0269501c19ac0..18f49945eda495 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -87,7 +87,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, void *p1, void *p2, void *p3) { extern void z_arm64_exit_exc(void); - z_arch_esf_t *pInitCtx; + struct arch_esf *pInitCtx; /* * Clean the thread->arch to avoid unexpected behavior because the @@ -102,7 +102,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * dropping into EL0. */ - pInitCtx = Z_STACK_PTR_TO_FRAME(struct __esf, stack_ptr); + pInitCtx = Z_STACK_PTR_TO_FRAME(struct arch_esf, stack_ptr); pInitCtx->x0 = (uint64_t)entry; pInitCtx->x1 = (uint64_t)p1; diff --git a/arch/arm64/include/kernel_arch_data.h b/arch/arm64/include/kernel_arch_data.h index ec781fc902dd52..8b607c1dbf47d2 100644 --- a/arch/arm64/include/kernel_arch_data.h +++ b/arch/arm64/include/kernel_arch_data.h @@ -36,7 +36,7 @@ extern "C" { #endif -typedef struct __esf _esf_t; +typedef struct arch_esf _esf_t; typedef struct __basic_sf _basic_sf_t; #ifdef __cplusplus diff --git a/arch/arm64/include/kernel_arch_func.h b/arch/arm64/include/kernel_arch_func.h index a5c3d59d87a6ff..cc91abc3b49f3f 100644 --- a/arch/arm64/include/kernel_arch_func.h +++ b/arch/arm64/include/kernel_arch_func.h @@ -43,7 +43,7 @@ static inline void arch_switch(void *switch_to, void **switched_from) z_arm64_context_switch(new, old); } -extern void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf); +extern void z_arm64_fatal_error(unsigned int reason, struct arch_esf *esf); extern void z_arm64_set_ttbr0(uint64_t ttbr0); extern void z_arm64_mem_cfg_ipi(void); diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c index 050597b7b1d82b..b3bdd136e0c20a 100644 --- a/arch/common/isr_tables.c +++ b/arch/common/isr_tables.c @@ -90,7 +90,7 @@ uintptr_t __irq_vector_table _irq_vector_table[IRQ_TABLE_SIZE] = { #ifdef CONFIG_GEN_SW_ISR_TABLE struct _isr_table_entry __sw_isr_table _sw_isr_table[IRQ_TABLE_SIZE] = { [0 ...(IRQ_TABLE_SIZE - 1)] = {(const void *)0x42, - (void *)&z_irq_spurious}, + &z_irq_spurious}, }; #endif diff --git a/arch/mips/core/fatal.c b/arch/mips/core/fatal.c index 16011241666ab2..a53e5bb0f5e6cc 100644 --- a/arch/mips/core/fatal.c +++ b/arch/mips/core/fatal.c @@ -9,7 +9,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); FUNC_NORETURN void z_mips_fatal_error(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { #ifdef CONFIG_EXCEPTION_DEBUG if (esf != NULL) { @@ -84,7 +84,7 @@ static char *cause_str(unsigned long cause) } } -void _Fault(z_arch_esf_t *esf) +void _Fault(struct arch_esf *esf) { unsigned long cause; diff --git a/arch/mips/core/isr.S b/arch/mips/core/isr.S index 44babb2149be23..86d05d19833567 100644 --- a/arch/mips/core/isr.S +++ b/arch/mips/core/isr.S @@ -14,7 +14,7 @@ #include #include -#define ESF_O(FIELD) __z_arch_esf_t_##FIELD##_OFFSET +#define ESF_O(FIELD) __struct_arch_esf_##FIELD##_OFFSET #define THREAD_O(FIELD) _thread_offset_to_##FIELD /* Convenience macros for loading/storing register states. */ @@ -58,12 +58,12 @@ op v1, ESF_O(v1)(sp) ; #define STORE_CALLER_SAVED() \ - addi sp, sp, -__z_arch_esf_t_SIZEOF ;\ + addi sp, sp, -__struct_arch_esf_SIZEOF ;\ DO_CALLER_SAVED(OP_STOREREG) ; #define LOAD_CALLER_SAVED() \ DO_CALLER_SAVED(OP_LOADREG) ;\ - addi sp, sp, __z_arch_esf_t_SIZEOF ; + addi sp, sp, __struct_arch_esf_SIZEOF ; /* imports */ GTEXT(_Fault) diff --git a/arch/mips/core/offsets/offsets.c b/arch/mips/core/offsets/offsets.c index 24b477e9558ea6..c70ce3c39fc7eb 100644 --- a/arch/mips/core/offsets/offsets.c +++ b/arch/mips/core/offsets/offsets.c @@ -23,32 +23,32 @@ GEN_OFFSET_SYM(_callee_saved_t, s6); GEN_OFFSET_SYM(_callee_saved_t, s7); GEN_OFFSET_SYM(_callee_saved_t, s8); -GEN_OFFSET_SYM(z_arch_esf_t, ra); -GEN_OFFSET_SYM(z_arch_esf_t, gp); -GEN_OFFSET_SYM(z_arch_esf_t, t0); -GEN_OFFSET_SYM(z_arch_esf_t, t1); -GEN_OFFSET_SYM(z_arch_esf_t, t2); -GEN_OFFSET_SYM(z_arch_esf_t, t3); -GEN_OFFSET_SYM(z_arch_esf_t, t4); -GEN_OFFSET_SYM(z_arch_esf_t, t5); -GEN_OFFSET_SYM(z_arch_esf_t, t6); -GEN_OFFSET_SYM(z_arch_esf_t, t7); -GEN_OFFSET_SYM(z_arch_esf_t, t8); -GEN_OFFSET_SYM(z_arch_esf_t, t9); -GEN_OFFSET_SYM(z_arch_esf_t, a0); -GEN_OFFSET_SYM(z_arch_esf_t, a1); -GEN_OFFSET_SYM(z_arch_esf_t, a2); -GEN_OFFSET_SYM(z_arch_esf_t, a3); -GEN_OFFSET_SYM(z_arch_esf_t, v0); -GEN_OFFSET_SYM(z_arch_esf_t, v1); -GEN_OFFSET_SYM(z_arch_esf_t, at); -GEN_OFFSET_SYM(z_arch_esf_t, epc); -GEN_OFFSET_SYM(z_arch_esf_t, badvaddr); -GEN_OFFSET_SYM(z_arch_esf_t, hi); -GEN_OFFSET_SYM(z_arch_esf_t, lo); -GEN_OFFSET_SYM(z_arch_esf_t, status); -GEN_OFFSET_SYM(z_arch_esf_t, cause); +GEN_OFFSET_STRUCT(arch_esf, ra); +GEN_OFFSET_STRUCT(arch_esf, gp); +GEN_OFFSET_STRUCT(arch_esf, t0); +GEN_OFFSET_STRUCT(arch_esf, t1); +GEN_OFFSET_STRUCT(arch_esf, t2); +GEN_OFFSET_STRUCT(arch_esf, t3); +GEN_OFFSET_STRUCT(arch_esf, t4); +GEN_OFFSET_STRUCT(arch_esf, t5); +GEN_OFFSET_STRUCT(arch_esf, t6); +GEN_OFFSET_STRUCT(arch_esf, t7); +GEN_OFFSET_STRUCT(arch_esf, t8); +GEN_OFFSET_STRUCT(arch_esf, t9); +GEN_OFFSET_STRUCT(arch_esf, a0); +GEN_OFFSET_STRUCT(arch_esf, a1); +GEN_OFFSET_STRUCT(arch_esf, a2); +GEN_OFFSET_STRUCT(arch_esf, a3); +GEN_OFFSET_STRUCT(arch_esf, v0); +GEN_OFFSET_STRUCT(arch_esf, v1); +GEN_OFFSET_STRUCT(arch_esf, at); +GEN_OFFSET_STRUCT(arch_esf, epc); +GEN_OFFSET_STRUCT(arch_esf, badvaddr); +GEN_OFFSET_STRUCT(arch_esf, hi); +GEN_OFFSET_STRUCT(arch_esf, lo); +GEN_OFFSET_STRUCT(arch_esf, status); +GEN_OFFSET_STRUCT(arch_esf, cause); -GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, STACK_ROUND_UP(sizeof(z_arch_esf_t))); +GEN_ABSOLUTE_SYM(__struct_arch_esf_SIZEOF, STACK_ROUND_UP(sizeof(struct arch_esf))); GEN_ABS_SYM_END diff --git a/arch/mips/core/thread.c b/arch/mips/core/thread.c index e551674d5215d8..7966ff462f5fd2 100644 --- a/arch/mips/core/thread.c +++ b/arch/mips/core/thread.c @@ -19,11 +19,11 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *stack_ptr, k_thread_entry_t entry, void *p1, void *p2, void *p3) { - struct __esf *stack_init; + struct arch_esf *stack_init; /* Initial stack frame for thread */ - stack_init = (struct __esf *)Z_STACK_PTR_ALIGN( - Z_STACK_PTR_TO_FRAME(struct __esf, stack_ptr) + stack_init = (struct arch_esf *)Z_STACK_PTR_ALIGN( + Z_STACK_PTR_TO_FRAME(struct arch_esf, stack_ptr) ); /* Setup the initial stack frame */ diff --git a/arch/mips/include/kernel_arch_func.h b/arch/mips/include/kernel_arch_func.h index ad89f75dd7f147..b01cc1a4c65daa 100644 --- a/arch/mips/include/kernel_arch_func.h +++ b/arch/mips/include/kernel_arch_func.h @@ -35,7 +35,7 @@ arch_thread_return_value_set(struct k_thread *thread, unsigned int value) } FUNC_NORETURN void z_mips_fatal_error(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); static inline bool arch_is_in_isr(void) { diff --git a/arch/nios2/core/exception.S b/arch/nios2/core/exception.S index 6b003262bb04df..ab2d3463dd4378 100644 --- a/arch/nios2/core/exception.S +++ b/arch/nios2/core/exception.S @@ -35,35 +35,35 @@ GTEXT(_offload_routine) */ SECTION_FUNC(exception.entry, _exception) /* Reserve thread stack space for saving context */ - subi sp, sp, __z_arch_esf_t_SIZEOF + subi sp, sp, __struct_arch_esf_SIZEOF /* Preserve all caller-saved registers onto the thread's stack */ - stw ra, __z_arch_esf_t_ra_OFFSET(sp) - stw r1, __z_arch_esf_t_r1_OFFSET(sp) - stw r2, __z_arch_esf_t_r2_OFFSET(sp) - stw r3, __z_arch_esf_t_r3_OFFSET(sp) - stw r4, __z_arch_esf_t_r4_OFFSET(sp) - stw r5, __z_arch_esf_t_r5_OFFSET(sp) - stw r6, __z_arch_esf_t_r6_OFFSET(sp) - stw r7, __z_arch_esf_t_r7_OFFSET(sp) - stw r8, __z_arch_esf_t_r8_OFFSET(sp) - stw r9, __z_arch_esf_t_r9_OFFSET(sp) - stw r10, __z_arch_esf_t_r10_OFFSET(sp) - stw r11, __z_arch_esf_t_r11_OFFSET(sp) - stw r12, __z_arch_esf_t_r12_OFFSET(sp) - stw r13, __z_arch_esf_t_r13_OFFSET(sp) - stw r14, __z_arch_esf_t_r14_OFFSET(sp) - stw r15, __z_arch_esf_t_r15_OFFSET(sp) + stw ra, __struct_arch_esf_ra_OFFSET(sp) + stw r1, __struct_arch_esf_r1_OFFSET(sp) + stw r2, __struct_arch_esf_r2_OFFSET(sp) + stw r3, __struct_arch_esf_r3_OFFSET(sp) + stw r4, __struct_arch_esf_r4_OFFSET(sp) + stw r5, __struct_arch_esf_r5_OFFSET(sp) + stw r6, __struct_arch_esf_r6_OFFSET(sp) + stw r7, __struct_arch_esf_r7_OFFSET(sp) + stw r8, __struct_arch_esf_r8_OFFSET(sp) + stw r9, __struct_arch_esf_r9_OFFSET(sp) + stw r10, __struct_arch_esf_r10_OFFSET(sp) + stw r11, __struct_arch_esf_r11_OFFSET(sp) + stw r12, __struct_arch_esf_r12_OFFSET(sp) + stw r13, __struct_arch_esf_r13_OFFSET(sp) + stw r14, __struct_arch_esf_r14_OFFSET(sp) + stw r15, __struct_arch_esf_r15_OFFSET(sp) /* Store value of estatus control register */ rdctl et, estatus - stw et, __z_arch_esf_t_estatus_OFFSET(sp) + stw et, __struct_arch_esf_estatus_OFFSET(sp) /* ea-4 is the address of the instruction when the exception happened, * put this in the stack frame as well */ addi r15, ea, -4 - stw r15, __z_arch_esf_t_instr_OFFSET(sp) + stw r15, __struct_arch_esf_instr_OFFSET(sp) /* Figure out whether we are here because of an interrupt or an * exception. If an interrupt, switch stacks and enter IRQ handling @@ -157,7 +157,7 @@ not_interrupt: * * We earlier put ea - 4 in the stack frame, replace it with just ea */ - stw ea, __z_arch_esf_t_instr_OFFSET(sp) + stw ea, __struct_arch_esf_instr_OFFSET(sp) #ifdef CONFIG_IRQ_OFFLOAD /* Check the contents of _offload_routine. If non-NULL, jump into @@ -193,35 +193,35 @@ _exception_exit: * and return to the interrupted context */ /* Return address from the exception */ - ldw ea, __z_arch_esf_t_instr_OFFSET(sp) + ldw ea, __struct_arch_esf_instr_OFFSET(sp) /* Restore estatus * XXX is this right??? */ - ldw r5, __z_arch_esf_t_estatus_OFFSET(sp) + ldw r5, __struct_arch_esf_estatus_OFFSET(sp) wrctl estatus, r5 /* Restore caller-saved registers */ - ldw ra, __z_arch_esf_t_ra_OFFSET(sp) - ldw r1, __z_arch_esf_t_r1_OFFSET(sp) - ldw r2, __z_arch_esf_t_r2_OFFSET(sp) - ldw r3, __z_arch_esf_t_r3_OFFSET(sp) - ldw r4, __z_arch_esf_t_r4_OFFSET(sp) - ldw r5, __z_arch_esf_t_r5_OFFSET(sp) - ldw r6, __z_arch_esf_t_r6_OFFSET(sp) - ldw r7, __z_arch_esf_t_r7_OFFSET(sp) - ldw r8, __z_arch_esf_t_r8_OFFSET(sp) - ldw r9, __z_arch_esf_t_r9_OFFSET(sp) - ldw r10, __z_arch_esf_t_r10_OFFSET(sp) - ldw r11, __z_arch_esf_t_r11_OFFSET(sp) - ldw r12, __z_arch_esf_t_r12_OFFSET(sp) - ldw r13, __z_arch_esf_t_r13_OFFSET(sp) - ldw r14, __z_arch_esf_t_r14_OFFSET(sp) - ldw r15, __z_arch_esf_t_r15_OFFSET(sp) + ldw ra, __struct_arch_esf_ra_OFFSET(sp) + ldw r1, __struct_arch_esf_r1_OFFSET(sp) + ldw r2, __struct_arch_esf_r2_OFFSET(sp) + ldw r3, __struct_arch_esf_r3_OFFSET(sp) + ldw r4, __struct_arch_esf_r4_OFFSET(sp) + ldw r5, __struct_arch_esf_r5_OFFSET(sp) + ldw r6, __struct_arch_esf_r6_OFFSET(sp) + ldw r7, __struct_arch_esf_r7_OFFSET(sp) + ldw r8, __struct_arch_esf_r8_OFFSET(sp) + ldw r9, __struct_arch_esf_r9_OFFSET(sp) + ldw r10, __struct_arch_esf_r10_OFFSET(sp) + ldw r11, __struct_arch_esf_r11_OFFSET(sp) + ldw r12, __struct_arch_esf_r12_OFFSET(sp) + ldw r13, __struct_arch_esf_r13_OFFSET(sp) + ldw r14, __struct_arch_esf_r14_OFFSET(sp) + ldw r15, __struct_arch_esf_r15_OFFSET(sp) /* Put the stack pointer back where it was when we entered * exception state */ - addi sp, sp, __z_arch_esf_t_SIZEOF + addi sp, sp, __struct_arch_esf_SIZEOF /* All done, copy estatus into status and transfer to ea */ eret diff --git a/arch/nios2/core/fatal.c b/arch/nios2/core/fatal.c index ac64b5bc309447..b531bb41e1789c 100644 --- a/arch/nios2/core/fatal.c +++ b/arch/nios2/core/fatal.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { #if CONFIG_EXCEPTION_DEBUG if (esf != NULL) { @@ -102,7 +102,7 @@ static char *cause_str(uint32_t cause_code) } #endif -FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) +FUNC_NORETURN void _Fault(const struct arch_esf *esf) { #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) /* Unfortunately, completely unavailable on Nios II/e cores */ diff --git a/arch/nios2/core/offsets/offsets.c b/arch/nios2/core/offsets/offsets.c index 8f3b3f748c1a1a..9d381d87446c12 100644 --- a/arch/nios2/core/offsets/offsets.c +++ b/arch/nios2/core/offsets/offsets.c @@ -44,24 +44,24 @@ GEN_OFFSET_SYM(_callee_saved_t, sp); GEN_OFFSET_SYM(_callee_saved_t, key); GEN_OFFSET_SYM(_callee_saved_t, retval); -GEN_OFFSET_SYM(z_arch_esf_t, ra); -GEN_OFFSET_SYM(z_arch_esf_t, r1); -GEN_OFFSET_SYM(z_arch_esf_t, r2); -GEN_OFFSET_SYM(z_arch_esf_t, r3); -GEN_OFFSET_SYM(z_arch_esf_t, r4); -GEN_OFFSET_SYM(z_arch_esf_t, r5); -GEN_OFFSET_SYM(z_arch_esf_t, r6); -GEN_OFFSET_SYM(z_arch_esf_t, r7); -GEN_OFFSET_SYM(z_arch_esf_t, r8); -GEN_OFFSET_SYM(z_arch_esf_t, r9); -GEN_OFFSET_SYM(z_arch_esf_t, r10); -GEN_OFFSET_SYM(z_arch_esf_t, r11); -GEN_OFFSET_SYM(z_arch_esf_t, r12); -GEN_OFFSET_SYM(z_arch_esf_t, r13); -GEN_OFFSET_SYM(z_arch_esf_t, r14); -GEN_OFFSET_SYM(z_arch_esf_t, r15); -GEN_OFFSET_SYM(z_arch_esf_t, estatus); -GEN_OFFSET_SYM(z_arch_esf_t, instr); -GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, sizeof(z_arch_esf_t)); +GEN_OFFSET_STRUCT(arch_esf, ra); +GEN_OFFSET_STRUCT(arch_esf, r1); +GEN_OFFSET_STRUCT(arch_esf, r2); +GEN_OFFSET_STRUCT(arch_esf, r3); +GEN_OFFSET_STRUCT(arch_esf, r4); +GEN_OFFSET_STRUCT(arch_esf, r5); +GEN_OFFSET_STRUCT(arch_esf, r6); +GEN_OFFSET_STRUCT(arch_esf, r7); +GEN_OFFSET_STRUCT(arch_esf, r8); +GEN_OFFSET_STRUCT(arch_esf, r9); +GEN_OFFSET_STRUCT(arch_esf, r10); +GEN_OFFSET_STRUCT(arch_esf, r11); +GEN_OFFSET_STRUCT(arch_esf, r12); +GEN_OFFSET_STRUCT(arch_esf, r13); +GEN_OFFSET_STRUCT(arch_esf, r14); +GEN_OFFSET_STRUCT(arch_esf, r15); +GEN_OFFSET_STRUCT(arch_esf, estatus); +GEN_OFFSET_STRUCT(arch_esf, instr); +GEN_ABSOLUTE_SYM(__struct_arch_esf_SIZEOF, sizeof(struct arch_esf)); GEN_ABS_SYM_END diff --git a/arch/nios2/include/kernel_arch_func.h b/arch/nios2/include/kernel_arch_func.h index 2f2030c1c731cb..2df268a1c62454 100644 --- a/arch/nios2/include/kernel_arch_func.h +++ b/arch/nios2/include/kernel_arch_func.h @@ -39,7 +39,7 @@ arch_thread_return_value_set(struct k_thread *thread, unsigned int value) } FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); static inline bool arch_is_in_isr(void) { diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 0993189b99ccac..76ea74026ac3d2 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -88,7 +88,7 @@ config RISCV_SOC_HAS_ISR_STACKING guarded by !_ASMLANGUAGE. The ESF should be defined to account for the hardware stacked registers in the proper order as they are saved on the stack by the hardware, and the registers saved by the - software macros. The structure must be called '__esf'. + software macros. The structure must be called 'struct arch_esf'. config RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING bool @@ -369,6 +369,7 @@ config ARCH_IRQ_VECTOR_TABLE_ALIGN config RISCV_TRAP_HANDLER_ALIGNMENT int "Alignment of RISC-V trap handler in bytes" + default 64 if RISCV_HAS_CLIC default 4 help This value configures the alignment of RISC-V trap handling diff --git a/arch/riscv/core/coredump.c b/arch/riscv/core/coredump.c index f232816433a088..70d7a9976d4ad2 100644 --- a/arch/riscv/core/coredump.c +++ b/arch/riscv/core/coredump.c @@ -67,7 +67,7 @@ struct riscv_arch_block { */ static struct riscv_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { struct coredump_arch_hdr_t hdr = { .id = COREDUMP_ARCH_HDR_ID, diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index bd4ed3dca36bcf..d6dd4bc38869a5 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -30,15 +30,15 @@ static const struct z_exc_handle exceptions[] = { #endif /* Stack trace function */ -void z_riscv_unwind_stack(const z_arch_esf_t *esf); +void z_riscv_unwind_stack(const struct arch_esf *esf); -uintptr_t z_riscv_get_sp_before_exc(const z_arch_esf_t *esf) +uintptr_t z_riscv_get_sp_before_exc(const struct arch_esf *esf) { /* * Kernel stack pointer prior this exception i.e. before * storing the exception stack frame. */ - uintptr_t sp = (uintptr_t)esf + sizeof(z_arch_esf_t); + uintptr_t sp = (uintptr_t)esf + sizeof(struct arch_esf); #ifdef CONFIG_USERSPACE if ((esf->mstatus & MSTATUS_MPP) == PRV_U) { @@ -54,12 +54,12 @@ uintptr_t z_riscv_get_sp_before_exc(const z_arch_esf_t *esf) } FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { z_riscv_fatal_error_csf(reason, esf, NULL); } -FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf, +FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const struct arch_esf *esf, const _callee_saved_t *csf) { #ifdef CONFIG_EXCEPTION_DEBUG @@ -152,14 +152,14 @@ static char *cause_str(unsigned long cause) } } -static bool bad_stack_pointer(z_arch_esf_t *esf) +static bool bad_stack_pointer(struct arch_esf *esf) { #ifdef CONFIG_PMP_STACK_GUARD /* * Check if the kernel stack pointer prior this exception (before * storing the exception stack frame) was in the stack guard area. */ - uintptr_t sp = (uintptr_t)esf + sizeof(z_arch_esf_t); + uintptr_t sp = (uintptr_t)esf + sizeof(struct arch_esf); #ifdef CONFIG_USERSPACE if (_current->arch.priv_stack_start != 0 && @@ -197,7 +197,7 @@ static bool bad_stack_pointer(z_arch_esf_t *esf) return false; } -void _Fault(z_arch_esf_t *esf) +void _Fault(struct arch_esf *esf) { #ifdef CONFIG_USERSPACE /* @@ -249,7 +249,7 @@ FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) void z_impl_user_fault(unsigned int reason) { - z_arch_esf_t *oops_esf = _current->syscall_frame; + struct arch_esf *oops_esf = _current->syscall_frame; if (((_current->base.user_options & K_USER) != 0) && reason != K_ERR_STACK_CHK_FAIL) { diff --git a/arch/riscv/core/fpu.c b/arch/riscv/core/fpu.c index da5d07b3146404..318e97e0002a9f 100644 --- a/arch/riscv/core/fpu.c +++ b/arch/riscv/core/fpu.c @@ -204,7 +204,7 @@ void z_riscv_fpu_enter_exc(void) * Note that the exception depth count was not incremented before this call * as no further exceptions are expected before returning to normal mode. */ -void z_riscv_fpu_trap(z_arch_esf_t *esf) +void z_riscv_fpu_trap(struct arch_esf *esf) { __ASSERT((esf->mstatus & MSTATUS_FS) == 0 && (csr_read(mstatus) & MSTATUS_FS) == 0, @@ -293,7 +293,7 @@ static bool fpu_access_allowed(unsigned int exc_update_level) * This is called on every exception exit except for z_riscv_fpu_trap(). * In that case the exception level of interest is 1 (soon to be 0). */ -void z_riscv_fpu_exit_exc(z_arch_esf_t *esf) +void z_riscv_fpu_exit_exc(struct arch_esf *esf) { if (fpu_access_allowed(1)) { esf->mstatus &= ~MSTATUS_FS; diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index e9a3d523127a42..8a829fd66b17fe 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -24,22 +24,22 @@ /* Convenience macro for loading/storing register states. */ #define DO_CALLER_SAVED(op) \ - RV_E( op t0, __z_arch_esf_t_t0_OFFSET(sp) );\ - RV_E( op t1, __z_arch_esf_t_t1_OFFSET(sp) );\ - RV_E( op t2, __z_arch_esf_t_t2_OFFSET(sp) );\ - RV_I( op t3, __z_arch_esf_t_t3_OFFSET(sp) );\ - RV_I( op t4, __z_arch_esf_t_t4_OFFSET(sp) );\ - RV_I( op t5, __z_arch_esf_t_t5_OFFSET(sp) );\ - RV_I( op t6, __z_arch_esf_t_t6_OFFSET(sp) );\ - RV_E( op a0, __z_arch_esf_t_a0_OFFSET(sp) );\ - RV_E( op a1, __z_arch_esf_t_a1_OFFSET(sp) );\ - RV_E( op a2, __z_arch_esf_t_a2_OFFSET(sp) );\ - RV_E( op a3, __z_arch_esf_t_a3_OFFSET(sp) );\ - RV_E( op a4, __z_arch_esf_t_a4_OFFSET(sp) );\ - RV_E( op a5, __z_arch_esf_t_a5_OFFSET(sp) );\ - RV_I( op a6, __z_arch_esf_t_a6_OFFSET(sp) );\ - RV_I( op a7, __z_arch_esf_t_a7_OFFSET(sp) );\ - RV_E( op ra, __z_arch_esf_t_ra_OFFSET(sp) ) + RV_E( op t0, __struct_arch_esf_t0_OFFSET(sp) );\ + RV_E( op t1, __struct_arch_esf_t1_OFFSET(sp) );\ + RV_E( op t2, __struct_arch_esf_t2_OFFSET(sp) );\ + RV_I( op t3, __struct_arch_esf_t3_OFFSET(sp) );\ + RV_I( op t4, __struct_arch_esf_t4_OFFSET(sp) );\ + RV_I( op t5, __struct_arch_esf_t5_OFFSET(sp) );\ + RV_I( op t6, __struct_arch_esf_t6_OFFSET(sp) );\ + RV_E( op a0, __struct_arch_esf_a0_OFFSET(sp) );\ + RV_E( op a1, __struct_arch_esf_a1_OFFSET(sp) );\ + RV_E( op a2, __struct_arch_esf_a2_OFFSET(sp) );\ + RV_E( op a3, __struct_arch_esf_a3_OFFSET(sp) );\ + RV_E( op a4, __struct_arch_esf_a4_OFFSET(sp) );\ + RV_E( op a5, __struct_arch_esf_a5_OFFSET(sp) );\ + RV_I( op a6, __struct_arch_esf_a6_OFFSET(sp) );\ + RV_I( op a7, __struct_arch_esf_a7_OFFSET(sp) );\ + RV_E( op ra, __struct_arch_esf_ra_OFFSET(sp) ) #ifdef CONFIG_EXCEPTION_DEBUG /* Convenience macro for storing callee saved register [s0 - s11] states. */ @@ -157,7 +157,7 @@ SECTION_FUNC(exception.entry, _isr_wrapper) /* Save user stack value. Coming from user space, we know this * can't overflow the privileged stack. The esf will be allocated * later but it is safe to store our saved user sp here. */ - sr t0, (-__z_arch_esf_t_SIZEOF + __z_arch_esf_t_sp_OFFSET)(sp) + sr t0, (-__struct_arch_esf_SIZEOF + __struct_arch_esf_sp_OFFSET)(sp) /* Make sure tls pointer is sane */ lr t0, ___cpu_t_current_OFFSET(s0) @@ -180,21 +180,21 @@ SECTION_FUNC(exception.entry, _isr_wrapper) SOC_ISR_SW_STACKING #else /* Save caller-saved registers on current thread stack. */ - addi sp, sp, -__z_arch_esf_t_SIZEOF + addi sp, sp, -__struct_arch_esf_SIZEOF DO_CALLER_SAVED(sr) ; #endif /* CONFIG_RISCV_SOC_HAS_ISR_STACKING */ /* Save s0 in the esf and load it with &_current_cpu. */ - sr s0, __z_arch_esf_t_s0_OFFSET(sp) + sr s0, __struct_arch_esf_s0_OFFSET(sp) get_current_cpu s0 /* Save MEPC register */ csrr t0, mepc - sr t0, __z_arch_esf_t_mepc_OFFSET(sp) + sr t0, __struct_arch_esf_mepc_OFFSET(sp) /* Save MSTATUS register */ csrr t2, mstatus - sr t2, __z_arch_esf_t_mstatus_OFFSET(sp) + sr t2, __struct_arch_esf_mstatus_OFFSET(sp) #if defined(CONFIG_FPU_SHARING) /* determine if FPU access was disabled */ @@ -301,7 +301,7 @@ no_fp: /* increment _current->arch.exception_depth */ #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE /* Handle context saving at SOC level. */ - addi a0, sp, __z_arch_esf_t_soc_context_OFFSET + addi a0, sp, __struct_arch_esf_soc_context_OFFSET jal ra, __soc_save_context #endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ @@ -351,7 +351,7 @@ no_fp: /* increment _current->arch.exception_depth */ /* * Call _Fault to handle exception. - * Stack pointer is pointing to a z_arch_esf_t structure, pass it + * Stack pointer is pointing to a struct_arch_esf structure, pass it * to _Fault (via register a0). * If _Fault shall return, set return address to * no_reschedule to restore stack. @@ -370,9 +370,9 @@ is_kernel_syscall: * It's safe to always increment by 4, even with compressed * instructions, because the ecall instruction is always 4 bytes. */ - lr t0, __z_arch_esf_t_mepc_OFFSET(sp) + lr t0, __struct_arch_esf_mepc_OFFSET(sp) addi t0, t0, 4 - sr t0, __z_arch_esf_t_mepc_OFFSET(sp) + sr t0, __struct_arch_esf_mepc_OFFSET(sp) #ifdef CONFIG_PMP_STACK_GUARD /* Re-activate PMP for m-mode */ @@ -383,7 +383,7 @@ is_kernel_syscall: #endif /* Determine what to do. Operation code is in t0. */ - lr t0, __z_arch_esf_t_t0_OFFSET(sp) + lr t0, __struct_arch_esf_t0_OFFSET(sp) .if RV_ECALL_RUNTIME_EXCEPT != 0; .err; .endif beqz t0, do_fault @@ -396,8 +396,8 @@ is_kernel_syscall: #ifdef CONFIG_RISCV_ALWAYS_SWITCH_THROUGH_ECALL li t1, RV_ECALL_SCHEDULE bne t0, t1, skip_schedule - lr a0, __z_arch_esf_t_a0_OFFSET(sp) - lr a1, __z_arch_esf_t_a1_OFFSET(sp) + lr a0, __struct_arch_esf_a0_OFFSET(sp) + lr a1, __struct_arch_esf_a1_OFFSET(sp) j reschedule skip_schedule: #endif @@ -408,7 +408,7 @@ skip_schedule: do_fault: /* Handle RV_ECALL_RUNTIME_EXCEPT. Retrieve reason in a0, esf in A1. */ - lr a0, __z_arch_esf_t_a0_OFFSET(sp) + lr a0, __struct_arch_esf_a0_OFFSET(sp) 1: mv a1, sp #ifdef CONFIG_EXCEPTION_DEBUG @@ -431,8 +431,8 @@ do_irq_offload: * Routine pointer is in saved a0, argument in saved a1 * so we load them with a1/a0 (reversed). */ - lr a1, __z_arch_esf_t_a0_OFFSET(sp) - lr a0, __z_arch_esf_t_a1_OFFSET(sp) + lr a1, __struct_arch_esf_a0_OFFSET(sp) + lr a0, __struct_arch_esf_a1_OFFSET(sp) /* Increment _current_cpu->nested */ lw t1, ___cpu_t_nested_OFFSET(s0) @@ -474,18 +474,18 @@ is_user_syscall: * Same as for is_kernel_syscall: increment saved MEPC by 4 to * prevent triggering the same ecall again upon exiting the ISR. */ - lr t1, __z_arch_esf_t_mepc_OFFSET(sp) + lr t1, __struct_arch_esf_mepc_OFFSET(sp) addi t1, t1, 4 - sr t1, __z_arch_esf_t_mepc_OFFSET(sp) + sr t1, __struct_arch_esf_mepc_OFFSET(sp) /* Restore argument registers from user stack */ - lr a0, __z_arch_esf_t_a0_OFFSET(sp) - lr a1, __z_arch_esf_t_a1_OFFSET(sp) - lr a2, __z_arch_esf_t_a2_OFFSET(sp) - lr a3, __z_arch_esf_t_a3_OFFSET(sp) - lr a4, __z_arch_esf_t_a4_OFFSET(sp) - lr a5, __z_arch_esf_t_a5_OFFSET(sp) - lr t0, __z_arch_esf_t_t0_OFFSET(sp) + lr a0, __struct_arch_esf_a0_OFFSET(sp) + lr a1, __struct_arch_esf_a1_OFFSET(sp) + lr a2, __struct_arch_esf_a2_OFFSET(sp) + lr a3, __struct_arch_esf_a3_OFFSET(sp) + lr a4, __struct_arch_esf_a4_OFFSET(sp) + lr a5, __struct_arch_esf_a5_OFFSET(sp) + lr t0, __struct_arch_esf_t0_OFFSET(sp) #if defined(CONFIG_RISCV_ISA_RV32E) /* Stack alignment for RV32E is 4 bytes */ addi sp, sp, -4 @@ -519,7 +519,7 @@ valid_syscall_id: #endif /* CONFIG_RISCV_ISA_RV32E */ /* Update a0 (return value) on the stack */ - sr a0, __z_arch_esf_t_a0_OFFSET(sp) + sr a0, __struct_arch_esf_a0_OFFSET(sp) /* Disable IRQs again before leaving */ csrc mstatus, MSTATUS_IEN @@ -534,7 +534,7 @@ is_interrupt: * If we came from userspace then we need to reconfigure the * PMP for kernel mode stack guard. */ - lr t0, __z_arch_esf_t_mstatus_OFFSET(sp) + lr t0, __struct_arch_esf_mstatus_OFFSET(sp) li t1, MSTATUS_MPP and t0, t0, t1 bnez t0, 1f @@ -665,7 +665,7 @@ no_reschedule: #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE /* Restore context at SOC level */ - addi a0, sp, __z_arch_esf_t_soc_context_OFFSET + addi a0, sp, __struct_arch_esf_soc_context_OFFSET jal ra, __soc_restore_context #endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ @@ -683,8 +683,8 @@ fp_trap_exit: #endif /* Restore MEPC and MSTATUS registers */ - lr t0, __z_arch_esf_t_mepc_OFFSET(sp) - lr t2, __z_arch_esf_t_mstatus_OFFSET(sp) + lr t0, __struct_arch_esf_mepc_OFFSET(sp) + lr t2, __struct_arch_esf_mstatus_OFFSET(sp) csrw mepc, t0 csrw mstatus, t2 @@ -711,7 +711,7 @@ fp_trap_exit: sb t1, %tprel_lo(is_user_mode)(t0) /* preserve stack pointer for next exception entry */ - add t0, sp, __z_arch_esf_t_SIZEOF + add t0, sp, __struct_arch_esf_SIZEOF sr t0, _curr_cpu_arch_user_exc_sp(s0) j 2f @@ -720,13 +720,13 @@ fp_trap_exit: * We are returning to kernel mode. Store the stack pointer to * be re-loaded further down. */ - addi t0, sp, __z_arch_esf_t_SIZEOF - sr t0, __z_arch_esf_t_sp_OFFSET(sp) + addi t0, sp, __struct_arch_esf_SIZEOF + sr t0, __struct_arch_esf_sp_OFFSET(sp) 2: #endif /* Restore s0 (it is no longer ours) */ - lr s0, __z_arch_esf_t_s0_OFFSET(sp) + lr s0, __struct_arch_esf_s0_OFFSET(sp) #ifdef CONFIG_RISCV_SOC_HAS_ISR_STACKING SOC_ISR_SW_UNSTACKING @@ -736,10 +736,10 @@ fp_trap_exit: #ifdef CONFIG_USERSPACE /* retrieve saved stack pointer */ - lr sp, __z_arch_esf_t_sp_OFFSET(sp) + lr sp, __struct_arch_esf_sp_OFFSET(sp) #else /* remove esf from the stack */ - addi sp, sp, __z_arch_esf_t_SIZEOF + addi sp, sp, __struct_arch_esf_SIZEOF #endif #endif /* CONFIG_RISCV_SOC_HAS_ISR_STACKING */ diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 9bc9306c2e9d11..7b2d55953b29bb 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -13,6 +13,7 @@ * structures. */ +#include #include #include #include @@ -88,43 +89,43 @@ GEN_OFFSET_SYM(_thread_arch_t, exception_depth); #endif /* CONFIG_FPU_SHARING */ /* esf member offsets */ -GEN_OFFSET_SYM(z_arch_esf_t, ra); -GEN_OFFSET_SYM(z_arch_esf_t, t0); -GEN_OFFSET_SYM(z_arch_esf_t, t1); -GEN_OFFSET_SYM(z_arch_esf_t, t2); -GEN_OFFSET_SYM(z_arch_esf_t, a0); -GEN_OFFSET_SYM(z_arch_esf_t, a1); -GEN_OFFSET_SYM(z_arch_esf_t, a2); -GEN_OFFSET_SYM(z_arch_esf_t, a3); -GEN_OFFSET_SYM(z_arch_esf_t, a4); -GEN_OFFSET_SYM(z_arch_esf_t, a5); +GEN_OFFSET_STRUCT(arch_esf, ra); +GEN_OFFSET_STRUCT(arch_esf, t0); +GEN_OFFSET_STRUCT(arch_esf, t1); +GEN_OFFSET_STRUCT(arch_esf, t2); +GEN_OFFSET_STRUCT(arch_esf, a0); +GEN_OFFSET_STRUCT(arch_esf, a1); +GEN_OFFSET_STRUCT(arch_esf, a2); +GEN_OFFSET_STRUCT(arch_esf, a3); +GEN_OFFSET_STRUCT(arch_esf, a4); +GEN_OFFSET_STRUCT(arch_esf, a5); #if !defined(CONFIG_RISCV_ISA_RV32E) -GEN_OFFSET_SYM(z_arch_esf_t, t3); -GEN_OFFSET_SYM(z_arch_esf_t, t4); -GEN_OFFSET_SYM(z_arch_esf_t, t5); -GEN_OFFSET_SYM(z_arch_esf_t, t6); -GEN_OFFSET_SYM(z_arch_esf_t, a6); -GEN_OFFSET_SYM(z_arch_esf_t, a7); +GEN_OFFSET_STRUCT(arch_esf, t3); +GEN_OFFSET_STRUCT(arch_esf, t4); +GEN_OFFSET_STRUCT(arch_esf, t5); +GEN_OFFSET_STRUCT(arch_esf, t6); +GEN_OFFSET_STRUCT(arch_esf, a6); +GEN_OFFSET_STRUCT(arch_esf, a7); #endif /* !CONFIG_RISCV_ISA_RV32E */ -GEN_OFFSET_SYM(z_arch_esf_t, mepc); -GEN_OFFSET_SYM(z_arch_esf_t, mstatus); +GEN_OFFSET_STRUCT(arch_esf, mepc); +GEN_OFFSET_STRUCT(arch_esf, mstatus); -GEN_OFFSET_SYM(z_arch_esf_t, s0); +GEN_OFFSET_STRUCT(arch_esf, s0); #ifdef CONFIG_USERSPACE -GEN_OFFSET_SYM(z_arch_esf_t, sp); +GEN_OFFSET_STRUCT(arch_esf, sp); #endif #if defined(CONFIG_RISCV_SOC_CONTEXT_SAVE) -GEN_OFFSET_SYM(z_arch_esf_t, soc_context); +GEN_OFFSET_STRUCT(arch_esf, soc_context); #endif #if defined(CONFIG_RISCV_SOC_OFFSETS) GEN_SOC_OFFSET_SYMS(); #endif -GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, sizeof(z_arch_esf_t)); +GEN_ABSOLUTE_SYM(__struct_arch_esf_SIZEOF, sizeof(struct arch_esf)); #ifdef CONFIG_EXCEPTION_DEBUG GEN_ABSOLUTE_SYM(__callee_saved_t_SIZEOF, ROUND_UP(sizeof(_callee_saved_t), ARCH_STACK_PTR_ALIGN)); diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 68147f8880a653..4ef287c4a7a561 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -86,14 +87,15 @@ static atomic_val_t cpu_pending_ipi[CONFIG_MP_MAX_NUM_CPUS]; #define IPI_SCHED 0 #define IPI_FPU_FLUSH 1 -void arch_sched_ipi(void) +void arch_sched_directed_ipi(uint32_t cpu_bitmap) { unsigned int key = arch_irq_lock(); unsigned int id = _current_cpu->id; unsigned int num_cpus = arch_num_cpus(); for (unsigned int i = 0; i < num_cpus; i++) { - if (i != id && _kernel.cpus[i].arch.online) { + if ((i != id) && _kernel.cpus[i].arch.online && + ((cpu_bitmap & BIT(i)) != 0)) { atomic_set_bit(&cpu_pending_ipi[i], IPI_SCHED); MSIP(_kernel.cpus[i].arch.hartid) = 1; } @@ -102,6 +104,11 @@ void arch_sched_ipi(void) arch_irq_unlock(key); } +void arch_sched_broadcast_ipi(void) +{ + arch_sched_directed_ipi(IPI_ALL_CPUS_MASK); +} + #ifdef CONFIG_FPU_SHARING void arch_flush_fpu_ipi(unsigned int cpu) { @@ -165,5 +172,4 @@ int arch_smp_init(void) return 0; } -SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif /* CONFIG_SMP */ diff --git a/arch/riscv/core/stacktrace.c b/arch/riscv/core/stacktrace.c index 7dbcd8067cc34a..cda6748c36371e 100644 --- a/arch/riscv/core/stacktrace.c +++ b/arch/riscv/core/stacktrace.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -uintptr_t z_riscv_get_sp_before_exc(const z_arch_esf_t *esf); +uintptr_t z_riscv_get_sp_before_exc(const struct arch_esf *esf); #if __riscv_xlen == 32 #define PR_REG "%08" PRIxPTR @@ -42,7 +42,7 @@ struct stackframe { LOG_ERR(" %2d: " SFP_FMT PR_REG " ra: " PR_REG, idx, sfp, ra) #endif -static bool in_stack_bound(uintptr_t addr, const z_arch_esf_t *esf) +static bool in_stack_bound(uintptr_t addr, const struct arch_esf *esf) { #ifdef CONFIG_THREAD_STACK_INFO uintptr_t start, end; @@ -86,7 +86,7 @@ static inline bool in_text_region(uintptr_t addr) } #ifdef CONFIG_FRAME_POINTER -void z_riscv_unwind_stack(const z_arch_esf_t *esf) +void z_riscv_unwind_stack(const struct arch_esf *esf) { uintptr_t fp = esf->s0; uintptr_t ra; @@ -115,7 +115,7 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf) LOG_ERR(""); } #else /* !CONFIG_FRAME_POINTER */ -void z_riscv_unwind_stack(const z_arch_esf_t *esf) +void z_riscv_unwind_stack(const struct arch_esf *esf) { uintptr_t sp = z_riscv_get_sp_before_exc(esf); uintptr_t ra; diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 38d5dbde092c6c..aeb33b31f3b1f0 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -23,15 +23,15 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, void *p1, void *p2, void *p3) { extern void z_riscv_thread_start(void); - struct __esf *stack_init; + struct arch_esf *stack_init; #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE const struct soc_esf soc_esf_init = {SOC_ESF_INIT}; #endif /* Initial stack frame for thread */ - stack_init = (struct __esf *)Z_STACK_PTR_ALIGN( - Z_STACK_PTR_TO_FRAME(struct __esf, stack_ptr) + stack_init = (struct arch_esf *)Z_STACK_PTR_ALIGN( + Z_STACK_PTR_TO_FRAME(struct arch_esf, stack_ptr) ); /* Setup the initial stack frame */ @@ -212,6 +212,8 @@ FUNC_NORETURN void z_riscv_switch_to_main_no_multithreading(k_thread_entry_t mai main_stack = (K_THREAD_STACK_BUFFER(z_main_stack) + K_THREAD_STACK_SIZEOF(z_main_stack)); + irq_unlock(MSTATUS_IEN); + __asm__ volatile ( "mv sp, %0; jalr ra, %1, 0" : diff --git a/arch/riscv/include/kernel_arch_func.h b/arch/riscv/include/kernel_arch_func.h index bdfc0527b9502d..c5ed6ff3f7f42e 100644 --- a/arch/riscv/include/kernel_arch_func.h +++ b/arch/riscv/include/kernel_arch_func.h @@ -71,9 +71,9 @@ arch_switch(void *switch_to, void **switched_from) /* Thin wrapper around z_riscv_fatal_error_csf */ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); -FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf, +FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const struct arch_esf *esf, const _callee_saved_t *csf); static inline bool arch_is_in_isr(void) diff --git a/arch/sparc/core/fatal.c b/arch/sparc/core/fatal.c index 55100606b9242f..40fd9d16792bc4 100644 --- a/arch/sparc/core/fatal.c +++ b/arch/sparc/core/fatal.c @@ -122,7 +122,7 @@ static const struct { { .tt = 0x0A, .desc = "tag_overflow", }, }; -static void print_trap_type(const z_arch_esf_t *esf) +static void print_trap_type(const struct arch_esf *esf) { const int tt = (esf->tbr & TBR_TT) >> TBR_TT_BIT; const char *desc = "unknown"; @@ -142,7 +142,7 @@ static void print_trap_type(const z_arch_esf_t *esf) LOG_ERR("tt = 0x%02X, %s", tt, desc); } -static void print_integer_registers(const z_arch_esf_t *esf) +static void print_integer_registers(const struct arch_esf *esf) { const struct savearea *flushed = (struct savearea *) esf->out[6]; @@ -159,7 +159,7 @@ static void print_integer_registers(const z_arch_esf_t *esf) } } -static void print_special_registers(const z_arch_esf_t *esf) +static void print_special_registers(const struct arch_esf *esf) { LOG_ERR( "psr: %08x wim: %08x tbr: %08x y: %08x", @@ -168,7 +168,7 @@ static void print_special_registers(const z_arch_esf_t *esf) LOG_ERR(" pc: %08x npc: %08x", esf->pc, esf->npc); } -static void print_backtrace(const z_arch_esf_t *esf) +static void print_backtrace(const struct arch_esf *esf) { const int MAX_LOGLINES = 40; const struct savearea *s = (struct savearea *) esf->out[6]; @@ -190,7 +190,7 @@ static void print_backtrace(const z_arch_esf_t *esf) } } -static void print_all(const z_arch_esf_t *esf) +static void print_all(const struct arch_esf *esf) { LOG_ERR(""); print_trap_type(esf); @@ -205,7 +205,7 @@ static void print_all(const z_arch_esf_t *esf) #endif /* CONFIG_EXCEPTION_DEBUG */ FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { #if CONFIG_EXCEPTION_DEBUG if (esf != NULL) { diff --git a/arch/sparc/core/fault_trap.S b/arch/sparc/core/fault_trap.S index c1a8977ba233c7..53b3d9f0b98cd2 100644 --- a/arch/sparc/core/fault_trap.S +++ b/arch/sparc/core/fault_trap.S @@ -72,7 +72,7 @@ SECTION_FUNC(TEXT, __sparc_trap_except_reason) mov %l5, %g3 /* Allocate an ABI stack frame and exception stack frame */ - sub %fp, 96 + __z_arch_esf_t_SIZEOF, %sp + sub %fp, 96 + __struct_arch_esf_SIZEOF, %sp /* * %fp: %sp of interrupted task * %sp: %sp of interrupted task - ABI_frame - esf @@ -81,19 +81,19 @@ SECTION_FUNC(TEXT, __sparc_trap_except_reason) mov %l7, %o0 /* Fill in the content of the exception stack frame */ #if defined(CONFIG_EXTRA_EXCEPTION_INFO) - std %i0, [%sp + 96 + __z_arch_esf_t_out_OFFSET + 0x00] - std %i2, [%sp + 96 + __z_arch_esf_t_out_OFFSET + 0x08] - std %i4, [%sp + 96 + __z_arch_esf_t_out_OFFSET + 0x10] - std %i6, [%sp + 96 + __z_arch_esf_t_out_OFFSET + 0x18] - std %g0, [%sp + 96 + __z_arch_esf_t_global_OFFSET + 0x00] - std %g2, [%sp + 96 + __z_arch_esf_t_global_OFFSET + 0x08] - std %g4, [%sp + 96 + __z_arch_esf_t_global_OFFSET + 0x10] - std %g6, [%sp + 96 + __z_arch_esf_t_global_OFFSET + 0x18] + std %i0, [%sp + 96 + __struct_arch_esf_out_OFFSET + 0x00] + std %i2, [%sp + 96 + __struct_arch_esf_out_OFFSET + 0x08] + std %i4, [%sp + 96 + __struct_arch_esf_out_OFFSET + 0x10] + std %i6, [%sp + 96 + __struct_arch_esf_out_OFFSET + 0x18] + std %g0, [%sp + 96 + __struct_arch_esf_global_OFFSET + 0x00] + std %g2, [%sp + 96 + __struct_arch_esf_global_OFFSET + 0x08] + std %g4, [%sp + 96 + __struct_arch_esf_global_OFFSET + 0x10] + std %g6, [%sp + 96 + __struct_arch_esf_global_OFFSET + 0x18] #endif - std %l0, [%sp + 96 + __z_arch_esf_t_psr_OFFSET] /* psr pc */ - std %l2, [%sp + 96 + __z_arch_esf_t_npc_OFFSET] /* npc wim */ + std %l0, [%sp + 96 + __struct_arch_esf_psr_OFFSET] /* psr pc */ + std %l2, [%sp + 96 + __struct_arch_esf_npc_OFFSET] /* npc wim */ rd %y, %l7 - std %l6, [%sp + 96 + __z_arch_esf_t_tbr_OFFSET] /* tbr y */ + std %l6, [%sp + 96 + __struct_arch_esf_tbr_OFFSET] /* tbr y */ /* Enable traps, raise PIL to mask all maskable interrupts. */ or %l0, PSR_PIL, %o2 diff --git a/arch/sparc/core/offsets/offsets.c b/arch/sparc/core/offsets/offsets.c index 3796117ac09453..023ef7452c443c 100644 --- a/arch/sparc/core/offsets/offsets.c +++ b/arch/sparc/core/offsets/offsets.c @@ -31,11 +31,11 @@ GEN_OFFSET_SYM(_callee_saved_t, i6); GEN_OFFSET_SYM(_callee_saved_t, o6); /* esf member offsets */ -GEN_OFFSET_SYM(z_arch_esf_t, out); -GEN_OFFSET_SYM(z_arch_esf_t, global); -GEN_OFFSET_SYM(z_arch_esf_t, npc); -GEN_OFFSET_SYM(z_arch_esf_t, psr); -GEN_OFFSET_SYM(z_arch_esf_t, tbr); -GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, STACK_ROUND_UP(sizeof(z_arch_esf_t))); +GEN_OFFSET_STRUCT(arch_esf, out); +GEN_OFFSET_STRUCT(arch_esf, global); +GEN_OFFSET_STRUCT(arch_esf, npc); +GEN_OFFSET_STRUCT(arch_esf, psr); +GEN_OFFSET_STRUCT(arch_esf, tbr); +GEN_ABSOLUTE_SYM(__struct_arch_esf_SIZEOF, sizeof(struct arch_esf)); GEN_ABS_SYM_END diff --git a/arch/sparc/include/kernel_arch_func.h b/arch/sparc/include/kernel_arch_func.h index 41f48ccc44a4ea..8b79b130ad6557 100644 --- a/arch/sparc/include/kernel_arch_func.h +++ b/arch/sparc/include/kernel_arch_func.h @@ -43,7 +43,7 @@ static inline void arch_switch(void *switch_to, void **switched_from) } FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); static inline bool arch_is_in_isr(void) { diff --git a/arch/x86/core/efi.c b/arch/x86/core/efi.c index 425b0dcde86f2f..e5470e6d8a3646 100644 --- a/arch/x86/core/efi.c +++ b/arch/x86/core/efi.c @@ -33,8 +33,8 @@ void efi_init(struct efi_boot_arg *efi_arg) return; } - z_phys_map((uint8_t **)&efi, (uintptr_t)efi_arg, - sizeof(struct efi_boot_arg), 0); + k_mem_map_phys_bare((uint8_t **)&efi, (uintptr_t)efi_arg, + sizeof(struct efi_boot_arg), 0); } /* EFI thunk. Not a lot of code, but lots of context: diff --git a/arch/x86/core/fatal.c b/arch/x86/core/fatal.c index 5db20eb5deb27c..4eafd999bc7849 100644 --- a/arch/x86/core/fatal.c +++ b/arch/x86/core/fatal.c @@ -35,7 +35,7 @@ FUNC_NORETURN void arch_system_halt(unsigned int reason) #ifdef CONFIG_THREAD_STACK_INFO -static inline uintptr_t esf_get_sp(const z_arch_esf_t *esf) +static inline uintptr_t esf_get_sp(const struct arch_esf *esf) { #ifdef CONFIG_X86_64 return esf->rsp; @@ -122,7 +122,7 @@ bool z_x86_check_guard_page(uintptr_t addr) #ifdef CONFIG_EXCEPTION_DEBUG -static inline uintptr_t esf_get_code(const z_arch_esf_t *esf) +static inline uintptr_t esf_get_code(const struct arch_esf *esf) { #ifdef CONFIG_X86_64 return esf->code; @@ -188,7 +188,7 @@ static void unwind_stack(uintptr_t base_ptr, uint16_t cs) } #endif /* CONFIG_EXCEPTION_STACK_TRACE */ -static inline uintptr_t get_cr3(const z_arch_esf_t *esf) +static inline uintptr_t get_cr3(const struct arch_esf *esf) { #if defined(CONFIG_USERSPACE) && defined(CONFIG_X86_KPTI) /* If the interrupted thread was in user mode, we did a page table @@ -206,14 +206,14 @@ static inline uintptr_t get_cr3(const z_arch_esf_t *esf) return z_x86_cr3_get(); } -static inline pentry_t *get_ptables(const z_arch_esf_t *esf) +static inline pentry_t *get_ptables(const struct arch_esf *esf) { - return z_mem_virt_addr(get_cr3(esf)); + return k_mem_virt_addr(get_cr3(esf)); } #ifdef CONFIG_X86_64 __pinned_func -static void dump_regs(const z_arch_esf_t *esf) +static void dump_regs(const struct arch_esf *esf) { LOG_ERR("RAX: 0x%016lx RBX: 0x%016lx RCX: 0x%016lx RDX: 0x%016lx", esf->rax, esf->rbx, esf->rcx, esf->rdx); @@ -236,7 +236,7 @@ static void dump_regs(const z_arch_esf_t *esf) } #else /* 32-bit */ __pinned_func -static void dump_regs(const z_arch_esf_t *esf) +static void dump_regs(const struct arch_esf *esf) { LOG_ERR("EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x", esf->eax, esf->ebx, esf->ecx, esf->edx); @@ -327,7 +327,7 @@ static void log_exception(uintptr_t vector, uintptr_t code) } __pinned_func -static void dump_page_fault(z_arch_esf_t *esf) +static void dump_page_fault(struct arch_esf *esf) { uintptr_t err; void *cr2; @@ -362,7 +362,7 @@ static void dump_page_fault(z_arch_esf_t *esf) __pinned_func FUNC_NORETURN void z_x86_fatal_error(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { if (esf != NULL) { #ifdef CONFIG_EXCEPTION_DEBUG @@ -385,7 +385,7 @@ FUNC_NORETURN void z_x86_fatal_error(unsigned int reason, __pinned_func FUNC_NORETURN void z_x86_unhandled_cpu_exception(uintptr_t vector, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { #ifdef CONFIG_EXCEPTION_DEBUG log_exception(vector, esf_get_code(esf)); @@ -404,7 +404,7 @@ static const struct z_exc_handle exceptions[] = { #endif __pinned_func -void z_x86_page_fault_handler(z_arch_esf_t *esf) +void z_x86_page_fault_handler(struct arch_esf *esf) { #ifdef CONFIG_DEMAND_PAGING if ((esf->errorCode & PF_P) == 0) { @@ -434,7 +434,7 @@ void z_x86_page_fault_handler(z_arch_esf_t *esf) } else #else { - was_valid_access = z_page_fault(virt); + was_valid_access = k_mem_page_fault(virt); } #endif /* CONFIG_X86_KPTI */ if (was_valid_access) { @@ -488,7 +488,7 @@ void z_x86_page_fault_handler(z_arch_esf_t *esf) } __pinned_func -void z_x86_do_kernel_oops(const z_arch_esf_t *esf) +void z_x86_do_kernel_oops(const struct arch_esf *esf) { uintptr_t reason; diff --git a/arch/x86/core/ia32/coredump.c b/arch/x86/core/ia32/coredump.c index b49373aab771e8..fb7d0fcfd8cc51 100644 --- a/arch/x86/core/ia32/coredump.c +++ b/arch/x86/core/ia32/coredump.c @@ -34,7 +34,7 @@ struct x86_arch_block { */ static struct x86_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { struct coredump_arch_hdr_t hdr = { .id = COREDUMP_ARCH_HDR_ID, diff --git a/arch/x86/core/ia32/crt0.S b/arch/x86/core/ia32/crt0.S index 32513a95790376..26500079a02b12 100644 --- a/arch/x86/core/ia32/crt0.S +++ b/arch/x86/core/ia32/crt0.S @@ -60,7 +60,7 @@ * Until we enable these page tables, only physical memory addresses * work. */ - movl $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %eax + movl $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %eax movl %eax, %cr3 #ifdef CONFIG_X86_PAE @@ -89,7 +89,7 @@ orl $(CR0_PG | CR0_WP), %eax movl %eax, %cr0 -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL /* Jump to a virtual address, which works because the identity and * virtual mappings both are to the same physical address. */ @@ -98,7 +98,7 @@ vm_enter: /* We are now executing in virtual memory. We'll un-map the identity * mappings later once we are in the C domain */ -#endif /* Z_VM_KERNEL */ +#endif /* K_MEM_IS_VM_KERNEL */ #endif /* CONFIG_X86_MMU */ .endm @@ -126,7 +126,7 @@ SECTION_FUNC(BOOT_TEXT, __start) */ #if CONFIG_SET_GDT /* load 32-bit operand size GDT */ - lgdt Z_MEM_PHYS_ADDR(_gdt_rom) + lgdt K_MEM_PHYS_ADDR(_gdt_rom) /* If we set our own GDT, update the segment registers as well. */ @@ -138,7 +138,7 @@ SECTION_FUNC(BOOT_TEXT, __start) movw %ax, %fs /* Zero FS */ movw %ax, %gs /* Zero GS */ - ljmp $CODE_SEG, $Z_MEM_PHYS_ADDR(__csSet) /* set CS = 0x08 */ + ljmp $CODE_SEG, $K_MEM_PHYS_ADDR(__csSet) /* set CS = 0x08 */ __csSet: #endif /* CONFIG_SET_GDT */ @@ -180,7 +180,8 @@ __csSet: andl $~0x400, %eax /* CR4[OSXMMEXCPT] = 0 */ movl %eax, %cr4 /* move EAX to CR4 */ - ldmxcsr Z_MEM_PHYS_ADDR(_sse_mxcsr_default_value) /* initialize SSE control/status reg */ + /* initialize SSE control/status reg */ + ldmxcsr K_MEM_PHYS_ADDR(_sse_mxcsr_default_value) #endif /* CONFIG_X86_SSE */ @@ -199,7 +200,7 @@ __csSet: */ #ifdef CONFIG_INIT_STACKS movl $0xAAAAAAAA, %eax - leal Z_MEM_PHYS_ADDR(z_interrupt_stacks), %edi + leal K_MEM_PHYS_ADDR(z_interrupt_stacks), %edi #ifdef CONFIG_X86_STACK_PROTECTION addl $4096, %edi #endif @@ -208,7 +209,7 @@ __csSet: rep stosl #endif - movl $Z_MEM_PHYS_ADDR(z_interrupt_stacks), %esp + movl $K_MEM_PHYS_ADDR(z_interrupt_stacks), %esp #ifdef CONFIG_X86_STACK_PROTECTION /* In this configuration, all stacks, including IRQ stack, are declared * with a 4K non-present guard page preceding the stack buffer @@ -243,7 +244,7 @@ __csSet: ltr %ax #endif -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL /* Need to reset the stack to virtual address after * page table is loaded. */ @@ -254,7 +255,7 @@ __csSet: #else addl $CONFIG_ISR_STACK_SIZE, %esp #endif -#endif /* Z_VM_KERNEL */ +#endif /* K_MEM_IS_VM_KERNEL */ #ifdef CONFIG_THREAD_LOCAL_STORAGE pushl %esp @@ -347,9 +348,9 @@ _gdt: * descriptor here */ /* Limit on GDT */ - .word Z_MEM_PHYS_ADDR(_gdt_rom_end) - Z_MEM_PHYS_ADDR(_gdt_rom) - 1 + .word K_MEM_PHYS_ADDR(_gdt_rom_end) - K_MEM_PHYS_ADDR(_gdt_rom) - 1 /* table address: _gdt_rom */ - .long Z_MEM_PHYS_ADDR(_gdt_rom) + .long K_MEM_PHYS_ADDR(_gdt_rom) .word 0x0000 /* Entry 1 (selector=0x0008): Code descriptor: DPL0 */ diff --git a/arch/x86/core/ia32/excstub.S b/arch/x86/core/ia32/excstub.S index 9c5f3f03191520..6c0a13a37cde36 100644 --- a/arch/x86/core/ia32/excstub.S +++ b/arch/x86/core/ia32/excstub.S @@ -161,12 +161,12 @@ SECTION_FUNC(PINNED_TEXT, _exception_enter) /* ESP is still pointing to the ESF at this point */ - testl $0x200, __z_arch_esf_t_eflags_OFFSET(%esp) + testl $0x200, __struct_arch_esf_eflags_OFFSET(%esp) je allDone sti allDone: - pushl %esp /* push z_arch_esf_t * parameter */ + pushl %esp /* push struct_arch_esf * parameter */ call *%ecx /* call exception handler */ addl $0x4, %esp diff --git a/arch/x86/core/ia32/fatal.c b/arch/x86/core/ia32/fatal.c index 597f21a01adc67..3ae8a6b67da3af 100644 --- a/arch/x86/core/ia32/fatal.c +++ b/arch/x86/core/ia32/fatal.c @@ -27,10 +27,10 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); unsigned int z_x86_exception_vector; #endif -__weak void z_debug_fatal_hook(const z_arch_esf_t *esf) { ARG_UNUSED(esf); } +__weak void z_debug_fatal_hook(const struct arch_esf *esf) { ARG_UNUSED(esf); } __pinned_func -void z_x86_spurious_irq(const z_arch_esf_t *esf) +void z_x86_spurious_irq(const struct arch_esf *esf) { int vector = z_irq_controller_isr_vector_get(); @@ -46,7 +46,7 @@ void arch_syscall_oops(void *ssf) { struct _x86_syscall_stack_frame *ssf_ptr = (struct _x86_syscall_stack_frame *)ssf; - z_arch_esf_t oops = { + struct arch_esf oops = { .eip = ssf_ptr->eip, .cs = ssf_ptr->cs, .eflags = ssf_ptr->eflags @@ -66,7 +66,7 @@ NANO_CPU_INT_REGISTER(_kernel_oops_handler, NANO_SOFT_IRQ, #if CONFIG_EXCEPTION_DEBUG __pinned_func FUNC_NORETURN static void generic_exc_handle(unsigned int vector, - const z_arch_esf_t *pEsf) + const struct arch_esf *pEsf) { #ifdef CONFIG_DEBUG_COREDUMP z_x86_exception_vector = vector; @@ -77,7 +77,7 @@ FUNC_NORETURN static void generic_exc_handle(unsigned int vector, #define _EXC_FUNC(vector) \ __pinned_func \ -FUNC_NORETURN __used static void handle_exc_##vector(const z_arch_esf_t *pEsf) \ +FUNC_NORETURN __used static void handle_exc_##vector(const struct arch_esf *pEsf) \ { \ generic_exc_handle(vector, pEsf); \ } @@ -120,7 +120,7 @@ EXC_FUNC_NOCODE(IV_MACHINE_CHECK, 0); _EXCEPTION_CONNECT_CODE(z_x86_page_fault_handler, IV_PAGE_FAULT, 0); #ifdef CONFIG_X86_ENABLE_TSS -static __pinned_noinit volatile z_arch_esf_t _df_esf; +static __pinned_noinit volatile struct arch_esf _df_esf; /* Very tiny stack; just enough for the bogus error code pushed by the CPU * and a frame pointer push by the compiler. All df_handler_top does is @@ -156,7 +156,7 @@ struct task_state_segment _df_tss = { .ss = DATA_SEG, .eip = (uint32_t)df_handler_top, .cr3 = (uint32_t) - Z_MEM_PHYS_ADDR(POINTER_TO_UINT(&z_x86_kernel_ptables[0])) + K_MEM_PHYS_ADDR(POINTER_TO_UINT(&z_x86_kernel_ptables[0])) }; __pinned_func @@ -182,14 +182,14 @@ static __used void df_handler_bottom(void) reason = K_ERR_STACK_CHK_FAIL; } #endif - z_x86_fatal_error(reason, (z_arch_esf_t *)&_df_esf); + z_x86_fatal_error(reason, (struct arch_esf *)&_df_esf); } __pinned_func static FUNC_NORETURN __used void df_handler_top(void) { /* State of the system when the double-fault forced a task switch - * will be in _main_tss. Set up a z_arch_esf_t and copy system state into + * will be in _main_tss. Set up a struct arch_esf and copy system state into * it */ _df_esf.esp = _main_tss.esp; @@ -213,7 +213,7 @@ static FUNC_NORETURN __used void df_handler_top(void) _main_tss.es = DATA_SEG; _main_tss.ss = DATA_SEG; _main_tss.eip = (uint32_t)df_handler_bottom; - _main_tss.cr3 = z_mem_phys_addr(z_x86_kernel_ptables); + _main_tss.cr3 = k_mem_phys_addr(z_x86_kernel_ptables); _main_tss.eflags = 0U; /* NT bit is set in EFLAGS so we will task switch back to _main_tss diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index a33a40a0a7832b..c89bf7accd5a1e 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -302,7 +302,7 @@ int z_float_disable(struct k_thread *thread) * instruction is executed while CR0[TS]=1. The handler then enables the * current thread to use all supported floating point registers. */ -void _FpNotAvailableExcHandler(z_arch_esf_t *pEsf) +void _FpNotAvailableExcHandler(struct arch_esf *pEsf) { ARG_UNUSED(pEsf); diff --git a/arch/x86/core/ia32/gdbstub.c b/arch/x86/core/ia32/gdbstub.c index 692ea78baf41cb..252f15d79ffebd 100644 --- a/arch/x86/core/ia32/gdbstub.c +++ b/arch/x86/core/ia32/gdbstub.c @@ -78,7 +78,7 @@ static unsigned int get_exception(unsigned int vector) /* * Debug exception handler. */ -static void z_gdb_interrupt(unsigned int vector, z_arch_esf_t *esf) +static void z_gdb_interrupt(unsigned int vector, struct arch_esf *esf) { debug_ctx.exception = get_exception(vector); @@ -212,7 +212,7 @@ size_t arch_gdb_reg_writeone(struct gdb_ctx *ctx, uint8_t *hex, size_t hexlen, return ret; } -static __used void z_gdb_debug_isr(z_arch_esf_t *esf) +static __used void z_gdb_debug_isr(struct arch_esf *esf) { #ifdef CONFIG_GDBSTUB_TRACE printk("gdbstub:enter %s (IV_DEBUG)\n", __func__); @@ -225,7 +225,7 @@ static __used void z_gdb_debug_isr(z_arch_esf_t *esf) #endif } -static __used void z_gdb_break_isr(z_arch_esf_t *esf) +static __used void z_gdb_break_isr(struct arch_esf *esf) { #ifdef CONFIG_GDBSTUB_TRACE printk("gdbstub:enter %s (IV_BREAKPOINT)\n", __func__); diff --git a/arch/x86/core/ia32/intstub.S b/arch/x86/core/ia32/intstub.S index 0dc08c67c245d4..4cd5c0bee9040f 100644 --- a/arch/x86/core/ia32/intstub.S +++ b/arch/x86/core/ia32/intstub.S @@ -33,7 +33,7 @@ GTEXT(arch_swap) #ifdef CONFIG_PM - GTEXT(z_pm_save_idle_exit) + GTEXT(pm_system_resume) #endif /** @@ -314,13 +314,13 @@ handle_idle: movl $0, _kernel_offset_to_idle(%ecx) /* - * Beware that a timer driver's z_pm_save_idle_exit() implementation might + * Beware that a timer driver's pm_system_resume() implementation might * expect that interrupts are disabled when invoked. This ensures that * the calculation and programming of the device for the next timer * deadline is not interrupted. */ - call z_pm_save_idle_exit + call pm_system_resume popl %edx popl %eax jmp alreadyOnIntStack diff --git a/arch/x86/core/ia32/userspace.S b/arch/x86/core/ia32/userspace.S index bf21a0cc1a2274..a4ad4c69fb8755 100644 --- a/arch/x86/core/ia32/userspace.S +++ b/arch/x86/core/ia32/userspace.S @@ -51,7 +51,7 @@ SECTION_FUNC(PINNED_TEXT, z_x86_trampoline_to_kernel) pushl %edi /* Switch to kernel page table */ - movl $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %esi + movl $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %esi movl %esi, %cr3 /* Save old trampoline stack pointer in %edi */ @@ -156,7 +156,7 @@ SECTION_FUNC(TEXT, z_x86_syscall_entry_stub) pushl %edi /* Switch to kernel page table */ - movl $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %esi + movl $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %esi movl %esi, %cr3 /* Save old trampoline stack pointer in %edi */ diff --git a/arch/x86/core/intel64/coredump.c b/arch/x86/core/intel64/coredump.c index f1c1a15eaff374..65a9306ca07da3 100644 --- a/arch/x86/core/intel64/coredump.c +++ b/arch/x86/core/intel64/coredump.c @@ -46,7 +46,7 @@ struct x86_64_arch_block { */ static struct x86_64_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { struct coredump_arch_hdr_t hdr = { .id = COREDUMP_ARCH_HDR_ID, diff --git a/arch/x86/core/intel64/fatal.c b/arch/x86/core/intel64/fatal.c index 9dd97614dc1e3c..9eed95bfaa3adf 100644 --- a/arch/x86/core/intel64/fatal.c +++ b/arch/x86/core/intel64/fatal.c @@ -13,14 +13,14 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); /* NMI handlers should override weak implementation * return true if NMI is handled, false otherwise */ -__weak bool z_x86_do_kernel_nmi(const z_arch_esf_t *esf) +__weak bool z_x86_do_kernel_nmi(const struct arch_esf *esf) { ARG_UNUSED(esf); return false; } -void z_x86_exception(z_arch_esf_t *esf) +void z_x86_exception(struct arch_esf *esf) { switch (esf->vector) { case Z_X86_OOPS_VECTOR: diff --git a/arch/x86/core/intel64/irq_offload.c b/arch/x86/core/intel64/irq_offload.c index 0146321f7d9d99..c2771d735cfc25 100644 --- a/arch/x86/core/intel64/irq_offload.c +++ b/arch/x86/core/intel64/irq_offload.c @@ -9,6 +9,7 @@ */ #include +#include #include #include @@ -17,12 +18,37 @@ extern void (*x86_irq_funcs[NR_IRQ_VECTORS])(const void *arg); extern const void *x86_irq_args[NR_IRQ_VECTORS]; +static void (*irq_offload_funcs[CONFIG_MP_NUM_CPUS])(const void *arg); +static const void *irq_offload_args[CONFIG_MP_NUM_CPUS]; + +static void dispatcher(const void *arg) +{ + uint8_t cpu_id = _current_cpu->id; + + if (irq_offload_funcs[cpu_id] != NULL) { + irq_offload_funcs[cpu_id](irq_offload_args[cpu_id]); + } +} void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { - x86_irq_funcs[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = routine; - x86_irq_args[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = parameter; + int key = arch_irq_lock(); + uint8_t cpu_id = _current_cpu->id; + + irq_offload_funcs[cpu_id] = routine; + irq_offload_args[cpu_id] = parameter; + __asm__ volatile("int %0" : : "i" (CONFIG_IRQ_OFFLOAD_VECTOR) : "memory"); - x86_irq_funcs[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = NULL; + + arch_irq_unlock(key); +} + +int irq_offload_init(void) +{ + x86_irq_funcs[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = dispatcher; + + return 0; } + +SYS_INIT(irq_offload_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index 68f89c90398f9a..108d9f15d378f0 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -44,7 +44,7 @@ /* Page tables created at build time by gen_mmu.py * NOTE: Presumes phys=virt */ - movl $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %eax + movl $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %eax movl %eax, %cr3 set_efer @@ -66,7 +66,7 @@ clts /* NOTE: Presumes phys=virt */ - movq $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %rax + movq $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %rax movq %rax, %cr3 set_efer diff --git a/arch/x86/core/intel64/smp.c b/arch/x86/core/intel64/smp.c index a73ba9c8f38c36..1e0aeb3e443aaf 100644 --- a/arch/x86/core/intel64/smp.c +++ b/arch/x86/core/intel64/smp.c @@ -34,9 +34,7 @@ int arch_smp_init(void) * 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). */ -void arch_sched_ipi(void) +void arch_sched_broadcast_ipi(void) { z_loapic_ipi(0, LOAPIC_ICR_IPI_OTHERS, CONFIG_SCHED_IPI_VECTOR); } - -SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/arch/x86/core/intel64/userspace.S b/arch/x86/core/intel64/userspace.S index ab09381c7af9cc..d3610c300cb9f7 100644 --- a/arch/x86/core/intel64/userspace.S +++ b/arch/x86/core/intel64/userspace.S @@ -87,7 +87,7 @@ z_x86_syscall_entry_stub: pushq %rax /* NOTE: Presumes phys=virt */ - movq $Z_MEM_PHYS_ADDR(z_x86_kernel_ptables), %rax + movq $K_MEM_PHYS_ADDR(z_x86_kernel_ptables), %rax movq %rax, %cr3 popq %rax movq $0, -8(%rsp) /* Delete stashed RAX data */ diff --git a/arch/x86/core/legacy_bios.c b/arch/x86/core/legacy_bios.c index 6a7159a9b1c139..6245a6175c58d3 100644 --- a/arch/x86/core/legacy_bios.c +++ b/arch/x86/core/legacy_bios.c @@ -17,18 +17,18 @@ static uintptr_t bios_search_rsdp_buff(uintptr_t search_phy_add, uint32_t search { uint64_t *search_buff; - z_phys_map((uint8_t **)&search_buff, search_phy_add, search_length, 0); + k_mem_map_phys_bare((uint8_t **)&search_buff, search_phy_add, search_length, 0); if (!search_buff) { return 0; } for (int i = 0; i < search_length / 8u; i++) { if (search_buff[i] == RSDP_SIGNATURE) { - z_phys_unmap((uint8_t *)search_buff, search_length); + k_mem_unmap_phys_bare((uint8_t *)search_buff, search_length); return (search_phy_add + (i * 8u)); } } - z_phys_unmap((uint8_t *)search_buff, search_length); + k_mem_unmap_phys_bare((uint8_t *)search_buff, search_length); return 0; } @@ -38,10 +38,10 @@ void *bios_acpi_rsdp_get(void) uint8_t *bios_ext_data, *zero_page_base; uintptr_t search_phy_add, rsdp_phy_add; - z_phys_map(&zero_page_base, 0, DATA_SIZE_K(4u), 0); + k_mem_map_phys_bare(&zero_page_base, 0, DATA_SIZE_K(4u), 0); bios_ext_data = EBDA_ADD + zero_page_base; search_phy_add = (uintptr_t)((*(uint16_t *)bios_ext_data) << 4u); - z_phys_unmap(zero_page_base, DATA_SIZE_K(4u)); + k_mem_unmap_phys_bare(zero_page_base, DATA_SIZE_K(4u)); if ((search_phy_add >= BIOS_EXT_DATA_LOW) && (search_phy_add < BIOS_EXT_DATA_HIGH)) { rsdp_phy_add = bios_search_rsdp_buff(search_phy_add, DATA_SIZE_K(1u)); diff --git a/arch/x86/core/multiboot.c b/arch/x86/core/multiboot.c index 2dab56128d111e..06d03c7b807149 100644 --- a/arch/x86/core/multiboot.c +++ b/arch/x86/core/multiboot.c @@ -41,8 +41,8 @@ void z_multiboot_init(struct multiboot_info *info_pa) */ info = info_pa; #else - z_phys_map((uint8_t **)&info, POINTER_TO_UINT(info_pa), - sizeof(*info_pa), K_MEM_CACHE_NONE); + k_mem_map_phys_bare((uint8_t **)&info, POINTER_TO_UINT(info_pa), + sizeof(*info_pa), K_MEM_CACHE_NONE); #endif /* CONFIG_ARCH_MAPS_ALL_RAM */ if (info == NULL) { @@ -70,8 +70,8 @@ void z_multiboot_init(struct multiboot_info *info_pa) #else uint8_t *address_va; - z_phys_map(&address_va, info->mmap_addr, info->mmap_length, - K_MEM_CACHE_NONE); + k_mem_map_phys_bare(&address_va, info->mmap_addr, info->mmap_length, + K_MEM_CACHE_NONE); address = POINTER_TO_UINT(address_va); #endif /* CONFIG_ARCH_MAPS_ALL_RAM */ diff --git a/arch/x86/core/offsets/ia32_offsets.c b/arch/x86/core/offsets/ia32_offsets.c index 61a7f25bb2a40e..2dfbb5c38ef282 100644 --- a/arch/x86/core/offsets/ia32_offsets.c +++ b/arch/x86/core/offsets/ia32_offsets.c @@ -52,7 +52,6 @@ GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF, GEN_OFFSET_SYM(_callee_saved_t, esp); -/* z_arch_esf_t structure member offsets */ - -GEN_OFFSET_SYM(z_arch_esf_t, eflags); +/* struct arch_esf structure member offsets */ +GEN_OFFSET_STRUCT(arch_esf, eflags); #endif /* _X86_OFFSETS_INC_ */ diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index d9b62b0b7115d1..4ff5ffcdc7eb88 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -73,10 +73,6 @@ FUNC_NORETURN void z_prep_c(void *arg) } #endif -#if defined(CONFIG_SMP) - arch_smp_init(); -#endif - z_cstart(); CODE_UNREACHABLE; } diff --git a/arch/x86/core/x86_mmu.c b/arch/x86/core/x86_mmu.c index 7bfa2088a418e7..566dd2cdfd40eb 100644 --- a/arch/x86/core/x86_mmu.c +++ b/arch/x86/core/x86_mmu.c @@ -313,7 +313,7 @@ static inline uintptr_t get_entry_phys(pentry_t entry, int level) __pinned_func static inline pentry_t *next_table(pentry_t entry, int level) { - return z_mem_virt_addr(get_entry_phys(entry, level)); + return k_mem_virt_addr(get_entry_phys(entry, level)); } /* Number of table entries at this level */ @@ -416,12 +416,12 @@ void z_x86_tlb_ipi(const void *arg) * if KPTI is turned on */ ptables_phys = z_x86_cr3_get(); - __ASSERT(ptables_phys == z_mem_phys_addr(&z_x86_kernel_ptables), ""); + __ASSERT(ptables_phys == k_mem_phys_addr(&z_x86_kernel_ptables), ""); #else /* We might have been moved to another memory domain, so always invoke * z_x86_thread_page_tables_get() instead of using current CR3 value. */ - ptables_phys = z_mem_phys_addr(z_x86_thread_page_tables_get(_current)); + ptables_phys = k_mem_phys_addr(z_x86_thread_page_tables_get(_current)); #endif /* * In the future, we can consider making this smarter, such as @@ -593,7 +593,7 @@ static void print_entries(pentry_t entries_array[], uint8_t *base, int level, if (phys == virt) { /* Identity mappings */ COLOR(YELLOW); - } else if (phys + Z_MEM_VM_OFFSET == virt) { + } else if (phys + K_MEM_VIRT_OFFSET == virt) { /* Permanent RAM mappings */ COLOR(GREEN); } else { @@ -661,7 +661,7 @@ static void dump_ptables(pentry_t *table, uint8_t *base, int level) #endif printk("%s at %p (0x%" PRIxPTR "): ", info->name, table, - z_mem_phys_addr(table)); + k_mem_phys_addr(table)); if (level == 0) { printk("entire address space\n"); } else { @@ -826,7 +826,7 @@ static inline pentry_t pte_finalize_value(pentry_t val, bool user_table, { #ifdef CONFIG_X86_KPTI static const uintptr_t shared_phys_addr = - Z_MEM_PHYS_ADDR(POINTER_TO_UINT(&z_shared_kernel_page_start)); + K_MEM_PHYS_ADDR(POINTER_TO_UINT(&z_shared_kernel_page_start)); if (user_table && (val & MMU_US) == 0 && (val & MMU_P) != 0 && get_entry_phys(val, level) != shared_phys_addr) { @@ -1307,7 +1307,7 @@ void arch_mem_unmap(void *addr, size_t size) ARG_UNUSED(ret); } -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL __boot_func static void identity_map_remove(uint32_t level) { @@ -1346,7 +1346,7 @@ static void identity_map_remove(uint32_t level) __boot_func void z_x86_mmu_init(void) { -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL /* We booted with physical address space being identity mapped. * As we are now executing in virtual address space, * the identity map is no longer needed. So remove them. @@ -1720,7 +1720,7 @@ static int copy_page_table(pentry_t *dst, pentry_t *src, int level) * cast needed for PAE case where sizeof(void *) and * sizeof(pentry_t) are not the same. */ - dst[i] = ((pentry_t)z_mem_phys_addr(child_dst) | + dst[i] = ((pentry_t)k_mem_phys_addr(child_dst) | INT_FLAGS); ret = copy_page_table(child_dst, @@ -1924,11 +1924,11 @@ int arch_mem_domain_thread_add(struct k_thread *thread) * z_x86_current_stack_perms() */ if (is_migration) { - old_ptables = z_mem_virt_addr(thread->arch.ptables); + old_ptables = k_mem_virt_addr(thread->arch.ptables); set_stack_perms(thread, domain->arch.ptables); } - thread->arch.ptables = z_mem_phys_addr(domain->arch.ptables); + thread->arch.ptables = k_mem_phys_addr(domain->arch.ptables); LOG_DBG("set thread %p page tables to 0x%" PRIxPTR, thread, thread->arch.ptables); @@ -2004,11 +2004,12 @@ static void mark_addr_page_reserved(uintptr_t addr, size_t len) uintptr_t end = ROUND_UP(addr + len, CONFIG_MMU_PAGE_SIZE); for (; pos < end; pos += CONFIG_MMU_PAGE_SIZE) { - if (!z_is_page_frame(pos)) { + if (!k_mem_is_page_frame(pos)) { continue; } - z_page_frame_set(z_phys_to_page_frame(pos), Z_PAGE_FRAME_RESERVED); + k_mem_page_frame_set(k_mem_phys_to_page_frame(pos), + K_MEM_PAGE_FRAME_RESERVED); } } @@ -2112,7 +2113,7 @@ void arch_mem_page_in(void *addr, uintptr_t phys) __pinned_func void arch_mem_scratch(uintptr_t phys) { - page_map_set(z_x86_page_tables_get(), Z_SCRATCH_PAGE, + page_map_set(z_x86_page_tables_get(), K_MEM_SCRATCH_PAGE, phys | MMU_P | MMU_RW | MMU_XD, NULL, MASK_ALL, OPTION_FLUSH); } @@ -2230,7 +2231,7 @@ bool z_x86_kpti_is_access_ok(void *addr, pentry_t *ptables) /* Might as well also check if it's un-mapped, normally we don't * fetch the PTE from the page tables until we are inside - * z_page_fault() and call arch_page_fault_status_get() + * k_mem_page_fault() and call arch_page_fault_status_get() */ if (level != PTE_LEVEL || pte == 0 || is_flipped_pte(pte)) { return false; diff --git a/arch/x86/include/ia32/exception.h b/arch/x86/include/ia32/exception.h index 27119709c2adeb..1b0ce9ee3b52d5 100644 --- a/arch/x86/include/ia32/exception.h +++ b/arch/x86/include/ia32/exception.h @@ -62,7 +62,7 @@ * Assign an exception handler to a particular vector in the IDT. * * @param handler A handler function of the prototype - * void handler(const z_arch_esf_t *esf) + * void handler(const struct arch_esf *esf) * @param vector Vector index in the IDT */ #define _EXCEPTION_CONNECT_NOCODE(handler, vector, dpl) \ @@ -75,7 +75,7 @@ * The error code will be accessible in esf->errorCode * * @param handler A handler function of the prototype - * void handler(const z_arch_esf_t *esf) + * void handler(const struct arch_esf *esf) * @param vector Vector index in the IDT */ #define _EXCEPTION_CONNECT_CODE(handler, vector, dpl) \ diff --git a/arch/x86/include/intel64/kernel_arch_func.h b/arch/x86/include/intel64/kernel_arch_func.h index a749a9b9af1787..abf022fe5fd556 100644 --- a/arch/x86/include/intel64/kernel_arch_func.h +++ b/arch/x86/include/intel64/kernel_arch_func.h @@ -36,7 +36,7 @@ void x86_sse_init(struct k_thread *thread); void z_x86_syscall_entry_stub(void); -bool z_x86_do_kernel_nmi(const z_arch_esf_t *esf); +bool z_x86_do_kernel_nmi(const struct arch_esf *esf); #endif /* _ASMLANGUAGE */ diff --git a/arch/x86/include/kernel_arch_func.h b/arch/x86/include/kernel_arch_func.h index 00b411978ec65c..9bc7cfe4212f83 100644 --- a/arch/x86/include/kernel_arch_func.h +++ b/arch/x86/include/kernel_arch_func.h @@ -49,16 +49,16 @@ void z_x86_early_serial_init(void); * interesting info and call z_x86_fatal_error() */ FUNC_NORETURN void z_x86_unhandled_cpu_exception(uintptr_t vector, - const z_arch_esf_t *esf); + const struct arch_esf *esf); /* Called upon unrecoverable error; dump registers and transfer control to * kernel via z_fatal_error() */ FUNC_NORETURN void z_x86_fatal_error(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); /* Common handling for page fault exceptions */ -void z_x86_page_fault_handler(z_arch_esf_t *esf); +void z_x86_page_fault_handler(struct arch_esf *esf); #ifdef CONFIG_THREAD_STACK_INFO /** @@ -90,7 +90,7 @@ void *z_x86_userspace_prepare_thread(struct k_thread *thread); #endif /* CONFIG_USERSPACE */ -void z_x86_do_kernel_oops(const z_arch_esf_t *esf); +void z_x86_do_kernel_oops(const struct arch_esf *esf); /* * Find a free IRQ vector at the specified priority, or return -1 if none left. diff --git a/arch/x86/include/x86_mmu.h b/arch/x86/include/x86_mmu.h index 31c8526cb7a0b1..ed6bb59b37cb4f 100644 --- a/arch/x86/include/x86_mmu.h +++ b/arch/x86/include/x86_mmu.h @@ -182,7 +182,7 @@ static inline uintptr_t z_x86_cr3_get(void) /* Return the virtual address of the page tables installed in this CPU in CR3 */ static inline pentry_t *z_x86_page_tables_get(void) { - return z_mem_virt_addr(z_x86_cr3_get()); + return k_mem_virt_addr(z_x86_cr3_get()); } /* Return cr2 value, which contains the page fault linear address. @@ -215,7 +215,7 @@ static inline pentry_t *z_x86_thread_page_tables_get(struct k_thread *thread) * the kernel's page tables and not the page tables associated * with their memory domain. */ - return z_mem_virt_addr(thread->arch.ptables); + return k_mem_virt_addr(thread->arch.ptables); } #else ARG_UNUSED(thread); diff --git a/arch/xtensa/core/coredump.c b/arch/xtensa/core/coredump.c index 7f010eb1954a7b..0ee1f8992a6b70 100644 --- a/arch/xtensa/core/coredump.c +++ b/arch/xtensa/core/coredump.c @@ -91,7 +91,7 @@ struct xtensa_arch_block { */ static struct xtensa_arch_block arch_blk; -void arch_coredump_info_dump(const z_arch_esf_t *esf) +void arch_coredump_info_dump(const struct arch_esf *esf) { struct coredump_arch_hdr_t hdr = { .id = COREDUMP_ARCH_HDR_ID, diff --git a/arch/xtensa/core/fatal.c b/arch/xtensa/core/fatal.c index 0d5da1ca8179d6..39e84b86f6b138 100644 --- a/arch/xtensa/core/fatal.c +++ b/arch/xtensa/core/fatal.c @@ -84,7 +84,7 @@ char *xtensa_exccause(unsigned int cause_code) #endif } -void xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf) +void xtensa_fatal_error(unsigned int reason, const struct arch_esf *esf) { #ifdef CONFIG_EXCEPTION_DEBUG if (esf) { diff --git a/arch/xtensa/core/gdbstub.c b/arch/xtensa/core/gdbstub.c index 4df72f0d355c76..0ebc9cc68ccd51 100644 --- a/arch/xtensa/core/gdbstub.c +++ b/arch/xtensa/core/gdbstub.c @@ -422,7 +422,7 @@ static unsigned int get_gdb_exception_reason(unsigned int reason) * @param ctx GDB context * @param stack Pointer to the stack frame */ -static void copy_to_ctx(struct gdb_ctx *ctx, const z_arch_esf_t *stack) +static void copy_to_ctx(struct gdb_ctx *ctx, const struct arch_esf *stack) { struct xtensa_register *reg; int idx, num_laddr_regs; @@ -513,7 +513,7 @@ static void copy_to_ctx(struct gdb_ctx *ctx, const z_arch_esf_t *stack) * @param ctx GDB context * @param stack Pointer to the stack frame */ -static void restore_from_ctx(struct gdb_ctx *ctx, const z_arch_esf_t *stack) +static void restore_from_ctx(struct gdb_ctx *ctx, const struct arch_esf *stack) { struct xtensa_register *reg; int idx, num_laddr_regs; @@ -913,7 +913,7 @@ int arch_gdb_remove_breakpoint(struct gdb_ctx *ctx, uint8_t type, return ret; } -void z_gdb_isr(z_arch_esf_t *esf) +void z_gdb_isr(struct arch_esf *esf) { uint32_t reg; diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index f44e17ad6a953c..d934f16a213c8e 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -320,6 +320,24 @@ void xtensa_mmu_init(void) arch_xtensa_mmu_post_init(_current_cpu->id == 0); } +void xtensa_mmu_reinit(void) +{ + /* First initialize the hardware */ + xtensa_init_paging(xtensa_kernel_ptables); + +#ifdef CONFIG_USERSPACE + struct k_thread *thread = _current_cpu->current; + struct arch_mem_domain *domain = + &(thread->mem_domain_info.mem_domain->arch); + + + /* Set the page table for current context */ + xtensa_set_paging(domain->asid, domain->ptables); +#endif /* CONFIG_USERSPACE */ + + arch_xtensa_mmu_post_init(_current_cpu->id == 0); +} + #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES /* Zephyr's linker scripts for Xtensa usually puts * something before z_mapped_start (aka .text), @@ -335,7 +353,7 @@ __weak void arch_reserved_pages_update(void) for (page = CONFIG_SRAM_BASE_ADDRESS, idx = 0; page < (uintptr_t)z_mapped_start; page += CONFIG_MMU_PAGE_SIZE, idx++) { - z_page_frame_set(&z_page_frames[idx], Z_PAGE_FRAME_RESERVED); + k_mem_page_frame_set(&k_mem_page_frames[idx], K_MEM_PAGE_FRAME_RESERVED); } } #endif /* CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES */ diff --git a/arch/xtensa/core/smp.c b/arch/xtensa/core/smp.c index ffd08ab805c29e..71d8150025b071 100644 --- a/arch/xtensa/core/smp.c +++ b/arch/xtensa/core/smp.c @@ -19,3 +19,13 @@ void arch_spin_relax(void) #undef NOP1 } #endif /* CONFIG_XTENSA_MORE_SPIN_RELAX_NOPS */ + + +/** + * init for multi-core/smp is done on the SoC level. Add this here for + * compatibility with other SMP systems. + */ +int arch_smp_init(void) +{ + return 0; +} diff --git a/arch/xtensa/core/vector_handlers.c b/arch/xtensa/core/vector_handlers.c index dd3c0c00f52468..471a67c086304f 100644 --- a/arch/xtensa/core/vector_handlers.c +++ b/arch/xtensa/core/vector_handlers.c @@ -37,7 +37,7 @@ static const struct z_exc_handle exceptions[] = { }; #endif /* CONFIG_USERSPACE */ -void xtensa_dump_stack(const z_arch_esf_t *stack) +void xtensa_dump_stack(const void *stack) { _xtensa_irq_stack_frame_raw_t *frame = (void *)stack; _xtensa_irq_bsa_t *bsa = frame->ptr_to_bsa; @@ -218,9 +218,10 @@ static inline DEF_INT_C_HANDLER(1) * different because exceptions and interrupts land at the same * vector; other interrupt levels have their own vectors. */ -void *xtensa_excint1_c(int *interrupted_stack) +void *xtensa_excint1_c(void *esf) { int cause; + int *interrupted_stack = &((struct arch_esf *)esf)->dummy; _xtensa_irq_bsa_t *bsa = (void *)*(int **)interrupted_stack; bool is_fatal_error = false; bool is_dblexc = false; @@ -385,7 +386,7 @@ void *xtensa_excint1_c(int *interrupted_stack) #if defined(CONFIG_GDBSTUB) void *xtensa_debugint_c(int *interrupted_stack) { - extern void z_gdb_isr(z_arch_esf_t *esf); + extern void z_gdb_isr(struct arch_esf *esf); z_gdb_isr((void *)interrupted_stack); diff --git a/arch/xtensa/include/xtensa_internal.h b/arch/xtensa/include/xtensa_internal.h index 60b512ab571352..f3e1ab4f44e20b 100644 --- a/arch/xtensa/include/xtensa_internal.h +++ b/arch/xtensa/include/xtensa_internal.h @@ -25,7 +25,7 @@ * * @param stack Pointer to stack frame. */ -void xtensa_dump_stack(const z_arch_esf_t *stack); +void xtensa_dump_stack(const void *stack); /** * @brief Get string description from an exception code. @@ -43,7 +43,7 @@ char *xtensa_exccause(unsigned int cause_code); * @param esf Exception context, with details and partial or full register * state when the error occurred. May in some cases be NULL. */ -void xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +void xtensa_fatal_error(unsigned int reason, const struct arch_esf *esf); /** * @brief Perform a one-way transition from supervisor to user mode. diff --git a/boards/96boards/carbon/96b_carbon_stm32f401xe.dts b/boards/96boards/carbon/96b_carbon_stm32f401xe.dts index d94c67dc79d996..4f2365f303ebd9 100644 --- a/boards/96boards/carbon/96b_carbon_stm32f401xe.dts +++ b/boards/96boards/carbon/96b_carbon_stm32f401xe.dts @@ -20,6 +20,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &hci_spi; }; leds { @@ -124,7 +125,7 @@ pinctrl-names = "default"; /* Nordic nRF51822-QFAC */ - bt-hci@0 { + hci_spi: bt-hci@0 { compatible = "zephyr,bt-hci-spi"; reg = <0>; reset-gpios = <&gpiob 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; diff --git a/boards/96boards/carbon/Kconfig.defconfig b/boards/96boards/carbon/Kconfig.defconfig index cede46b95fe397..2cf1bbdc6fcec6 100644 --- a/boards/96boards/carbon/Kconfig.defconfig +++ b/boards/96boards/carbon/Kconfig.defconfig @@ -14,9 +14,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y endif # BT diff --git a/boards/actinius/icarus/actinius_icarus_common_2_0_0.dtsi b/boards/actinius/icarus/actinius_icarus_common_2_0_0.dtsi index 9c63a8de3351c0..802437900a8de4 100644 --- a/boards/actinius/icarus/actinius_icarus_common_2_0_0.dtsi +++ b/boards/actinius/icarus/actinius_icarus_common_2_0_0.dtsi @@ -39,10 +39,6 @@ }; / { - aliases { - spi-flash0 = &w25q64; - }; - charger_enable: charger-enable { compatible = "actinius-charger-enable"; gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; diff --git a/boards/actinius/icarus_bee/actinius_icarus_bee_common.dtsi b/boards/actinius/icarus_bee/actinius_icarus_bee_common.dtsi index 0bc57cd205acd1..f4972923e69075 100644 --- a/boards/actinius/icarus_bee/actinius_icarus_bee_common.dtsi +++ b/boards/actinius/icarus_bee/actinius_icarus_bee_common.dtsi @@ -79,7 +79,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &blue_led; watchdog0 = &wdt0; - spi-flash0 = &w25q64; accel0 = &lis2dh12_accel; }; diff --git a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_common.dtsi b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_common.dtsi index 317b0d153b7a74..683edc7bc5793a 100644 --- a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_common.dtsi +++ b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_common.dtsi @@ -55,7 +55,6 @@ mcuboot-led0 = &blue_led; watchdog0 = &wdt0; accel0 = &lis2dh12_accel; - spi-flash0 = &w25q64; led-strip = &neopixel_led; }; diff --git a/boards/adafruit/feather/adafruit_feather_nrf52840.dts b/boards/adafruit/feather/adafruit_feather_nrf52840.dts index 2333e5becbeda1..5c5eba7c503a11 100644 --- a/boards/adafruit/feather/adafruit_feather_nrf52840.dts +++ b/boards/adafruit/feather/adafruit_feather_nrf52840.dts @@ -60,7 +60,6 @@ led1 = &led1; sw0 = &button0; watchdog0 = &wdt0; - spi-flash0 = &gd25q16; }; }; diff --git a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts index cc1cb7020626b4..7995e359593075 100644 --- a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts +++ b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts @@ -31,7 +31,6 @@ aliases { led0 = &led; - spi-flash0 = &gd25q16; }; }; diff --git a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts index 45827a7bcec827..af2640954a5f0b 100644 --- a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts +++ b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts @@ -48,7 +48,6 @@ led0 = &led0; sw0 = &button0; watchdog0 = &wdt0; - spi-flash0 = &gd25q16; led-strip = &apa102; }; }; diff --git a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.dts b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.dts index 171e57963bcd8a..3b6934062e9cd4 100644 --- a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.dts +++ b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.dts @@ -54,7 +54,6 @@ aliases { led0 = &green_led; watchdog0 = &iwdg; - spi-flash0 = &mx25r6435f; ambient-temp0 = &adt7420; }; diff --git a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.dts b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.dts index 83a3343ca351d7..3a990815857f00 100644 --- a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.dts +++ b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.dts @@ -48,7 +48,6 @@ aliases { led0 = &blue_led; watchdog0 = &iwdg; - spi-flash0 = &flash_ext; }; }; diff --git a/boards/adi/max32655evkit/Kconfig.max32655evkit b/boards/adi/max32655evkit/Kconfig.max32655evkit new file mode 100644 index 00000000000000..2eed6e48c6089c --- /dev/null +++ b/boards/adi/max32655evkit/Kconfig.max32655evkit @@ -0,0 +1,7 @@ +# MAX32655EVKIT boards configuration + +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32655EVKIT + select SOC_MAX32655_M4 if BOARD_MAX32655EVKIT_MAX32655_M4 diff --git a/boards/adi/max32655evkit/board.cmake b/boards/adi/max32655evkit/board.cmake new file mode 100644 index 00000000000000..965de9e4de2aa1 --- /dev/null +++ b/boards/adi/max32655evkit/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/max32655.cfg]") +board_runner_args(jlink "--device=MAX32655" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32655evkit/board.yml b/boards/adi/max32655evkit/board.yml new file mode 100644 index 00000000000000..4824c6fe8e5967 --- /dev/null +++ b/boards/adi/max32655evkit/board.yml @@ -0,0 +1,8 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32655evkit + vendor: adi + socs: + - name: max32655 diff --git a/boards/adi/max32655evkit/doc/img/max32655evkit_img1.jpg b/boards/adi/max32655evkit/doc/img/max32655evkit_img1.jpg new file mode 100644 index 00000000000000..3b449c043495b5 Binary files /dev/null and b/boards/adi/max32655evkit/doc/img/max32655evkit_img1.jpg differ diff --git a/boards/adi/max32655evkit/doc/img/max32655evkit_img2.jpg b/boards/adi/max32655evkit/doc/img/max32655evkit_img2.jpg new file mode 100644 index 00000000000000..12b6444e361d53 Binary files /dev/null and b/boards/adi/max32655evkit/doc/img/max32655evkit_img2.jpg differ diff --git a/boards/adi/max32655evkit/doc/index.rst b/boards/adi/max32655evkit/doc/index.rst new file mode 100644 index 00000000000000..30ee39c9ce0038 --- /dev/null +++ b/boards/adi/max32655evkit/doc/index.rst @@ -0,0 +1,177 @@ +.. _max32655_evkit: + +MAX32655EVKIT +############# + +Overview +******** +The MAX32655 evaluation kit (EV kit) provides a platform for evaluation capabilities +of the MAX32655 microcontroller, which is an advanced system-on-chip (SoC). +It features an Arm® Cortex®-M4F CPU for efficient computation of complex functions and +algorithms, integrated power management (SIMO), and the newest generation +Bluetooth® 5.0 Low Energy (Bluetooth LE), long-range radio for wearable and hearable device applications. + +The Zephyr port is running on the MAX32655 MCU. + +.. image:: img/max32655evkit_img1.jpg + :align: center + :alt: MAX32655 EVKIT Front + +.. image:: img/max32655evkit_img2.jpg + :align: center + :alt: MAX32655 Back + +Hardware +******** + +- MAX32655 MCU: + + - Ultra-Low-Power Wireless Microcontroller + - Internal 100MHz Oscillator + - Flexible Low-Power Modes with 7.3728MHz System Clock Option + - 512KB Flash and 128KB SRAM (Optional ECC on One 32KB SRAM Bank) + - 16KB Instruction Cache + - Bluetooth 5.2 LE Radio + - Dedicated, Ultra-Low-Power, 32-Bit RISC-V Coprocessor to Offload Timing-Critical Bluetooth Processing + - Fully Open-Source Bluetooth 5.2 Stack Available + - Supports AoA, AoD, LE Audio, and Mesh + - High-Throughput (2Mbps) Mode + - Long-Range (125kbps and 500kbps) Modes + - Rx Sensitivity: -97.5dBm; Tx Power: +4.5dBm + - Single-Ended Antenna Connection (50Ω) + - Power Management Maximizes Battery Life + - 2.0V to 3.6V Supply Voltage Range + - Integrated SIMO Power Regulator + - Dynamic Voltage Scaling (DVS) + - 23.8μA/MHz Active Current at 3.0V + - 4.4μA at 3.0V Retention Current for 32KB + - Selectable SRAM Retention + RTC in Low-Power Modes + - Multiple Peripherals for System Control + - Up to Two High-Speed SPI Master/Slave + - Up to Three High-Speed I2C Master/Slave (3.4Mbps) + - Up to Four UART, One I2S Master/Slave + - Up to 8-Input, 10-Bit Sigma-Delta ADC 7.8ksps + - Up to Four Micro-Power Comparators + - Timers: Up to Two Four 32-Bit, Two LP, TwoWatchdog Timers + - 1-Wire® Master + - Up to Four Pulse Train (PWM) Engines + - RTC with Wake-Up Timer + - Up to 52 GPIOs + - Security and Integrity​ + - Available Secure Boot + - TRNG Seed Generator + - AES 128/192/256 Hardware Acceleration Engine + +- External devices connected to the MAX32655 EVKIT: + + - Color TFT Display + - Audio Stereo Codec Interface + - Digital Microphone + - A 128Mb QSPI flash + +Supported Features +================== + +Below are the interfaces supported by Zephyr on MAX32655EVKIT. + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Connections and IOs +=================== + ++-----------+---------------+-----------------------------------------------------------------------+ +| Name | Signal | Usage | ++===========+===============+=======================================================================+ +| JP1 | VREGI | Connect/Disconnect VREGIO power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP2 | P0_24 | Enable/Disable LED1 | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP3 | P0_25 | Enable/Disable LED2 | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP4 | P2_6/ P2_7 | Connect/Disconnect the USB to serial UART to GPIO P2_6 (LPUART_RX) | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP5 | P2_7/ P0_1 | Connect/Disconnect the USB to serial UART to GPIO P2_7 (LPUART_TX) | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP6 | P0_2 | Connect/Disconnect the USB to serial UART to GPIO P0_2 (UART0_CTS) | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP7 | P0_3 | Connect/Disconnect he USB to serial UART to GPIO P0_3 (UART0_RTS) | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP8 | VREGI | Select VDDIO_EN power source (3V3 or coin cell) | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP9 | VDDIOH_EN | Select VDDIOH_EN power source 3V3/VREGI | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP10 | VDDIOH | Connect/Disconnect VDDIOH power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP11 | VDDIO_EN | Select VDDIO_EN power source 1V8/VREGO_A | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP12 | VDDIO | Connect/Disconnect VDDIO power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP13 | VDDA_EN | Select VDDA_EN power source 1V8/VREGO_A | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP14 | VDDA | Connect/Disconnect VDDA power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP15 | VCOREA_EN | Select VCOREA_EN power source 1V1/VREGO_C | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP16 | VCOREA | Connect/Disconnect VCOREA power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP17 | VCOREB_EN | Select VCOREB_EN power source 1V1/VREGO_B | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP18 | VCOREB | Connect/Disconnect VCOREB power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP19 | BLE_LDO | Connect/Disconnect BLE_LDO power | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP20 | VREF | Select VREF power source VDDIO/VDDIOH | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP21 | I2C0_PU | Select I2C0_PU power source VDDIO/VDDIOH | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP22 | I2C1_PU | Select I2C1_PU power source VDDIO/VDDIOH | ++-----------+---------------+-----------------------------------------------------------------------+ +| JP23 | BOARD RESET | Connect/Disconnect RV JTAG NRESET from the BOARD RESET circuitry | ++-----------+---------------+-----------------------------------------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +The MAX32655 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH3. +Logic levels are fixed to VDDIO (1.8V). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (JW3) using an + appropriate adapter board and cable. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32655EVKIT web page`_ + +.. _MAX32655EVKIT web page: + https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/max32655evkit.html#eb-overview diff --git a/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts b/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts new file mode 100644 index 00000000000000..b1323a9bd3cd87 --- /dev/null +++ b/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023-2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + + #include + #include + #include + +/ { + model = "Analog Devices MAX32655EVKIT"; + compatible = "adi,max32655evkit"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + led2: led_2 { + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + pb1: pb1 { + gpios = <&gpio0 18 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + }; + pb2: pb2 { + gpios = <&gpio0 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3"; + }; + pb_wakeup: pb_wakeup { + gpios = <&gpio3 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW + | MAX32_GPIO_VSEL_VDDIOH)>; + label = "Wakeup"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + sw0 = &pb1; + sw1 = &pb2; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0a_tx_p0_1 &uart0a_rx_p0_0>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; diff --git a/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml b/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml new file mode 100644 index 00000000000000..257a0d060a9407 --- /dev/null +++ b/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml @@ -0,0 +1,13 @@ +identifier: max32655evkit/max32655/m4 +name: max32655evkit m4 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - serial +ram: 128 +flash: 512 diff --git a/boards/adi/max32655evkit/max32655evkit_max32655_m4_defconfig b/boards/adi/max32655evkit/max32655evkit_max32655_m4_defconfig new file mode 100644 index 00000000000000..4fa0a464106343 --- /dev/null +++ b/boards/adi/max32655evkit/max32655evkit_max32655_m4_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32655fthr/Kconfig.max32655fthr b/boards/adi/max32655fthr/Kconfig.max32655fthr new file mode 100644 index 00000000000000..589209a2fb3e2b --- /dev/null +++ b/boards/adi/max32655fthr/Kconfig.max32655fthr @@ -0,0 +1,7 @@ +# MAX32655FTHR boards configuration + +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32655FTHR + select SOC_MAX32655_M4 if BOARD_MAX32655FTHR_MAX32655_M4 diff --git a/boards/adi/max32655fthr/board.cmake b/boards/adi/max32655fthr/board.cmake new file mode 100644 index 00000000000000..d2353452cbe3cc --- /dev/null +++ b/boards/adi/max32655fthr/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/max32655.cfg]") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32655fthr/board.yml b/boards/adi/max32655fthr/board.yml new file mode 100644 index 00000000000000..087b51d8d958c1 --- /dev/null +++ b/boards/adi/max32655fthr/board.yml @@ -0,0 +1,8 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32655fthr + vendor: adi + socs: + - name: max32655 diff --git a/boards/adi/max32655fthr/doc/img/max32655fthr_img1.jpg b/boards/adi/max32655fthr/doc/img/max32655fthr_img1.jpg new file mode 100644 index 00000000000000..075a68e15fb6db Binary files /dev/null and b/boards/adi/max32655fthr/doc/img/max32655fthr_img1.jpg differ diff --git a/boards/adi/max32655fthr/doc/img/max32655fthr_img2.jpg b/boards/adi/max32655fthr/doc/img/max32655fthr_img2.jpg new file mode 100644 index 00000000000000..9976dfd48c4ba8 Binary files /dev/null and b/boards/adi/max32655fthr/doc/img/max32655fthr_img2.jpg differ diff --git a/boards/adi/max32655fthr/doc/img/max32655fthr_img3.jpg b/boards/adi/max32655fthr/doc/img/max32655fthr_img3.jpg new file mode 100644 index 00000000000000..f523ef2aed2561 Binary files /dev/null and b/boards/adi/max32655fthr/doc/img/max32655fthr_img3.jpg differ diff --git a/boards/adi/max32655fthr/doc/index.rst b/boards/adi/max32655fthr/doc/index.rst new file mode 100644 index 00000000000000..f6ba1b94f5929c --- /dev/null +++ b/boards/adi/max32655fthr/doc/index.rst @@ -0,0 +1,193 @@ +.. _max32655_fthr: + +MAX32655FTHR +############ + +Overview +******** +The MAX32655FTHR is a rapid development platform to help engineers quickly implement +ultra low-power wireless solutions using MAX32655 Arm© Cortex®-M4F and Bluetooth® 5.2 Low Energy (LE). +The board also includes the MAX20303 PMIC for battery and power management. +The form factor is a small 0.9in x 2.6in dual-row header footprint that is compatible +with Adafruit Feather Wing peripheral expansion boards. The board includes a variety of peripherals, +such as a digital microphone, lowpower stereo audio CODEC, 128MB QSPI Flash, micro SD card connector, +RGB indicator LED, and pushbutton. +The MAX32655FTHR provides a power-optimized flexible platform for quick proof-of-concepts and +early software development to enhance time to market. Go to +https://www.analog.com/MAX32655FTHR to get started developing with this board. + + +The Zephyr port is running on the MAX32655 MCU. + +.. image:: img/max32655fthr_img1.jpg + :align: center + :alt: MAX32655FTHR Front + +.. image:: img/max32655fthr_img2.jpg + :align: center + :alt: MAX32655FTHR Front Modules + +.. image:: img/max32655fthr_img3.jpg + :align: center + :alt: MAX32655FTHR Back + +Hardware +******** + +- MAX32655 MCU: + + - Ultra-Low-Power Wireless Microcontroller + - Internal 100MHz Oscillator + - Flexible Low-Power Modes with 7.3728MHz System Clock Option + - 512KB Flash and 128KB SRAM (Optional ECC on One 32KB SRAM Bank) + - 16KB Instruction Cache + - Bluetooth 5.2 LE Radio + - Dedicated, Ultra-Low-Power, 32-Bit RISC-V Coprocessor to Offload Timing-Critical Bluetooth Processing + - Fully Open-Source Bluetooth 5.2 Stack Available + - Supports AoA, AoD, LE Audio, and Mesh + - High-Throughput (2Mbps) Mode + - Long-Range (125kbps and 500kbps) Modes + - Rx Sensitivity: -97.5dBm; Tx Power: +4.5dBm + - Single-Ended Antenna Connection (50Ω) + - Power Management Maximizes Battery Life + - 2.0V to 3.6V Supply Voltage Range + - Integrated SIMO Power Regulator + - Dynamic Voltage Scaling (DVS) + - 23.8μA/MHz Active Current at 3.0V + - 4.4μA at 3.0V Retention Current for 32KB + - Selectable SRAM Retention + RTC in Low-Power Modes + - Multiple Peripherals for System Control + - Up to Two High-Speed SPI Master/Slave + - Up to Three High-Speed I2C Master/Slave (3.4Mbps) + - Up to Four UART, One I2S Master/Slave + - Up to 8-Input, 10-Bit Sigma-Delta ADC 7.8ksps + - Up to Four Micro-Power Comparators + - Timers: Up to Two Four 32-Bit, Two LP, TwoWatchdog Timers + - 1-Wire® Master + - Up to Four Pulse Train (PWM) Engines + - RTC with Wake-Up Timer + - Up to 52 GPIOs + - Security and Integrity​ + - Available Secure Boot + - TRNG Seed Generator + - AES 128/192/256 Hardware Acceleration Engine + +- External devices connected to the MAX32655FTHR: + + - Audio Stereo Codec Interface + - Digital Microphone + - PMIC and Battery Charger + - A 128Mb QSPI flash + - Micro SDCard Interface + - RGB LEDs + - Push Buttons + +Supported Features +================== + +Below are the interfaces supported by Zephyr on MAX32655FTHR. + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Push Buttons +************ +There are six pushbuttons on the MAX32655FTHR board + +SW1 +=== +PMIC Power Button, when the board is powered on state, pressing +this button for 12 seconds performs a hard powerdown. +When the board is in a powered-off state, pressing this button powers on the board. +This button can also be read by MAX32655 firmware, PMIC_PFN2 signal connected to Port 0.13 +is a buffered input of the button status. When the button is pressed, this signal goes to a logic-low +state. + +SW2 +=== +User-programmable function button connected to +MAX32655 Port 0.2 through a debouncer IC. + +SW3 +=== +User-programmable function button connected to +MAX32655 Port 0.3 through a debouncer IC. + +SW4 +=== +Wake-up button connected to MAX32655 Port 3.1. + +SW5 +=== +Resets the MAX32655 through RSTN input of the MAX32655. + +SW6 +=== +DAPLink adapter button. Keep this button +pressed while applying power to the board to +put the MAX32625 DAPLink adapter on board +to MAINTENANCE mode for DAPLink firmware +updates. + + +LEDs +**** +There are three RGB LEDs on the MAX32655FTHR board + +LED1 (D1) +========= +Connected to the MAX32655FTHR GPIO ports. +This LED can be controlled by user firmware. +Port 0.18: Red color +Port 0.19: Green color +Port 0.26: Blue color + +LED2 (D2) +========= +Connected to MAX20303 PMIC LEDx outputs. +These LEDs can be controlled through I2C commands. +They also can be configured as charge +status indicators by issuing I2C commands. + +LED3 (D3) +========= +DAPLink adapter MAX32625 status LED. +Controlled by the DAPLink adapter and cannot be +used as a user LED. + +Programming and Debugging +************************* + +Flashing +======== + +The MAX32625 microcontroller on the board is flashed with DAPLink firmware at the factory. +It allows debugging and flashing the MAX32655 Arm Core over USB. + +Once the USB cable is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32655FTHR web page`_ + +.. _MAX32655FTHR web page: + https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/max32655fthr.html diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts new file mode 100644 index 00000000000000..256e433091de29 --- /dev/null +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023-2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +/ { + model = "Analog Devices MAX32655FTHR"; + compatible = "adi,max32655fthr"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + led2: led_2 { + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + led3: led_3 { + gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + pb1: pb1 { + gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + }; + pb2: pb2 { + gpios = <&gpio0 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3"; + }; + pb_wakeup: pb_wakeup { + gpios = <&gpio3 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW + | MAX32_GPIO_VSEL_VDDIOH)>; + label = "Wakeup"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + led2 = &led3; + sw0 = &pb1; + sw1 = &pb2; + }; + + /* Used for accessing other pins */ + feather_header: feather_connector { + compatible = "adafruit-feather-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <12 0 &gpio0 31 0>, /* SDA */ + <13 0 &gpio0 30 0>, /* SCL */ + <14 0 &gpio1 9 0>, /* GPIO */ + <15 0 &gpio1 8 0>, /* GPIO */ + <16 0 &gpio0 20 0>, /* GPIO */ + <17 0 &gpio0 24 0>, /* GPIO */ + <18 0 &gpio0 25 0>, /* GPIO */ + <19 0 &gpio1 7 0>, /* GPIO */ + <20 0 &gpio1 6 0>, /* GPIO */ + /* 11 not connected */ + <10 0 &gpio2 7 0>, /* TX */ + <9 0 &gpio2 6 0>, /* RX */ + <8 0 &gpio0 22 0>, /* MISO */ + <7 0 &gpio0 21 0>, /* MOSI */ + <6 0 &gpio0 23 0>, /* SCK */ + <5 0 &gpio2 5 0>, /* AIN5 */ + <4 0 &gpio2 4 0>, /* AIN4 */ + <3 0 &gpio2 3 0>, /* AIN3 */ + <2 0 &gpio2 2 0>, /* AIN2 */ + <1 0 &gpio2 1 0>, /* AIN1 */ + <0 0 &gpio2 0 0>; /* AIN0 */ + }; +}; + +&uart0 { + pinctrl-0 = <&uart0a_tx_p0_1 &uart0a_rx_p0_0>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml b/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml new file mode 100644 index 00000000000000..af17994f344e71 --- /dev/null +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml @@ -0,0 +1,13 @@ +identifier: max32655fthr/max32655/m4 +name: max32655fthr m4 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - serial +ram: 128 +flash: 512 diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4_defconfig b/boards/adi/max32655fthr/max32655fthr_max32655_m4_defconfig new file mode 100644 index 00000000000000..4fa0a464106343 --- /dev/null +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32680evkit/Kconfig.max32680evkit b/boards/adi/max32680evkit/Kconfig.max32680evkit new file mode 100644 index 00000000000000..ad5115590bd6bc --- /dev/null +++ b/boards/adi/max32680evkit/Kconfig.max32680evkit @@ -0,0 +1,7 @@ +# MAX32680EVKIT boards configuration + +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32680EVKIT + select SOC_MAX32680_M4 if BOARD_MAX32680EVKIT_MAX32680_M4 diff --git a/boards/adi/max32680evkit/board.cmake b/boards/adi/max32680evkit/board.cmake new file mode 100644 index 00000000000000..bd318bb200d32c --- /dev/null +++ b/boards/adi/max32680evkit/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/max32680.cfg]") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32680evkit/board.yml b/boards/adi/max32680evkit/board.yml new file mode 100644 index 00000000000000..23b5102a97fdb3 --- /dev/null +++ b/boards/adi/max32680evkit/board.yml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32680evkit + vendor: adi + socs: + - name: max32680 diff --git a/boards/adi/max32680evkit/doc/img/max32680evkit_img1.jpg b/boards/adi/max32680evkit/doc/img/max32680evkit_img1.jpg new file mode 100644 index 00000000000000..c334dfe867ea73 Binary files /dev/null and b/boards/adi/max32680evkit/doc/img/max32680evkit_img1.jpg differ diff --git a/boards/adi/max32680evkit/doc/index.rst b/boards/adi/max32680evkit/doc/index.rst new file mode 100644 index 00000000000000..a06cffcc1386d5 --- /dev/null +++ b/boards/adi/max32680evkit/doc/index.rst @@ -0,0 +1,334 @@ +.. _max32680_evkit: + +MAX32680EVKIT +############# + +Overview +******** + +The MAX32680 evaluation kit (EV kit) provides a platform +for evaluation capabilities of the MAX32680 microcontroller, +which is an advanced system-on-chip (SoC) +designed for industrial and medical sensors. Power regulation +and management is provided by a single-inductor +multiple-output (SIMO) buck regulator system and contains +the latest generation Bluetooth® 5.2 Low Energy +(LE) radio. + +The Zephyr port is running on the MAX32680 MCU. + +.. image:: img/max32680evkit_img1.jpg + :align: center + :alt: MAX32680 EVKIT + + +Hardware +******** + +- MAX32680 MCU: + + - Ultra-Low-Power Wireless Microcontroller + + - Internal 100MHz Oscillator + - 512KB Flash and 128KB SRAM, Optional ECC on One 32KB SRAM Bank + + - Bluetooth 5.2 LE Radio + + - Dedicated, Ultra-Low-Power, 32-Bit RISC-VCoprocessor to Offload + + Timing-Critical Bluetooth Processing + + - Fully Open-Source Bluetooth 5.2 Stack Available + - Supports AoA, AoD, LE Audio, and Mesh + - High-Throughput (2Mbps) Mode•Long-Range (125kbps and 500kbps) Modes + - Rx Sensitivity: -97.5dBm; Tx Power: +4.5dBm + - Single-Ended Antenna Connection (50Ω) + + - Smart Integration Reduces BOM, Cost, and PCB Size + + - Two 16-Bit to 24-Bit Sigma-Delta ADCs + - 12 Channels, Assignable to Either ADC + - Flexible Resolution and Sample Rates + - 24-Bits at 0.4ksps, 16-Bits at 4ksps + - Four External Input, 10-Bit Sigma-Delta ADC 7.8ksps + - 12-Bit DAC + - On-Die Temperature Sensor + - Digital Peripherals: Two SPI, Two I2C, up to FourUART, and up to 36 GPIOs + - Timers: Six 32-Bit Timers, Two Watchdog Timers,Two Pulse Trains, 1-Wire® Master + + - Power Management Maximizes Battery Life + + - 2.0V to 3.6V Supply Voltage Range + - Integrated SIMO Power Regulator + - Dynamic Voltage Scaling (DVS) + - 23.8μA/MHz ACTIVE Mode Current at 3.0VCoremark® + - 4.4μA at 3.0V Retention Current for 32KB SRAM + - Selectable SRAM Retention in Low-Power Modes + + - Robust Security and Reliability + + - TRNG + - Secure Nonvolatile Key Storage and AES-128/192/256 + - Secure Boot to Protect IP/Firmware + - Wide, -40°C to +85°C Operating Temperature + +- External devices connected to the MAX32680 EVKIT: + + - SMA Connector for Attaching an External Bluetooth Antenna + - 128 x 128 (1.45in) Color TFT Display with SPI Interface + - Two Selectable On-Board, High-Precision Voltage References + - USB 2.0 Micro B to Serial UARTs + - UART1 and LPUART0 Interface is Selectable Through On-Board Jumpers + - All GPIOs Signals Accessed Through 0.1in Headers + - Access to Four Analog Inputs Through SMA Connectors Configured as Differential + - Access to Eight Analog Inputs Through 0.1in Headers Configured as Single-End + - Optional Discrete Filter for the Twelve Analog Inputs + - DAC Accessed Through SMA Connector or Test Point + - 10-Pin SWD Connector + - 10-Pin RV JTAG Connector + - Board Power Provided by USB Port + - On-Board 3.3V LDO Regulator to Power MAX32680 Internal SIMO + - Test Loops Provided to Supply Optional VCORE Power Externally + - Individual Power Measurement on All IC Rails Through Jumpers + - Two General Purpose LEDs and Two General Purpose Pushbutton Switches + +Supported Features +================== + +Below interfaces are supported by Zephyr on MAX32680EVKIT. + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Connections and IOs +=================== + ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| Name | Name | Settings | Description | ++===========+===============+===============+==================================================================================================+ +| JP1 | VREGI | | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects 3.3V power from the MAX32680 SIMO. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects 3.3V power to the MAX32680 SIMO. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP2 | REF0P | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Connects the external high-precision voltage refernce to REF0P. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects the internal voltage refernce to REF0P. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP3 | REF0N | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects REF0N from ground. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects REF0N to ground. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP4 | VDDIO_AUX | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects VDDIO_AUX from pull-ups and reference voltages. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects VDDIO_AUX to pull-ups and reference voltages. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP5 | VDDIOH | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Connects VREGO_A to VDDIOH. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects the 3.3V from the estrenal LDO to VDDIOH. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP6 | REF1P | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Connects the external high-precision voltage refernce to REF1P. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects the internal voltage refernce to REF1P. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP7 | REF1N | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects REF1N from ground. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects REF1N to ground. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP8 | I2C0_SDA | +-----------+ | +-------------------------------------------------------------------------------+ | +| | I2C0_SCL | | 2-1 | | | Connects I2C0 pullups to VDDIO_AUX (1.8V). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects I2C0 pullups to 3.3V. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP9 | I2C1_SDA | +-----------+ | +-------------------------------------------------------------------------------+ | +| | I2C1_SCL | | 2-1 | | | Connects I2C1 pullups to VDDIO_AUX (1.8V). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects I2C1 pullups to 3.3V. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP10 | P0_24 | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects red LED D1 from P0_24. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects red LED D1 to P0_24. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP11 | P0_25 | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects green LED D2 from P0_25. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects green LED D2 to P0_25. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP12 | FSK_IN | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects FSK_IN from HART analog circuitry. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects FSK_IN to HART analog circuitry. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP13 | RCV_FSK | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects RCV_FSK from CC LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects RCV_FSK to CC LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP14 | FSK_OUT | +-----------+ | +--------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects FSK_OUT from HART analog circuitry. | | +| | | +-----------+ | +--------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects FSK_OUT to HART analog circuitry. | | +| | | +-----------+ | +--------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP15 | RCV_FSK | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects RCV_FSK from XFMR LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects RCV_FSK to XFMR LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP16 | RLOAD | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects 249 ohm resistor shunt from CC LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects 249 ohm resistor shunt to CC LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP17 | FSK AMP GAIN | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Enables FSK variable amp gain. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Disables FSK variable amp gain. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP18 | AMP BYPASS | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Enables FSK amp. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Bypasses FSK amp. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP19 | FSK AMP GAIN | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Enables FSK fixed amp gain. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Disables FSK fixed amp gain. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP20 | HART_RTS | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Enables HART_RTS optical transceiver. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Bypasses HART_RTS optical transceiver. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP21 | RLOAD | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects 249 ohm resistor shunt from XFMR LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Closed | | | Connects 249 ohm resistor shunt to XFMR LOOP. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP22 | UART0_RX | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Disconnects the USB - serial bridge from UART1_RX (P0.12). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects the USB - serial bridge to LPUART_RX (P2.6). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP23 | UART0_TX | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Disonnects the USB - serial bridge from UART1_TX (P0.13). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Connects the USB - serial bridge to LPUART_TX (P2.7). | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP24 | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_IN | | | Open | | | Disconnects TX of USB - serial bridge from HART_IN (P0.1) | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_IN | | | 1-2 | | | Connects TX of USB - serial bridge to HART_IN (P0.1). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_OUT | | | Open | | | Disconnects RX of USB - serial bridge from HART_OUT (P0.0). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_OUT | | | 2-3 | | | Connects RX of USB - serial bridge to HART_OUT (P0.0). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_RTS | | | Open | | | Disconnects RTS of USB - serial bridge from HART_RTS (P0.3). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_RTS | | | 3-4 | | | Connects TX of USB - serial bridge to HART_RTS (P0.3). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_OCD | | | Open | | | Disconnects RTS of USB - serial bridge from HART_OCD (P0.2). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | HART_OCD | | | 4-5 | | | Connects TX of USB - serial bridge to HART_OCD (P0.2). | | +| | +-----------+ | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP25 | RSTN | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Open | | | Disconnects DUT_3V3_RSTN from RSTN. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | Close | | | Connects DUT_3V3_RSTN to RSTN. | | +| | | +-----------+ | +-------------------------------------------------------------------------------+ | +| | | | | ++-----------+---------------+---------------+--------------------------------------------------------------------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +The MAX32680 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH10. +Logic levels are set to 1.8V (VDDIO_AUX). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32680EVKIT web page`_ + +.. _MAX32680EVKIT web page: + https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/max32680evkit.html#eb-overview diff --git a/boards/adi/max32680evkit/max32680evkit_max32680_m4.dts b/boards/adi/max32680evkit/max32680evkit_max32680_m4.dts new file mode 100644 index 00000000000000..5fce323ce4156b --- /dev/null +++ b/boards/adi/max32680evkit/max32680evkit_max32680_m4.dts @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + + #include + #include + #include + +/ { + model = "Analog Devices MAX32680EVKIT"; + compatible = "adi,max32680evkit"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + led2: led_2 { + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + pb1: pb1 { + gpios = <&gpio0 26 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1"; + }; + pb2: pb2 { + gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + sw0 = &pb1; + sw1 = &pb2; + }; +}; + +&uart1 { + pinctrl-0 = <&uart1a_tx_p0_13 &uart1a_rx_p0_12>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml b/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml new file mode 100644 index 00000000000000..68e2baa65d7339 --- /dev/null +++ b/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml @@ -0,0 +1,13 @@ +identifier: max32680evkit/max32680/m4 +name: max32680evkit m4 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - serial +ram: 128 +flash: 512 diff --git a/boards/adi/max32680evkit/max32680evkit_max32680_m4_defconfig b/boards/adi/max32680evkit/max32680evkit_max32680_m4_defconfig new file mode 100644 index 00000000000000..a048ab2608ff0c --- /dev/null +++ b/boards/adi/max32680evkit/max32680evkit_max32680_m4_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32690evkit/doc/index.rst b/boards/adi/max32690evkit/doc/index.rst index 176a34ce2ba852..7da8592ff4f157 100644 --- a/boards/adi/max32690evkit/doc/index.rst +++ b/boards/adi/max32690evkit/doc/index.rst @@ -109,6 +109,10 @@ Below interfaces are supported by Zephyr on MAX32690EVKIT. +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++--------------------------------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ Connections and IOs diff --git a/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml b/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml index 2fb76416589625..38989aa05f7248 100644 --- a/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml +++ b/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml @@ -9,5 +9,7 @@ toolchain: supported: - gpio - serial + - spi + - i2c ram: 1024 flash: 3072 diff --git a/boards/alientek/pandora_stm32l475/pandora_stm32l475.dts b/boards/alientek/pandora_stm32l475/pandora_stm32l475.dts index 1c28f6c8176365..567e88a01523f9 100644 --- a/boards/alientek/pandora_stm32l475/pandora_stm32l475.dts +++ b/boards/alientek/pandora_stm32l475/pandora_stm32l475.dts @@ -27,8 +27,6 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - - spi-flash0 = &w25q128jv; }; leds { diff --git a/boards/ambiq/apollo3_evb/apollo3_evb.dts b/boards/ambiq/apollo3_evb/apollo3_evb.dts index c7856793e6795f..51b19c55e236f4 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb.dts +++ b/boards/ambiq/apollo3_evb/apollo3_evb.dts @@ -15,6 +15,7 @@ zephyr,shell-uart = &uart0; zephyr,uart-pipe = &uart0; zephyr,flash-controller = &flash; + zephyr,bt_hci = &bt_hci_apollo; }; aliases { @@ -101,6 +102,14 @@ status = "okay"; }; +&spi0 { + compatible = "ambiq,spi"; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + &i2c3 { compatible = "ambiq,i2c"; pinctrl-0 = <&i2c3_default>; diff --git a/boards/ambiq/apollo3_evb/apollo3_evb.yaml b/boards/ambiq/apollo3_evb/apollo3_evb.yaml index 09275d9e5f82b5..18327a617a763e 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb.yaml +++ b/boards/ambiq/apollo3_evb/apollo3_evb.yaml @@ -12,6 +12,7 @@ supported: - watchdog - counter - gpio + - spi - i2c testing: ignore_tags: diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts index bce6963242f758..277675449c4faf 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts @@ -15,6 +15,7 @@ zephyr,shell-uart = &uart0; zephyr,uart-pipe = &uart0; zephyr,flash-controller = &flash; + zephyr,bt_hci = &bt_hci_apollo; }; aliases { @@ -101,6 +102,14 @@ status = "okay"; }; +&spi0 { + compatible = "ambiq,spi"; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + &i2c3 { compatible = "ambiq,i2c"; pinctrl-0 = <&i2c3_default>; diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb.yaml b/boards/ambiq/apollo3p_evb/apollo3p_evb.yaml index 275c1efb6ef4c5..1a54a4a9d159b5 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb.yaml +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb.yaml @@ -12,6 +12,7 @@ supported: - watchdog - counter - gpio + - spi - i2c testing: ignore_tags: diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/Kconfig.defconfig b/boards/ambiq/apollo4p_blue_kxr_evb/Kconfig.defconfig index 87e1c5a8764f9d..7303c78a28644d 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/Kconfig.defconfig +++ b/boards/ambiq/apollo4p_blue_kxr_evb/Kconfig.defconfig @@ -9,10 +9,6 @@ if BT config MAIN_STACK_SIZE default 2048 -choice BT_HCI_BUS_TYPE - default BT_AMBIQ_HCI -endchoice - config BT_BUF_ACL_TX_COUNT default 14 diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index f9aa3c11c31c11..130a195154c8bf 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -15,6 +15,7 @@ zephyr,shell-uart = &uart0; zephyr,uart-pipe = &uart0; zephyr,flash-controller = &flash; + zephyr,bt-hci = &bt_hci_apollo; }; aliases { diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml index d9e9f244d861aa..9bd2496b1244bf 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml +++ b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.yaml @@ -20,3 +20,7 @@ testing: ignore_tags: - net vendor: ambiq +# Provisional hack to prevent tests being run in this board, as it fails in many test & samples: +twister: false +# Once https://github.com/zephyrproject-rtos/zephyr/issues/74212, 73443 & 72775 are fixed +# this should be removed diff --git a/boards/ambiq/apollo4p_evb/apollo4p_evb.yaml b/boards/ambiq/apollo4p_evb/apollo4p_evb.yaml index 205da184346bff..8b67616a27b322 100644 --- a/boards/ambiq/apollo4p_evb/apollo4p_evb.yaml +++ b/boards/ambiq/apollo4p_evb/apollo4p_evb.yaml @@ -20,3 +20,7 @@ testing: - net - bluetooth vendor: ambiq +# Provisional hack to prevent tests being run in this board, as it fails in many test & samples: +twister: false +# Once https://github.com/zephyrproject-rtos/zephyr/issues/74212, 73443 & 72775 are fixed +# this should be removed diff --git a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts index 0ffb4f75380fb9..5d6e0dd7d883c3 100644 --- a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts +++ b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.dts @@ -18,7 +18,7 @@ zephyr,console = &usart1; zephyr,shell-uart = &usart1; zephyr,uart-mcumgr = &usart1; - zephyr,bt-uart = &uart7; + zephyr,bt-hci = &bt_hci_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,canbus = &fdcan2; @@ -37,7 +37,6 @@ led0 = &red_led; led1 = &green_led; sw0 = &user_button; - spi-flash0 = &n25q128a1; }; }; @@ -98,12 +97,17 @@ status = "okay"; hw-flow-control; - murata-1dx { - compatible = "infineon,cyw43xxx-bt-hci"; - bt-reg-on-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>; - bt-host-wake-gpios = <&gpiog 3 GPIO_ACTIVE_HIGH>; - bt-dev-wake-gpios = <&gpioh 7 GPIO_ACTIVE_HIGH>; - fw-download-speed = <115200>; + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + + murata-1dx { + compatible = "infineon,cyw43xxx-bt-hci"; + bt-reg-on-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>; + bt-host-wake-gpios = <&gpiog 3 GPIO_ACTIVE_HIGH>; + bt-dev-wake-gpios = <&gpioh 7 GPIO_ACTIVE_HIGH>; + fw-download-speed = <115200>; + }; }; }; diff --git a/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.dts b/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.dts index 2329853a1a3bb6..52e376ed1405ee 100644 --- a/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.dts +++ b/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.dts @@ -8,6 +8,7 @@ #include #include "arduino_nicla_sense_me-pinctrl.dtsi" #include +#include / { model = "Arduino Nicla Sense ME"; @@ -37,7 +38,6 @@ aliases { sw0 = &user_button; watchdog0 = &wdt0; - spi-flash0 = &mx25r1635f; }; }; @@ -73,6 +73,18 @@ pinctrl-0 = <&i2c0_default>; pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; + + is31fl3194@53 { + compatible = "issi,is31fl3194"; + reg = <0x53>; + led_rgb { + label = "RGB LED"; + color-mapping = , + , + ; + current-limit = <10>; + }; + }; }; /* I2C1 in datasheet */ diff --git a/boards/arduino/portenta_h7/Kconfig.defconfig b/boards/arduino/portenta_h7/Kconfig.defconfig new file mode 100644 index 00000000000000..002ff75b5a551b --- /dev/null +++ b/boards/arduino/portenta_h7/Kconfig.defconfig @@ -0,0 +1,43 @@ +# Copyright 2024 Rahul Arasikere +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ARDUINO_PORTENTA_H7 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +if USB_DEVICE_STACK + +config USB_DEVICE_PRODUCT + default "Arduino SA Portenta H7" + +config USB_DEVICE_PID + default 0x035b + +config USB_DEVICE_VID + default 0x2341 + +config USB_DEVICE_INITIALIZE_AT_BOOT + default y + +if LOG + +# Logger cannot use itself to log +choice USB_CDC_ACM_LOG_LEVEL_CHOICE + default USB_CDC_ACM_LOG_LEVEL_OFF +endchoice + +# Set USB log level to error only +choice USB_DEVICE_LOG_LEVEL_CHOICE + default USB_DEVICE_LOG_LEVEL_ERR +endchoice + +endif # LOG + +endif # USB_DEVICE_STACK + +endif # BOARD_ARDUINO_PORTENTA_H7 diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi b/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi index 87d85f2726352d..e030d9d1cd0562 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi +++ b/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { leds { compatible = "gpio-leds"; @@ -18,6 +20,12 @@ }; }; + otghs_ulpi_phy: otghs_ulpis_phy { + compatible = "usb-ulpi-phy"; + reset-gpios = < &gpioj 4 GPIO_ACTIVE_LOW >; + #phy-cells = <0>; + }; + aliases { led0 = &red_led; led1 = &green_led; @@ -31,12 +39,12 @@ }; &rcc { - d1cpre = <1>; - hpre = <1>; - d1ppre = <1>; - d2ppre1 = <1>; - d2ppre2 = <2>; - d3ppre = <1>; + d1cpre = < 1 >; + hpre = < 2 >; + d1ppre = < 2 >; + d2ppre1 = < 2 >; + d2ppre2 = < 2 >; + d3ppre = < 2 >; }; /* UART0 in datasheet */ @@ -113,12 +121,129 @@ status = "okay"; }; -zephyr_udc0: &usbotg_fs { - pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; +&mailbox { + status = "okay"; +}; + +&fmc { + status = "okay"; + pinctrl-0 = < &fmc_d2_pd0 &fmc_d3_pd1 &fmc_d13_pd8 &fmc_d14_pd9 + &fmc_d15_pd10 &fmc_d0_pd14 &fmc_d1_pd15 &fmc_nbl0_pe0 + &fmc_nbl1_pe1 &fmc_d4_pe7 &fmc_d5_pe8 &fmc_d6_pe9 + &fmc_d7_pe10 &fmc_d8_pe11 &fmc_d9_pe12 &fmc_d10_pe13 + &fmc_d11_pe14 &fmc_d12_pe15 &fmc_a0_pf0 &fmc_a1_pf1 + &fmc_a2_pf2 &fmc_a3_pf3 &fmc_a4_pf4 &fmc_a5_pf5 + &fmc_sdnras_pf11 &fmc_a6_pf12 &fmc_a7_pf13 &fmc_a8_pf14 + &fmc_a9_pf15 &fmc_a10_pg0 &fmc_a11_pg1 &fmc_a12_pg2 + &fmc_a14_pg4 /* FMC_BA0 */ &fmc_a15_pg5 /* FMC_BA1 */ + &fmc_sdclk_pg8 &fmc_sdncas_pg15 &fmc_sdcke0_ph2 &fmc_sdne0_ph3 + &fmc_sdnwe_ph5 >; pinctrl-names = "default"; - status = "disabled"; + st,mem-swap = "disable"; + sdram { + status = "okay"; + mode-register = < 0x220 >; + + /** From Arduino github repository: + * RefreshRate = 64 ms / 8192 cyc = 7.8125 us/cyc + * RefreshCycles = 7.8125 us * 90 MHz = 703 + * According to the formula on p.1665 of the reference manual, + * we also need to subtract 20 from the value, so the target + * refresh rate is 703 - 20 = 683. + */ + refresh-rate = < 683 >; + num-auto-refresh = < 8 >; + + bank@0 { + reg = < 0 >; + st,sdram-control = < STM32_FMC_SDRAM_NC_8 + STM32_FMC_SDRAM_NR_12 + STM32_FMC_SDRAM_MWID_16 + STM32_FMC_SDRAM_NB_4 + STM32_FMC_SDRAM_CAS_2 + STM32_FMC_SDRAM_SDCLK_PERIOD_2 + STM32_FMC_SDRAM_RBURST_ENABLE + STM32_FMC_SDRAM_RPIPE_0 >; + st,sdram-timing = < 2 7 5 7 2 3 3 >; + }; + }; }; -&mailbox { +&quadspi { + pinctrl-0 = < &quadspi_bk1_io0_pd11 + &quadspi_bk1_io1_pd12 + &quadspi_bk1_io2_pf7 + &quadspi_bk1_io3_pd13 + &quadspi_bk1_ncs_pg6 + &quadspi_clk_pf10 >; + pinctrl-names = "default"; status = "okay"; + + mx25l12833f: qspi-nor-flash@90000000 { + compatible = "st,stm32-qspi-nor"; + reg = < 0x90000000 DT_SIZE_M(16) >; /* 128 MBits */ + qspi-max-frequency = < 40000000 >; + sfdp-bfp = [ e5 20 f1 ff ff ff ff 07 44 eb 08 6b 08 3b 04 bb + fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52 + 10 d8 00 ff 82 41 bd 00 81 e5 7b c6 44 03 67 38 + 30 b0 30 b0 f7 bd d5 5c 4a be 29 ff e1 d0 ff ff ]; + jedec-id = [ 66 66 20 ]; + spi-bus-width = <4>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = < 1 >; + #size-cells = < 1 >; + + storage_partition: partition@0 { + label = "storage"; + reg=< 0x0 DT_SIZE_K(15872) >; + }; + + wifi_firmware: partition@f80000 { + label = "wifi-firmware"; + reg = < 0xf80000 DT_SIZE_K(512) >; + }; + }; + }; +}; + +&mac { + pinctrl-0 = < ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_tx_en_pg11 + ð_txd1_pg12 + ð_txd0_pg13 >; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usbotg_hs { + pinctrl-0 = < &usb_otg_hs_ulpi_d0_pa3 + &usb_otg_hs_ulpi_ck_pa5 + &usb_otg_hs_ulpi_d1_pb0 + &usb_otg_hs_ulpi_d2_pb1 + &usb_otg_hs_ulpi_d7_pb5 + &usb_otg_hs_ulpi_d3_pb10 + &usb_otg_hs_ulpi_d4_pb11 + &usb_otg_hs_ulpi_d5_pb12 + &usb_otg_hs_ulpi_d6_pb13 + &usb_otg_hs_ulpi_stp_pc0 + &usb_otg_hs_ulpi_nxt_ph4 + &usb_otg_hs_ulpi_dir_pi11 >; + pinctrl-names = "default"; + phys = < &otghs_ulpi_phy >; + maximum-speed = "high-speed"; + /* Include the USB1ULPIEN | USB1OTGHSULPIEN clock enable bit */ + clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x6000000>, + <&rcc STM32_SRC_HSI48 USB_SEL(3)>; + num-bidir-endpoints = < 4 >; + status = "okay"; + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + }; }; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.dts b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.dts index e214fbdecd4d45..12190a28715b35 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.dts +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.dts @@ -24,7 +24,7 @@ }; &rcc { - clock-frequency = ; + clock-frequency = ; }; &usart1 { diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml index afbca313573ebe..352ae2b3cce890 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml @@ -14,4 +14,5 @@ testing: ignore_tags: - mpu - nfc + - flash vendor: arduino diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts index 4ad43a01c1cbc7..4b43bb6cbd4f82 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts @@ -15,11 +15,12 @@ /* HW resources are split between CM7 and CM4 */ chosen { - zephyr,console = &usart1; - zephyr,shell-uart = &usart1; + zephyr,console = &cdc_acm_uart0; + zephyr,shell-uart = &cdc_acm_uart0; + zephyr,cdc-acm-uart0 = &cdc_acm_uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &code_partition; + zephyr,code-partition = &slot0_partition; }; oscen: oscen { @@ -27,27 +28,56 @@ regulator-name = "oscen"; enable-gpios = <&gpioh 1 GPIO_ACTIVE_HIGH>; regulator-boot-on; + status = "okay"; + }; + + ethernet_phy_en: ethernet_phy_en { + compatible = "regulator-fixed"; + regulator-name = "ethernet-phy-reset-release"; + enable-gpios = <&gpioj 15 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + status = "okay"; + }; + + sdram1: sdram@c0000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + device_type = "memory"; + reg = <0xc0000000 DT_SIZE_M(8)>; + zephyr,memory-region = "SDRAM1"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; }; +&clk_hse { + clock-frequency = ; + hse-bypass; + status = "okay"; +}; + &clk_hsi { - hsi-div = <8>; + hsi-div = <1>; status = "okay"; }; &pll { - div-m = <1>; - mul-n = <24>; + div-m = <5>; + mul-n = <160>; div-p = <2>; - div-q = <4>; + div-q = <10>; div-r = <2>; - clocks = <&clk_hsi>; + clocks = <&clk_hse>; status = "okay"; }; +/** The power supply for the Portenta H7 is based on a ST PSU reference design. + * The design specification from this reference design limits the maximum + * clock speed to 400 MHz. + * Refer: section 8.1 of the reference design guide. + */ + &rcc { clocks = <&pll>; - clock-frequency = ; + clock-frequency = ; }; @@ -59,7 +89,16 @@ status = "okay"; }; +/* Only one should be enabled */ &usbotg_fs { + status = "disabled"; +}; + +&usbotg_hs { + status = "okay"; +}; + +&cdc_acm_uart0 { status = "okay"; }; @@ -70,27 +109,31 @@ #size-cells = <1>; boot_partition: partition@0 { - label = "bootloader"; - reg = <0x0 0x00040000>; + label = "mcuboot"; + reg = <0x00000000 0x00010000>; read-only; }; - - code_partition: partition@40000 { - label = "code"; - reg = <0x40000 0x000c0000>; - read-only; - }; - /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. - * - * Storage partition will be used by FCB/LittleFS/NVS - * if enabled. + * The flash starting at 0x00010000 and ending at + * 0x0001ffff (sectors 16-31) is reserved for use + * by the application. */ - storage_partition: partition@f8000 { - label = "storage"; - reg = <0x000f8000 0x00008000>; + scratch_partition: partition@10000 { + label = "image-scratch"; + reg = <0x00010000 0x00030000>; + }; + /* The arduino default bootloader occupies the address space 0x0 - 0x40000. + * This way regardless of the user's choice to use the mcuboot bootloader, + * applications will be located at 0x40000 which will be loaded by the + * arduino bootloader. + */ + slot0_partition: partition@40000 { + label = "image-0"; + reg = <0x00040000 0x00060000>; + }; + slot1_partition: partition@A0000 { + label = "image-1"; + reg = <0x000A0000 0x00060000>; }; }; }; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.overlay b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.overlay new file mode 100644 index 00000000000000..b60fff37ae065c --- /dev/null +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.overlay @@ -0,0 +1,9 @@ +/** + * Copyright (c) 2024 Rahul Arasikere . + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&clk_lsi { + status = "okay"; +}; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.overlay b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.overlay new file mode 100644 index 00000000000000..1860e51e1975ae --- /dev/null +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_4_10_0.overlay @@ -0,0 +1,10 @@ +/** + * Copyright (c) 2024 Rahul Arasikere . + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&clk_lse { + clock-frequency = <32768>; + status = "okay"; +}; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig index 18f533bf91d916..eef0bde3c46391 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig @@ -30,7 +30,11 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +CONFIG_UART_LINE_CTRL=y # Enable regulator CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y + +# Enable USB Stack +CONFIG_USB_DEVICE_STACK=y diff --git a/boards/arduino/portenta_h7/board.yml b/boards/arduino/portenta_h7/board.yml index be2ba58da962f1..01e28f0b5fdf07 100644 --- a/boards/arduino/portenta_h7/board.yml +++ b/boards/arduino/portenta_h7/board.yml @@ -3,3 +3,9 @@ board: vendor: arduino socs: - name: stm32h747xx + revision: + format: major.minor.patch + default: 1.0.0 + revisions: + - name: 1.0.0 + - name: 4.10.0 diff --git a/boards/arduino/portenta_h7/doc/index.rst b/boards/arduino/portenta_h7/doc/index.rst index 87b7aefdfe5d70..63d6e2da069c5c 100644 --- a/boards/arduino/portenta_h7/doc/index.rst +++ b/boards/arduino/portenta_h7/doc/index.rst @@ -56,9 +56,23 @@ The current Zephyr arduino_portenta_h7 board configuration supports the followin +-----------+------------+-------------------------------------+ | IPM | on-chip | virtual mailbox based on HSEM | +-----------+------------+-------------------------------------+ +| EXTFLASH | on-chip | qspi | ++-----------+------------+-------------------------------------+ +| SDRAM | on-chip | sdram | ++-----------+------------+-------------------------------------+ +| USB | on-board | usb-hs | ++-----------+------------+-------------------------------------+ +| ETHERNET | on-board | eth | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on Zephyr porting. +The high precision low speed external (LSE) clock is only fully supported on +boards with hardware revision 4.10 or greater. By default the internal source +is used; to enable the use of the external oscillator, manually specify the +hardware revision at build time (see :ref:`application_board_version` for +information on how to build for specific revisions of the board). + Resources sharing ================= diff --git a/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.dts b/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.dts index 9f8c84df95601c..f3eb05c6eb9b72 100644 --- a/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.dts +++ b/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.dts @@ -23,7 +23,6 @@ mcuboot-button0 = &button0; sensor0 = &light; sensor1 = &humidity; - spi-flash0 = &spi_flash0; }; chosen { diff --git a/boards/bytesatwork/bytesensi_l/Kconfig b/boards/bytesatwork/bytesensi_l/Kconfig new file mode 100644 index 00000000000000..fd8429f038965d --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_BYTESENSI_L diff --git a/boards/bytesatwork/bytesensi_l/Kconfig.bytesensi_l b/boards/bytesatwork/bytesensi_l/Kconfig.bytesensi_l new file mode 100644 index 00000000000000..530e716b540d41 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/Kconfig.bytesensi_l @@ -0,0 +1,6 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BYTESENSI_L + bool "bytesatwork bytesSENSI-L nRF52832" + select SOC_NRF52832_QFAA diff --git a/boards/bytesatwork/bytesensi_l/Kconfig.defconfig b/boards/bytesatwork/bytesensi_l/Kconfig.defconfig new file mode 100644 index 00000000000000..52c2d397af8569 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_BYTESENSI_L + +config BT_CTLR + default BT + +endif # BOARD_BYTESENSI_L diff --git a/boards/bytesatwork/bytesensi_l/board.cmake b/boards/bytesatwork/bytesensi_l/board.cmake new file mode 100644 index 00000000000000..efeed46003eff5 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nRF52832_xxAA" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/bytesatwork/bytesensi_l/board.yml b/boards/bytesatwork/bytesensi_l/board.yml new file mode 100644 index 00000000000000..04e4cd9ad1153b --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/board.yml @@ -0,0 +1,7 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 +board: + name: bytesensi_l + vendor: bytesatwork + socs: + - name: nrf52832 diff --git a/boards/bytesatwork/bytesensi_l/bytesensi_l.dts b/boards/bytesatwork/bytesensi_l/bytesensi_l.dts new file mode 100644 index 00000000000000..e54908293fb2b1 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/bytesensi_l.dts @@ -0,0 +1,151 @@ +/* + * Copyrigtt (c) 2024 bytesatwork AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "bytesensi_l_pinctrl.dtsi" + +#include + +/ { + model = "bytesatwork BLE/LORA sensor board"; + compatible = "bytesatwork,bytesensi-l"; + + chosen { + zephyr,console = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + /* Alias for lora samples */ + lora0 = &lora; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x32000>; + }; + slot1_partition: partition@3e000 { + label = "image-1"; + reg = <0x0003E000 0x32000>; + }; + scratch_partition: partition@70000 { + label = "image-scratch"; + reg = <0x00070000 0xa000>; + }; + storage_partition: partition@7a000 { + label = "storage"; + reg = <0x0007a000 0x00005000>; + }; + }; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; + + /* Enable 1-wire to enable i2c bus as well */ + one-wire-gpio { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-1 = <&i2c0_sleep>; + pinctrl-names = "default", "sleep"; + + light_sensor: apds9960@39 { + status = "okay"; + compatible = "avago,apds9960"; + reg = <0x39>; + int-gpios = <&gpio0 25 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + + temperature_sensor: tmp116@4a { + status = "okay"; + compatible = "ti,tmp116"; + reg = <0x4a>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom: ti_tmp116_eeprom@0 { + compatible = "ti,tmp116-eeprom"; + reg = <0x0>; + read-only; + }; + }; + + gas_sensor: ccs811@5a { + status = "okay"; + compatible = "ams,ccs811"; + reg = <0x5a>; + irq-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + wake-gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; + }; + + pressure_sensor: lps22hb-press@5c { + status = "okay"; + compatible = "st,lps22hb-press"; + reg = <0x5c>; + }; +}; + +&spi1 { + status = "okay"; + compatible = "nordic,nrf-spi"; + pinctrl-0 = <&spi1_default>; + pinctrl-1 = <&spi1_sleep>; + pinctrl-names = "default", "sleep"; + cs-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>, + <&gpio0 5 GPIO_ACTIVE_LOW>; + + lora: lora@0 { + status = "okay"; + compatible = "semtech,sx1276"; + reg = <0>; + reset-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + dio-gpios = + <&gpio0 19 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpio0 20 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpio0 22 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpio0 23 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + spi-max-frequency = <1000000>; + power-amplifier-output = "pa-boost"; + }; + + nor_flash: mx25r6435f@1 { + status = "okay"; + compatible ="jedec,spi-nor"; + size = <0x4000000>; + reg = <1>; + spi-max-frequency = <8000000>; + status = "okay"; + jedec-id = [c2 28 17]; + }; +}; diff --git a/boards/bytesatwork/bytesensi_l/bytesensi_l.yaml b/boards/bytesatwork/bytesensi_l/bytesensi_l.yaml new file mode 100644 index 00000000000000..362508e67a2fa4 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/bytesensi_l.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 +identifier: bytesensi_l +name: bytesatwork byteSENSI-L +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 512 +supported: + - ble + - gpio + - i2c + - lora + - spi +vendor: bytesatwork diff --git a/boards/bytesatwork/bytesensi_l/bytesensi_l_defconfig b/boards/bytesatwork/bytesensi_l/bytesensi_l_defconfig new file mode 100644 index 00000000000000..80cef47e867819 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/bytesensi_l_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable console over segger RTT +CONFIG_CONSOLE=y +CONFIG_RTT_CONSOLE=y +CONFIG_USE_SEGGER_RTT=y diff --git a/boards/bytesatwork/bytesensi_l/bytesensi_l_pinctrl.dtsi b/boards/bytesatwork/bytesensi_l/bytesensi_l_pinctrl.dtsi new file mode 100644 index 00000000000000..8b31ab2d3b04a7 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/bytesensi_l_pinctrl.dtsi @@ -0,0 +1,54 @@ +/* + * Copyrigtt (c) 2024 bytesatwork AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + psels = , + ; + }; + }; + + i2c0_sleep: i2c0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + spi1_default: spi1_default{ + group1 { + psels = , + , + ; + }; + }; + + spi1_sleep: spi1_sleep{ + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/bytesatwork/bytesensi_l/doc/img/byteSENSI-L.jpg b/boards/bytesatwork/bytesensi_l/doc/img/byteSENSI-L.jpg new file mode 100644 index 00000000000000..5baccde618f445 Binary files /dev/null and b/boards/bytesatwork/bytesensi_l/doc/img/byteSENSI-L.jpg differ diff --git a/boards/bytesatwork/bytesensi_l/doc/index.rst b/boards/bytesatwork/bytesensi_l/doc/index.rst new file mode 100644 index 00000000000000..5c9ca7f7b9ffc1 --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/doc/index.rst @@ -0,0 +1,157 @@ +.. _bytesensi_l: + +bytesatwork byteSENSI-L +####################### + +Overview +******** + +The byteSENSI-L is a fun LoRa device based on nRF52 MCU that integrates many +sensors. + +.. image:: img/byteSENSI-L.jpg + :width: 800px + :align: center + :alt: byteSENSI-L + +Hardware +******** + +Supported Features +================== + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth | ++-----------+------------+----------------------+ +| RADIO | Semtech | LoRa | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Connections and IOs +=================== + +External Connectors +------------------- + +External Supply @ X1 + ++-------+--------------+---------------------------------------+ +| PIN # | Signal Name | Function | ++=======+==============+=======================================+ +| 1 | VBAT | Power input instead of CR2477 battery | ++-------+--------------+---------------------------------------+ +| 2 | GND | Ground | ++-------+--------------+---------------------------------------+ + +Programming Connector @ SL1 + ++-------+--------------+ +| PIN # | Signal Name | ++=======+==============+ +| 1 | VBAT | ++-------+--------------+ +| 2 | SWDIO | ++-------+--------------+ +| 3 | GND | ++-------+--------------+ +| 4 | SWDCLK | ++-------+--------------+ +| 5 | GND | ++-------+--------------+ +| 6 | NC (SWO) | ++-------+--------------+ +| 7 | NC (Key) | ++-------+--------------+ +| 8 | NC | ++-------+--------------+ +| 9 | GND | ++-------+--------------+ +| 10 | nReset | ++-------+--------------+ + +I2C Sensor @ X3 + ++-------+--------------+-------------------------+ +| PIN # | Signal Name | Function | ++=======+==============+=========================+ +| 1 | VBAT | Power out | ++-------+--------------+-------------------------+ +| 2 | SCL | I2C clock at P0.15 | ++-------+--------------+-------------------------+ +| 3 | SDA | I2C data at P0.16 | ++-------+--------------+-------------------------+ +| 4 | INT | Interrupt at P0.13 | ++-------+--------------+-------------------------+ +| 5 | I2C_ADDR | tied to VBAT | ++-------+--------------+-------------------------+ +| 6 | GND | Ground | ++-------+--------------+-------------------------+ + +One Wire Sensor @ X2 + ++-------+----------------+-------------------------+ +| PIN # | Signal Name | Function | ++=======+================+=========================+ +| 1 | VDD | 4V8 | ++-------+----------------+-------------------------+ +| 2 | IO | One Wire | ++-------+----------------+-------------------------+ +| 3 | GND | Ground | ++-------+----------------+-------------------------+ + +External BLE Antenna @ J1 + +External LoRa Antenna @ J2 + +External GPS Antenna @ J3 + +Programming and Debugging +************************* + +Flashing +======== +The byteSENSI-L board can be flashed with the SEGGER JLink programmer. + +You can build and flash applications in the usual way. Here is an example for +the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: bytesensi_l + :goals: build flash + :compact: + +Debugging +========= + +Debugging your application can be done with ``west debug``. + +Serial console +============== + +The byteSENSI-L board only uses Segger's RTT console for providing serial +console. There is no physical serial port available. + +References +********** +* `bytesatwork website `_ +* `bytesatwork wiki `_ diff --git a/boards/bytesatwork/bytesensi_l/pre_dt_board.cmake b/boards/bytesatwork/bytesensi_l/pre_dt_board.cmake new file mode 100644 index 00000000000000..4bcc2f7a610aea --- /dev/null +++ b/boards/bytesatwork/bytesensi_l/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 bytesatwork AG +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - power@40000000 & clock@40000000 & bprot@40000000 +# - acl@4001e000 & flash-controller@4001e000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/bytesatwork/index.rst b/boards/bytesatwork/index.rst new file mode 100644 index 00000000000000..cb47fbff333258 --- /dev/null +++ b/boards/bytesatwork/index.rst @@ -0,0 +1,10 @@ +.. _boards-bytesatwork: + +bytesatwork +########### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_common.dtsi b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_common.dtsi index 00ce5dcf6c00cf..ced868614da980 100644 --- a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_common.dtsi +++ b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_common.dtsi @@ -50,7 +50,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &blue_led; watchdog0 = &wdt0; - spi-flash0 = &w25q32jv; accel0 = &lis2dh; }; diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_common.dtsi b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_common.dtsi index 437ea9ad225a07..764348106c9f74 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_common.dtsi +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_common.dtsi @@ -86,7 +86,8 @@ &spi6 { cs-gpios = <&gpio_prt12 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, - <&gpio_prt13 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + <&gpio_prt13 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; - pinctrl-0 = <&p12_0_spi6_mosi &p12_1_spi6_miso &p12_2_spi6_clk>; + pinctrl-0 = <&p12_0_scb6_spi_m_mosi &p12_1_scb6_spi_m_miso &p12_2_scb6_spi_m_clk>; + pinctrl-names = "default"; }; diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347-pinctrl.dtsi b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347-pinctrl.dtsi new file mode 100644 index 00000000000000..1e42a6e464699e --- /dev/null +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347-pinctrl.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Configure pin control bias mode for uart5 pins */ +&p5_1_scb5_uart_tx { + drive-push-pull; +}; + +&p5_0_scb5_uart_rx { + input-enable; +}; + +&p9_1_scb2_uart_tx { + drive-push-pull; +}; + +&p9_0_scb2_uart_rx { + input-enable; +}; + +&p13_1_scb6_uart_tx { + drive-push-pull; +}; + +&p13_0_scb6_uart_rx { + input-enable; +}; + +/* Configure pin control bias mode for SPI pins */ +&p12_0_scb6_spi_m_mosi { + drive-push-pull; +}; + +&p12_1_scb6_spi_m_miso { + input-enable; +}; + +&p12_2_scb6_spi_m_clk { + drive-push-pull; +}; diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.overlay b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.overlay index eab076f247cb86..9ef0f747cd06a1 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.overlay +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.overlay @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "cy8ckit_062_ble_cy8c6347-pinctrl.dtsi" / { aliases { @@ -21,7 +22,8 @@ interrupt-parent = <&intmux_ch21>; - pinctrl-0 = <&p5_0_uart5_rx &p5_1_uart5_tx>; + pinctrl-0 = <&p5_0_scb5_uart_rx &p5_1_scb5_uart_tx>; + pinctrl-names = "default"; }; arduino_serial: &uart5 {}; diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.overlay b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.overlay index 49944a6dea498f..ea63d017a65151 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.overlay +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "cy8ckit_062_ble_cy8c6347-pinctrl.dtsi" + / { aliases { uart-2 = &uart2; @@ -21,7 +23,9 @@ interrupt-parent = <&intmux_ch21>; - pinctrl-0 = <&p9_0_uart2_rx &p9_1_uart2_tx>; + pinctrl-0 = <&p9_0_scb2_uart_rx &p9_1_scb2_uart_tx>; + pinctrl-names = "default"; + }; &uart5 { @@ -30,7 +34,9 @@ interrupt-parent = <&intmux_ch22>; - pinctrl-0 = <&p5_0_uart5_rx &p5_1_uart5_tx>; + pinctrl-0 = <&p5_0_scb5_uart_rx &p5_1_scb5_uart_tx>; + pinctrl-names = "default"; + }; arduino_serial: &uart5 {}; diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.overlay b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.overlay index 9284d41cea78e5..26f422a9b4dc38 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.overlay +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "cy8ckit_062_ble_cy8c6347-pinctrl.dtsi" + / { aliases { uart-6 = &uart6; @@ -19,5 +21,6 @@ status = "okay"; current-speed = <115200>; - pinctrl-0 = <&p13_0_uart6_rx &p13_1_uart6_tx>; + pinctrl-0 = <&p13_0_scb6_uart_rx &p13_1_scb6_uart_tx>; + pinctrl-names = "default"; }; diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247-pinctrl.dtsi b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247-pinctrl.dtsi new file mode 100644 index 00000000000000..1e42a6e464699e --- /dev/null +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247-pinctrl.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Configure pin control bias mode for uart5 pins */ +&p5_1_scb5_uart_tx { + drive-push-pull; +}; + +&p5_0_scb5_uart_rx { + input-enable; +}; + +&p9_1_scb2_uart_tx { + drive-push-pull; +}; + +&p9_0_scb2_uart_rx { + input-enable; +}; + +&p13_1_scb6_uart_tx { + drive-push-pull; +}; + +&p13_0_scb6_uart_rx { + input-enable; +}; + +/* Configure pin control bias mode for SPI pins */ +&p12_0_scb6_spi_m_mosi { + drive-push-pull; +}; + +&p12_1_scb6_spi_m_miso { + input-enable; +}; + +&p12_2_scb6_spi_m_clk { + drive-push-pull; +}; diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.dts b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.dts index 18fe196201b2f4..73766b76c10494 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.dts +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.dts @@ -9,6 +9,7 @@ #include #include +#include "cy8ckit_062_wifi_bt_cy8c6247-pinctrl.dtsi" / { model = "cy8ckit_062_wifi_bt_m0 with a Cypress PSoC6 SoC"; @@ -61,5 +62,6 @@ interrupt-parent = <&intmux_ch21>; - pinctrl-0 = <&p13_0_uart6_rx &p13_1_uart6_tx>; + pinctrl-0 = <&p13_0_scb6_uart_rx &p13_1_scb6_uart_tx>; + pinctrl-names = "default"; }; diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.dts b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.dts index 7cd87ba86342fa..29ea4b85134c34 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.dts +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include "cy8ckit_062_wifi_bt_cy8c6247-pinctrl.dtsi" / { model = "cy8ckit_062_wifi_bt_m4 with a Cypress PSoC6 SoC"; @@ -28,5 +29,6 @@ status = "okay"; current-speed = <115200>; - pinctrl-0 = <&p5_0_uart5_rx &p5_1_uart5_tx>; + pinctrl-0 = <&p5_0_scb5_uart_rx &p5_1_scb5_uart_tx>; + pinctrl-names = "default"; }; diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 89a8b463e69e55..f1a40a8b318726 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -138,31 +138,61 @@ set(ebyte_e73_tbb_nrf52832_DEPRECATED ebyte_e73_tbb ) set(efm32pg_stk3402a_DEPRECATED - efm32pg_stk3402a/efm32pg12b500f1024gl125 + slstk3402a/efm32pg12b500f1024gl125 ) set(efm32pg_stk3402a_jg_DEPRECATED - efm32pg_stk3402a/efm32jg12b500f1024gl125 + slstk3402a/efm32jg12b500f1024gl125 +) +set(efm32hg_slstk3400a_DEPRECATED + slstk3400a +) +set(efm32pg_stk3401a_DEPRECATED + slstk3401a +) +set(efm32gg_stk3701a_DEPRECATED + slstk3701a +) +set(efm32gg_slwstk6121a_DEPRECATED + slwrb4321a ) set(efr32_radio_brd4104a_DEPRECATED - efr32_radio/efr32bg13p632f512gm48 + slwrb4104a ) set(efr32_radio_brd4161a_DEPRECATED - efr32_radio/efr32mg12p432f1024gl125 + slwrb4161a ) set(efr32_radio_brd4170a_DEPRECATED - efr32_radio/efr32mg12p433f1024gm68 + slwrb4170a ) set(efr32_radio_brd4180a_DEPRECATED - efr32_radio/efr32mg21a020f1024im32 + slwrb4180a ) set(efr32_radio_brd4187c_DEPRECATED - efr32_radio/efr32mg24b220f1536im48 + xg24_rb4187c ) set(efr32_radio_brd4250b_DEPRECATED - efr32_radio/efr32fg1p133f256gm48 + slwrb4250b ) set(efr32_radio_brd4255a_DEPRECATED - efr32_radio/efr32fg13p233f512gm48 + slwrb4255a +) +set(efm32gg_sltb009a_DEPRECATED + sltb009a +) +set(efr32mg_sltb004a_DEPRECATED + sltb004a +) +set(efr32bg22_brd4184a_DEPRECATED + sltb010a@0 +) +set(efr32bg22_brd4184b_DEPRECATED + sltb010a@2 +) +set(efr32xg24_dk2601b_DEPRECATED + xg24_dk2601b +) +set(efr32bg27_brd2602a_DEPRECATED + xg27_dk2602a ) set(em_starterkit_DEPRECATED em_starterkit/emsk_em9d diff --git a/boards/digilent/arty_a7/dts/arty_a7_arm_designstart.dtsi b/boards/digilent/arty_a7/dts/arty_a7_arm_designstart.dtsi index 0f51819e180763..8162b47d7d3d79 100644 --- a/boards/digilent/arty_a7/dts/arty_a7_arm_designstart.dtsi +++ b/boards/digilent/arty_a7/dts/arty_a7_arm_designstart.dtsi @@ -26,7 +26,6 @@ sw1 = &sw1; sw2 = &sw2; sw3 = &sw3; - spi-flash0 = &flash0; }; leds { diff --git a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts index eab0c152666168..98971ae4f1a462 100644 --- a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts +++ b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts @@ -23,6 +23,10 @@ }; }; +&ctrl0 { + status = "okay"; +}; + &uart0 { status = "okay"; current-speed = <115200>; diff --git a/boards/espressif/esp32_devkitc_wroom/Kconfig.defconfig b/boards/espressif/esp32_devkitc_wroom/Kconfig.defconfig index 6da35bf9735f03..374b423b5483cc 100644 --- a/boards/espressif/esp32_devkitc_wroom/Kconfig.defconfig +++ b/boards/espressif/esp32_devkitc_wroom/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32_DEVKITC_WROOM_ESP32_PROCPU if BOARD_ESP32_DEVKITC_WROOM_ESP32_APPCPU diff --git a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts index 6ba26177f52501..37a117d80dbe98 100644 --- a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts +++ b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts @@ -36,6 +36,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -165,3 +166,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp32_devkitc_wrover/Kconfig.defconfig b/boards/espressif/esp32_devkitc_wrover/Kconfig.defconfig index ba249b4a0a6afb..c56c404a40e7f7 100644 --- a/boards/espressif/esp32_devkitc_wrover/Kconfig.defconfig +++ b/boards/espressif/esp32_devkitc_wrover/Kconfig.defconfig @@ -10,10 +10,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32_DEVKITC_WROVER_ESP32_PROCPU if BOARD_ESP32_DEVKITC_WROVER_ESP32_APPCPU diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts index 8d414b1e8903ff..f6ad45109c3981 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts @@ -36,6 +36,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -161,3 +162,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp32_ethernet_kit/Kconfig.defconfig b/boards/espressif/esp32_ethernet_kit/Kconfig.defconfig index e7f2edb7c059f5..75b0cc9f631efd 100644 --- a/boards/espressif/esp32_ethernet_kit/Kconfig.defconfig +++ b/boards/espressif/esp32_ethernet_kit/Kconfig.defconfig @@ -6,7 +6,7 @@ if BOARD_ESP32_ETHERNET_KIT_ESP32_PROCPU config ESP_SPIRAM - default y + default y if !MCUBOOT choice SPIRAM_TYPE default SPIRAM_TYPE_ESPPSRAM64 @@ -19,10 +19,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32_ETHERNET_KIT_ESP32_PROCPU if BOARD_ESP32_ETHERNET_KIT_ESP32_APPCPU diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts index 7c6c32970b7452..124fa29df4e99c 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -122,3 +123,7 @@ ð { phy-handle = <&phy>; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp32c3_devkitm/Kconfig.defconfig b/boards/espressif/esp32c3_devkitm/Kconfig.defconfig index 9944bb871951b5..cf5aeac8382d07 100644 --- a/boards/espressif/esp32c3_devkitm/Kconfig.defconfig +++ b/boards/espressif/esp32c3_devkitm/Kconfig.defconfig @@ -9,7 +9,3 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 51200 if WIFI default 40960 if BT default 4096 - -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts index 039e72b48935c9..ae11ed41aa2e25 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -130,3 +131,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp32s3_devkitc/Kconfig.defconfig b/boards/espressif/esp32s3_devkitc/Kconfig.defconfig index 9b109ab4525bd6..d539cd6652349f 100644 --- a/boards/espressif/esp32s3_devkitc/Kconfig.defconfig +++ b/boards/espressif/esp32s3_devkitc/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32S3_DEVKITC_ESP32S3_PROCPU if BOARD_ESP32S3_DEVKITC_ESP32S3_APPCPU diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts index 8894649a1bcc24..afff520f7ba14c 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts @@ -25,6 +25,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -168,3 +169,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp32s3_devkitm/Kconfig.defconfig b/boards/espressif/esp32s3_devkitm/Kconfig.defconfig index 1905ae5f5515ba..26339590ee31e4 100644 --- a/boards/espressif/esp32s3_devkitm/Kconfig.defconfig +++ b/boards/espressif/esp32s3_devkitm/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32S3_DEVKITM_ESP32S3_PROCPU if BOARD_ESP32S3_DEVKITM_ESP32S3_APPCPU diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts index 3ee4131ab33c60..c88bf0d01012e2 100644 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts +++ b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts @@ -25,6 +25,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -172,3 +173,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/espressif/esp_wrover_kit/Kconfig.defconfig b/boards/espressif/esp_wrover_kit/Kconfig.defconfig index a05a1684d6b14f..adf8cd7e3980e0 100644 --- a/boards/espressif/esp_wrover_kit/Kconfig.defconfig +++ b/boards/espressif/esp_wrover_kit/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - config DISK_DRIVER_SDMMC default y diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts index ad900df0e46d4e..5edfe4f761caae 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts @@ -36,6 +36,7 @@ zephyr,code-partition = &slot0_partition; zephyr,display = &ili9341; zephyr,sdhc = &sdhc1; + zephyr,bt-hci = &esp32_bt_hci; }; leds { @@ -243,3 +244,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/lairdconnect/bl5340_dvk/CMakeLists.txt b/boards/ezurio/bl5340_dvk/CMakeLists.txt similarity index 100% rename from boards/lairdconnect/bl5340_dvk/CMakeLists.txt rename to boards/ezurio/bl5340_dvk/CMakeLists.txt diff --git a/boards/lairdconnect/bl5340_dvk/Kconfig b/boards/ezurio/bl5340_dvk/Kconfig similarity index 100% rename from boards/lairdconnect/bl5340_dvk/Kconfig rename to boards/ezurio/bl5340_dvk/Kconfig diff --git a/boards/lairdconnect/bl5340_dvk/Kconfig.bl5340_dvk b/boards/ezurio/bl5340_dvk/Kconfig.bl5340_dvk similarity index 100% rename from boards/lairdconnect/bl5340_dvk/Kconfig.bl5340_dvk rename to boards/ezurio/bl5340_dvk/Kconfig.bl5340_dvk diff --git a/boards/lairdconnect/bl5340_dvk/Kconfig.defconfig b/boards/ezurio/bl5340_dvk/Kconfig.defconfig similarity index 98% rename from boards/lairdconnect/bl5340_dvk/Kconfig.defconfig rename to boards/ezurio/bl5340_dvk/Kconfig.defconfig index 65c005ee286054..ece5d8d8d39608 100644 --- a/boards/lairdconnect/bl5340_dvk/Kconfig.defconfig +++ b/boards/ezurio/bl5340_dvk/Kconfig.defconfig @@ -57,9 +57,8 @@ config FLASH_LOAD_SIZE endif # BOARD_BL5340_DVK_NRF5340_CPUAPP_NS -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts similarity index 80% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts index 7640e86e4aad15..a1ef13d63e543c 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +10,8 @@ #include "bl5340_dvk_nrf5340_cpuapp_common.dtsi" / { - model = "Laird Connectivity BL5340 (nRF5340) Application"; - compatible = "lairdconnect,bl5340-dvk-cpuapp"; + model = "Ezurio BL5340 (nRF5340) Application"; + compatible = "ezurio,bl5340-dvk-cpuapp"; chosen { zephyr,sram = &sram0_image; diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml similarity index 92% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml index a4e91d78ab3f49..cf432d7ab6e24f 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml @@ -18,4 +18,4 @@ supported: - uart - usb_device - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common-pinctrl.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common-pinctrl.dtsi diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi similarity index 98% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi index ff29e1f176ea2e..372144f15b097b 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi @@ -15,7 +15,7 @@ zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; zephyr,display = &ili9340; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; }; /* Main LEDs and buttons are on an I2C TCA9538 GPIO port expander */ @@ -105,7 +105,6 @@ watchdog0 = &wdt0; accel0 = &lis3dh; bbram0 = &extrtc0; - spi-flash0 = &mx25r64; }; mipi_dbi { @@ -152,7 +151,7 @@ pinctrl-1 = <&i2c1_sleep>; pinctrl-names = "default", "sleep"; at24c256@50 { - compatible = "atmel,at24"; + compatible = "atmel,at24c256", "atmel,at24"; reg = <0x50>; size = <32768>; pagesize = <64>; diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_defconfig b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_defconfig similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_defconfig rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_defconfig diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts similarity index 76% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts index d159b8c4afe1b7..35410c51b70cb8 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +10,8 @@ #include "bl5340_dvk_nrf5340_cpuapp_common.dtsi" / { - model = "Laird Connectivity BL5340 (nRF5340) Application"; - compatible = "lairdconnect,bl5340-dvk-cpuapp"; + model = "Ezurio BL5340 (nRF5340) Application"; + compatible = "ezurio,bl5340-dvk-cpuapp"; chosen { zephyr,sram = &sram0_ns; diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml similarity index 92% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml index f9ad633de314b6..89d29c79e055e8 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml @@ -17,4 +17,4 @@ supported: - uart - usb_device - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns_defconfig b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns_defconfig similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns_defconfig rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns_defconfig diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet-pinctrl.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet-pinctrl.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet-pinctrl.dtsi diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts similarity index 86% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts index 4df761d04879ae..ef70281f16670b 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021-2023 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +11,8 @@ #include "bl5340_dvk_nrf5340_cpunet_common.dtsi" / { - model = "Laird Connectivity BL5340 (nRF5340) Network"; - compatible = "lairdconnect,bl5340-dvk-cpunet"; + model = "Ezurio BL5340 (nRF5340) Network"; + compatible = "ezurio,bl5340-dvk-cpunet"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml similarity index 91% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml index d9727296714594..ab6f60bdd3ab50 100644 --- a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml @@ -15,4 +15,4 @@ supported: - spi - uart - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_defconfig b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_defconfig similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_defconfig rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_defconfig diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_reset.c b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_reset.c similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_reset.c rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_reset.c diff --git a/boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi similarity index 100% rename from boards/lairdconnect/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi rename to boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi diff --git a/boards/lairdconnect/bl5340_dvk/board.cmake b/boards/ezurio/bl5340_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/bl5340_dvk/board.cmake rename to boards/ezurio/bl5340_dvk/board.cmake diff --git a/boards/lairdconnect/bl5340_dvk/board.yml b/boards/ezurio/bl5340_dvk/board.yml similarity index 82% rename from boards/lairdconnect/bl5340_dvk/board.yml rename to boards/ezurio/bl5340_dvk/board.yml index 71343692f4cb13..69be46ffe62ec0 100644 --- a/boards/lairdconnect/bl5340_dvk/board.yml +++ b/boards/ezurio/bl5340_dvk/board.yml @@ -1,6 +1,6 @@ board: name: bl5340_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: 'nrf5340' variants: diff --git a/boards/lairdconnect/bl5340_dvk/doc/img/bl5340_dvk_top.jpg b/boards/ezurio/bl5340_dvk/doc/img/bl5340_dvk_top.jpg similarity index 100% rename from boards/lairdconnect/bl5340_dvk/doc/img/bl5340_dvk_top.jpg rename to boards/ezurio/bl5340_dvk/doc/img/bl5340_dvk_top.jpg diff --git a/boards/lairdconnect/bl5340_dvk/doc/index.rst b/boards/ezurio/bl5340_dvk/doc/index.rst similarity index 97% rename from boards/lairdconnect/bl5340_dvk/doc/index.rst rename to boards/ezurio/bl5340_dvk/doc/index.rst index 4148b639a6d3a6..700838f0764ab3 100644 --- a/boards/lairdconnect/bl5340_dvk/doc/index.rst +++ b/boards/ezurio/bl5340_dvk/doc/index.rst @@ -1,11 +1,11 @@ .. _bl5340_dvk: -Laird Connectivity BL5340 DVK -############################# +Ezurio BL5340 DVK +################# Overview ******** -The BL5340 Development Kit provides support for the Laird Connectivity +The BL5340 Development Kit provides support for the Ezurio BL5340 module which is powered by a dual-core Nordic Semiconductor nRF5340 ARM Cortex-M33F CPU. The nRF5340 inside the BL5340 module is a dual-core SoC based on the Arm® Cortex®-M33 architecture, with: @@ -47,7 +47,7 @@ This development kit has the following features: :align: center :alt: BL5340 DVK - BL5340 DVK (Credit: Laird Connectivity) + BL5340 DVK (Credit: Ezurio) More information about the module can be found on the `BL5340 homepage`_. @@ -420,7 +420,7 @@ References .. _IDAU: https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau -.. _BL5340 homepage: https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl5340-series-multi-core-bluetooth-52-802154-nfc-modules +.. _BL5340 homepage: https://www.ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl5340-series-multi-core-bluetooth-52-802154-nfc-modules .. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com .. _TI TCA9538 datasheet: https://www.ti.com/lit/gpn/TCA9538 .. _Macronix MX25R6435FZNIL0 datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf diff --git a/boards/lairdconnect/bl5340_dvk/pre_dt_board.cmake b/boards/ezurio/bl5340_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl5340_dvk/pre_dt_board.cmake rename to boards/ezurio/bl5340_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/bl652_dvk/Kconfig b/boards/ezurio/bl652_dvk/Kconfig similarity index 100% rename from boards/lairdconnect/bl652_dvk/Kconfig rename to boards/ezurio/bl652_dvk/Kconfig diff --git a/boards/lairdconnect/bl652_dvk/Kconfig.bl652_dvk b/boards/ezurio/bl652_dvk/Kconfig.bl652_dvk similarity index 100% rename from boards/lairdconnect/bl652_dvk/Kconfig.bl652_dvk rename to boards/ezurio/bl652_dvk/Kconfig.bl652_dvk diff --git a/boards/lairdconnect/bl652_dvk/Kconfig.defconfig b/boards/ezurio/bl652_dvk/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bl652_dvk/Kconfig.defconfig rename to boards/ezurio/bl652_dvk/Kconfig.defconfig diff --git a/boards/lairdconnect/bl652_dvk/bl652_dvk-pinctrl.dtsi b/boards/ezurio/bl652_dvk/bl652_dvk-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl652_dvk/bl652_dvk-pinctrl.dtsi rename to boards/ezurio/bl652_dvk/bl652_dvk-pinctrl.dtsi diff --git a/boards/lairdconnect/bl652_dvk/bl652_dvk.dts b/boards/ezurio/bl652_dvk/bl652_dvk.dts similarity index 97% rename from boards/lairdconnect/bl652_dvk/bl652_dvk.dts rename to boards/ezurio/bl652_dvk/bl652_dvk.dts index f2cffbd819b96e..8a537a89796647 100644 --- a/boards/lairdconnect/bl652_dvk/bl652_dvk.dts +++ b/boards/ezurio/bl652_dvk/bl652_dvk.dts @@ -1,6 +1,7 @@ /* * Copyright (c) 2019 Laird Connectivity * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,8 +12,8 @@ #include / { - model = "Laird BL652 DVK"; - compatible = "lairdconnect,bl652_dvk"; + model = "Ezurio BL652 DVK"; + compatible = "ezurio,bl652_dvk"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bl652_dvk/bl652_dvk.yaml b/boards/ezurio/bl652_dvk/bl652_dvk.yaml similarity index 89% rename from boards/lairdconnect/bl652_dvk/bl652_dvk.yaml rename to boards/ezurio/bl652_dvk/bl652_dvk.yaml index a2fd4370d7f4bb..a549fcfdd66988 100644 --- a/boards/lairdconnect/bl652_dvk/bl652_dvk.yaml +++ b/boards/ezurio/bl652_dvk/bl652_dvk.yaml @@ -15,4 +15,4 @@ supported: - pwm - spi - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl652_dvk/bl652_dvk_defconfig b/boards/ezurio/bl652_dvk/bl652_dvk_defconfig similarity index 100% rename from boards/lairdconnect/bl652_dvk/bl652_dvk_defconfig rename to boards/ezurio/bl652_dvk/bl652_dvk_defconfig diff --git a/boards/lairdconnect/bl652_dvk/board.cmake b/boards/ezurio/bl652_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/bl652_dvk/board.cmake rename to boards/ezurio/bl652_dvk/board.cmake diff --git a/boards/lairdconnect/bl652_dvk/board.yml b/boards/ezurio/bl652_dvk/board.yml similarity index 69% rename from boards/lairdconnect/bl652_dvk/board.yml rename to boards/ezurio/bl652_dvk/board.yml index 2c2e672ec80aca..b573627457f802 100644 --- a/boards/lairdconnect/bl652_dvk/board.yml +++ b/boards/ezurio/bl652_dvk/board.yml @@ -1,5 +1,5 @@ board: name: bl652_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52832 diff --git a/boards/lairdconnect/bl652_dvk/doc/bl652_dvk.rst b/boards/ezurio/bl652_dvk/doc/bl652_dvk.rst similarity index 95% rename from boards/lairdconnect/bl652_dvk/doc/bl652_dvk.rst rename to boards/ezurio/bl652_dvk/doc/bl652_dvk.rst index 9acbb30d46ebcd..b6fffcc4aa78b3 100644 --- a/boards/lairdconnect/bl652_dvk/doc/bl652_dvk.rst +++ b/boards/ezurio/bl652_dvk/doc/bl652_dvk.rst @@ -1,13 +1,13 @@ .. _bl652_dvk: -Laird Connectivity BL652 DVK -############################ +Ezurio BL652 DVK +################ Overview ******** The BL652 Development Kit hardware provides -support for the Laird Connectivity BL652 module powered by a Nordic Semiconductor nRF52832 ARM Cortex-M4F CPU. +support for the Ezurio BL652 module powered by a Nordic Semiconductor nRF52832 ARM Cortex-M4F CPU. This development kit has the following features: @@ -260,11 +260,11 @@ the board are working properly with Zephyr: 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/lairdconnect/bl652_dvk/bl652_dvk.dts`. +:zephyr_file:`boards/ezurio/bl652_dvk/bl652_dvk.dts`. References ********** .. target-notes:: -.. _BL652 Module Website: https://connectivity.lairdtech.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl652-series-bluetooth-v5-nfc +.. _BL652 Module Website: https://ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl652-series-bluetooth-v5-nfc diff --git a/boards/lairdconnect/bl652_dvk/doc/img/BL652-SA_DVK_BoxContents.jpg b/boards/ezurio/bl652_dvk/doc/img/BL652-SA_DVK_BoxContents.jpg similarity index 100% rename from boards/lairdconnect/bl652_dvk/doc/img/BL652-SA_DVK_BoxContents.jpg rename to boards/ezurio/bl652_dvk/doc/img/BL652-SA_DVK_BoxContents.jpg diff --git a/boards/lairdconnect/bl652_dvk/doc/img/bl652_dvk.jpg b/boards/ezurio/bl652_dvk/doc/img/bl652_dvk.jpg similarity index 100% rename from boards/lairdconnect/bl652_dvk/doc/img/bl652_dvk.jpg rename to boards/ezurio/bl652_dvk/doc/img/bl652_dvk.jpg diff --git a/boards/lairdconnect/bl652_dvk/pre_dt_board.cmake b/boards/ezurio/bl652_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl652_dvk/pre_dt_board.cmake rename to boards/ezurio/bl652_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/bl653_dvk/Kconfig b/boards/ezurio/bl653_dvk/Kconfig similarity index 100% rename from boards/lairdconnect/bl653_dvk/Kconfig rename to boards/ezurio/bl653_dvk/Kconfig diff --git a/boards/lairdconnect/bl653_dvk/Kconfig.bl653_dvk b/boards/ezurio/bl653_dvk/Kconfig.bl653_dvk similarity index 100% rename from boards/lairdconnect/bl653_dvk/Kconfig.bl653_dvk rename to boards/ezurio/bl653_dvk/Kconfig.bl653_dvk diff --git a/boards/lairdconnect/bl653_dvk/Kconfig.defconfig b/boards/ezurio/bl653_dvk/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bl653_dvk/Kconfig.defconfig rename to boards/ezurio/bl653_dvk/Kconfig.defconfig diff --git a/boards/lairdconnect/bl653_dvk/bl653_dvk-pinctrl.dtsi b/boards/ezurio/bl653_dvk/bl653_dvk-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl653_dvk/bl653_dvk-pinctrl.dtsi rename to boards/ezurio/bl653_dvk/bl653_dvk-pinctrl.dtsi diff --git a/boards/lairdconnect/bl653_dvk/bl653_dvk.dts b/boards/ezurio/bl653_dvk/bl653_dvk.dts similarity index 97% rename from boards/lairdconnect/bl653_dvk/bl653_dvk.dts rename to boards/ezurio/bl653_dvk/bl653_dvk.dts index 4c536eb4512550..35de9a2a802780 100644 --- a/boards/lairdconnect/bl653_dvk/bl653_dvk.dts +++ b/boards/ezurio/bl653_dvk/bl653_dvk.dts @@ -1,6 +1,7 @@ /* * Copyright (c) 2020 Laird Connectivity * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,8 +12,8 @@ #include / { - model = "Laird BL653 Dev Kit"; - compatible = "lairdconnect,bl653_dvk"; + model = "Ezurio BL653 Dev Kit"; + compatible = "ezurio,bl653_dvk"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bl653_dvk/bl653_dvk.yaml b/boards/ezurio/bl653_dvk/bl653_dvk.yaml similarity index 90% rename from boards/lairdconnect/bl653_dvk/bl653_dvk.yaml rename to boards/ezurio/bl653_dvk/bl653_dvk.yaml index 6a2792ea5219db..ee1b610f312b9a 100644 --- a/boards/lairdconnect/bl653_dvk/bl653_dvk.yaml +++ b/boards/ezurio/bl653_dvk/bl653_dvk.yaml @@ -16,4 +16,4 @@ supported: - counter - spi - i2c -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl653_dvk/bl653_dvk_defconfig b/boards/ezurio/bl653_dvk/bl653_dvk_defconfig similarity index 100% rename from boards/lairdconnect/bl653_dvk/bl653_dvk_defconfig rename to boards/ezurio/bl653_dvk/bl653_dvk_defconfig diff --git a/boards/lairdconnect/bl653_dvk/board.cmake b/boards/ezurio/bl653_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/bl653_dvk/board.cmake rename to boards/ezurio/bl653_dvk/board.cmake diff --git a/boards/lairdconnect/bl653_dvk/board.yml b/boards/ezurio/bl653_dvk/board.yml similarity index 69% rename from boards/lairdconnect/bl653_dvk/board.yml rename to boards/ezurio/bl653_dvk/board.yml index c898247f1f3838..dc42555309a236 100644 --- a/boards/lairdconnect/bl653_dvk/board.yml +++ b/boards/ezurio/bl653_dvk/board.yml @@ -1,5 +1,5 @@ board: name: bl653_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52833 diff --git a/boards/lairdconnect/bl653_dvk/doc/bl653_dvk.rst b/boards/ezurio/bl653_dvk/doc/bl653_dvk.rst similarity index 94% rename from boards/lairdconnect/bl653_dvk/doc/bl653_dvk.rst rename to boards/ezurio/bl653_dvk/doc/bl653_dvk.rst index 71270f6f4e8509..ec8fdb0e02d8ca 100644 --- a/boards/lairdconnect/bl653_dvk/doc/bl653_dvk.rst +++ b/boards/ezurio/bl653_dvk/doc/bl653_dvk.rst @@ -1,13 +1,13 @@ .. _bl653_dvk: -Laird Connectivity BL653 DVK -############################ +Ezurio BL653 DVK +################ Overview ******** The BL653 Development Kit (453-00039-K1, 453-00041-K1) hardware provides -support for the Laird Connectivity BL653 module powered by a Nordic Semiconductor nRF52833 ARM Cortex-M4F CPU. +support for the Ezurio BL653 module powered by a Nordic Semiconductor nRF52833 ARM Cortex-M4F CPU. This development kit has the following features: @@ -167,7 +167,7 @@ the board are working properly with Zephyr: 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/lairdconnect/bl653_dvk/bl653_dvk.dts`. +:zephyr_file:`boards/ezurio/bl653_dvk/bl653_dvk.dts`. Using UART1 *********** @@ -225,5 +225,5 @@ References .. target-notes:: -.. _BL653 website: https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl653-series-bluetooth-51-802154-nfc-module +.. _BL653 website: https://www.ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl653-series-bluetooth-51-802154-nfc-module .. _nRF52833 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52833_OPS_v0.7.pdf diff --git a/boards/lairdconnect/bl653_dvk/doc/img/bl653_dvk.jpg b/boards/ezurio/bl653_dvk/doc/img/bl653_dvk.jpg similarity index 100% rename from boards/lairdconnect/bl653_dvk/doc/img/bl653_dvk.jpg rename to boards/ezurio/bl653_dvk/doc/img/bl653_dvk.jpg diff --git a/boards/lairdconnect/bl653_dvk/pre_dt_board.cmake b/boards/ezurio/bl653_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl653_dvk/pre_dt_board.cmake rename to boards/ezurio/bl653_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/bl654_dvk/Kconfig b/boards/ezurio/bl654_dvk/Kconfig similarity index 100% rename from boards/lairdconnect/bl654_dvk/Kconfig rename to boards/ezurio/bl654_dvk/Kconfig diff --git a/boards/lairdconnect/bl654_dvk/Kconfig.bl654_dvk b/boards/ezurio/bl654_dvk/Kconfig.bl654_dvk similarity index 100% rename from boards/lairdconnect/bl654_dvk/Kconfig.bl654_dvk rename to boards/ezurio/bl654_dvk/Kconfig.bl654_dvk diff --git a/boards/lairdconnect/bl654_dvk/Kconfig.defconfig b/boards/ezurio/bl654_dvk/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bl654_dvk/Kconfig.defconfig rename to boards/ezurio/bl654_dvk/Kconfig.defconfig diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk-pinctrl.dtsi b/boards/ezurio/bl654_dvk/bl654_dvk-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl654_dvk/bl654_dvk-pinctrl.dtsi rename to boards/ezurio/bl654_dvk/bl654_dvk-pinctrl.dtsi diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk.dts b/boards/ezurio/bl654_dvk/bl654_dvk.dts similarity index 97% rename from boards/lairdconnect/bl654_dvk/bl654_dvk.dts rename to boards/ezurio/bl654_dvk/bl654_dvk.dts index 7ede69427de75e..6e9848f03cd32a 100644 --- a/boards/lairdconnect/bl654_dvk/bl654_dvk.dts +++ b/boards/ezurio/bl654_dvk/bl654_dvk.dts @@ -1,6 +1,7 @@ /* * Copyright (c) 2019 Laird Connectivity * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,8 +12,8 @@ #include / { - model = "Laird BL654 Dev Kit"; - compatible = "lairdconnect,bl654_dvk"; + model = "Ezurio BL654 Dev Kit"; + compatible = "ezurio,bl654_dvk"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk.yaml b/boards/ezurio/bl654_dvk/bl654_dvk.yaml similarity index 88% rename from boards/lairdconnect/bl654_dvk/bl654_dvk.yaml rename to boards/ezurio/bl654_dvk/bl654_dvk.yaml index 27eec7dcaebac2..c4d016d63b6995 100644 --- a/boards/lairdconnect/bl654_dvk/bl654_dvk.yaml +++ b/boards/ezurio/bl654_dvk/bl654_dvk.yaml @@ -12,4 +12,4 @@ supported: - ble - pwm - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk_defconfig b/boards/ezurio/bl654_dvk/bl654_dvk_defconfig similarity index 100% rename from boards/lairdconnect/bl654_dvk/bl654_dvk_defconfig rename to boards/ezurio/bl654_dvk/bl654_dvk_defconfig diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa.dts b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.dts similarity index 100% rename from boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa.dts rename to boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.dts diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa.yaml b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml similarity index 90% rename from boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa.yaml rename to boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml index d02d93862843d1..6ecf919159136e 100644 --- a/boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa.yaml +++ b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml @@ -12,4 +12,4 @@ supported: - ble - pwm - watchdog -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa_defconfig b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa_defconfig similarity index 100% rename from boards/lairdconnect/bl654_dvk/bl654_dvk_nrf52840_pa_defconfig rename to boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa_defconfig diff --git a/boards/lairdconnect/bl654_dvk/board.cmake b/boards/ezurio/bl654_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/bl654_dvk/board.cmake rename to boards/ezurio/bl654_dvk/board.cmake diff --git a/boards/lairdconnect/bl654_dvk/board.yml b/boards/ezurio/bl654_dvk/board.yml similarity index 77% rename from boards/lairdconnect/bl654_dvk/board.yml rename to boards/ezurio/bl654_dvk/board.yml index 788824c7af1928..fdc9035ff68b0f 100644 --- a/boards/lairdconnect/bl654_dvk/board.yml +++ b/boards/ezurio/bl654_dvk/board.yml @@ -1,6 +1,6 @@ board: name: bl654_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 variants: diff --git a/boards/lairdconnect/bl654_dvk/doc/bl654_dvk.rst b/boards/ezurio/bl654_dvk/doc/bl654_dvk.rst similarity index 94% rename from boards/lairdconnect/bl654_dvk/doc/bl654_dvk.rst rename to boards/ezurio/bl654_dvk/doc/bl654_dvk.rst index 7ccb6294f4bc83..fba2bafba9cbb7 100644 --- a/boards/lairdconnect/bl654_dvk/doc/bl654_dvk.rst +++ b/boards/ezurio/bl654_dvk/doc/bl654_dvk.rst @@ -1,13 +1,13 @@ .. _bl654_dvk: -Laird Connectivity BL654 DVK -############################ +Ezurio BL654 DVK +################ Overview ******** The BL654 Development Kit hardware provides -support for the Laird Connectivity BL654 module powered by a Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU. +support for the Ezurio BL654 module powered by a Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU. It is also pin compatible with the BL654PA which adds a power amplifier. The "pa" variant provides this compatibility. Use board ``bl654_dvk/nrf52840/pa`` to build for that target. @@ -178,7 +178,7 @@ the board are working properly with Zephyr: 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/lairdconnect/bl654_dvk/bl654_dvk.dts`. +:zephyr_file:`boards/ezurio/bl654_dvk/bl654_dvk.dts`. References @@ -186,5 +186,5 @@ References .. target-notes:: -.. _BL654 website: https://connectivity.lairdtech.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series +.. _BL654 website: https://ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html diff --git a/boards/lairdconnect/bl654_dvk/doc/img/455-00001_BoxContents.jpg b/boards/ezurio/bl654_dvk/doc/img/455-00001_BoxContents.jpg similarity index 100% rename from boards/lairdconnect/bl654_dvk/doc/img/455-00001_BoxContents.jpg rename to boards/ezurio/bl654_dvk/doc/img/455-00001_BoxContents.jpg diff --git a/boards/lairdconnect/bl654_dvk/doc/img/bl654_dvk.jpg b/boards/ezurio/bl654_dvk/doc/img/bl654_dvk.jpg similarity index 100% rename from boards/lairdconnect/bl654_dvk/doc/img/bl654_dvk.jpg rename to boards/ezurio/bl654_dvk/doc/img/bl654_dvk.jpg diff --git a/boards/lairdconnect/bl654_dvk/pre_dt_board.cmake b/boards/ezurio/bl654_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl654_dvk/pre_dt_board.cmake rename to boards/ezurio/bl654_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/bl654_sensor_board/Kconfig b/boards/ezurio/bl654_sensor_board/Kconfig similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/Kconfig rename to boards/ezurio/bl654_sensor_board/Kconfig diff --git a/boards/lairdconnect/bl654_sensor_board/Kconfig.bl654_sensor_board b/boards/ezurio/bl654_sensor_board/Kconfig.bl654_sensor_board similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/Kconfig.bl654_sensor_board rename to boards/ezurio/bl654_sensor_board/Kconfig.bl654_sensor_board diff --git a/boards/lairdconnect/bl654_sensor_board/Kconfig.defconfig b/boards/ezurio/bl654_sensor_board/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/Kconfig.defconfig rename to boards/ezurio/bl654_sensor_board/Kconfig.defconfig diff --git a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board-pinctrl.dtsi b/boards/ezurio/bl654_sensor_board/bl654_sensor_board-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/bl654_sensor_board-pinctrl.dtsi rename to boards/ezurio/bl654_sensor_board/bl654_sensor_board-pinctrl.dtsi diff --git a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.dts b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.dts similarity index 95% rename from boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.dts rename to boards/ezurio/bl654_sensor_board/bl654_sensor_board.dts index c43354f2705f7b..8b5993d864dc8f 100644 --- a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.dts +++ b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +11,8 @@ #include / { - model = "Laird BL654 Sensor Board"; - compatible = "lairdconnect,bl654-sensor-board"; + model = "Ezurio BL654 Sensor Board"; + compatible = "ezurio,bl654-sensor-board"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.yaml b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml similarity index 92% rename from boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.yaml rename to boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml index 856805fbd16910..bcaafe5669ac5f 100644 --- a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board.yaml +++ b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml @@ -17,4 +17,4 @@ supported: - pwm - watchdog - netif:openthread -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl654_sensor_board/bl654_sensor_board_defconfig b/boards/ezurio/bl654_sensor_board/bl654_sensor_board_defconfig similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/bl654_sensor_board_defconfig rename to boards/ezurio/bl654_sensor_board/bl654_sensor_board_defconfig diff --git a/boards/lairdconnect/bl654_sensor_board/board.cmake b/boards/ezurio/bl654_sensor_board/board.cmake similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/board.cmake rename to boards/ezurio/bl654_sensor_board/board.cmake diff --git a/boards/lairdconnect/bl654_sensor_board/board.yml b/boards/ezurio/bl654_sensor_board/board.yml similarity index 72% rename from boards/lairdconnect/bl654_sensor_board/board.yml rename to boards/ezurio/bl654_sensor_board/board.yml index ebe40b44601f3a..566c992411db1b 100644 --- a/boards/lairdconnect/bl654_sensor_board/board.yml +++ b/boards/ezurio/bl654_sensor_board/board.yml @@ -1,5 +1,5 @@ board: name: bl654_sensor_board - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/bl654_sensor_board/doc/bl654_sensor_board.rst b/boards/ezurio/bl654_sensor_board/doc/bl654_sensor_board.rst similarity index 92% rename from boards/lairdconnect/bl654_sensor_board/doc/bl654_sensor_board.rst rename to boards/ezurio/bl654_sensor_board/doc/bl654_sensor_board.rst index c990c934952ea5..50eb94cf5b2668 100644 --- a/boards/lairdconnect/bl654_sensor_board/doc/bl654_sensor_board.rst +++ b/boards/ezurio/bl654_sensor_board/doc/bl654_sensor_board.rst @@ -1,12 +1,12 @@ .. _bl654_sensor_board: -Laird Connectivity BL654 Sensor Board -##################################### +Ezurio BL654 Sensor Board +######################### Overview ******** -The BL654 Sensor Board hardware provides support for the Laird Connectivity +The BL654 Sensor Board hardware provides support for the Ezurio BL654 module which is powered by a Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU. @@ -132,7 +132,7 @@ Applications for the ``bl654_sensor_board`` board configuration can be built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. An external debugger/programmer is required which can be connected to using a Tag-Connect -TC2030-CTX cable, a Laird Connectivity USB-SWD Programmer board or Segger JLink +TC2030-CTX cable, a Ezurio USB-SWD Programmer board or Segger JLink programmer can be used to program and debug the BL654 sensor board. Flashing @@ -142,14 +142,14 @@ If using an external JLink, 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). If using a Laird Connectivity USB-SWD Programmer Board, see the +details). If using a Ezurio USB-SWD Programmer Board, see the `pyOCD website`_ to find details about the software and how to install it. Here is an example for the :ref:`hello_world` application. First, run your favorite terminal program to listen for output - note that an external UART is required to be connected to the BL654 sensor board's UART, if -using the Laird Connectivity USB-SWD Programmer Board, the BL654 sensor board +using the Ezurio USB-SWD Programmer Board, the BL654 sensor board can be plugged in to the UART header. An FTDI cable can also be used - the voltage of the I/O lines and power line must be between 1.8v and 3.3v, do not connect an FTDI cable with a 5v power line to the BL654 sensor board. @@ -181,7 +181,7 @@ can be found. For example, under Linux, :code:`/dev/ttyACM0`. The BL654 sensor board needs an external programmer to program it, any SWD programmer which has a 9-pin ARM debug port can be used with a Tag-Connect -TC2030-CTX cable. If using the Laird Connectivity USB-SWD Programmer Board, +TC2030-CTX cable. If using the Ezurio USB-SWD Programmer Board, connect the cable to P1 and ensure the board is set to supply power to the target at 3.3v. @@ -214,7 +214,7 @@ Debugging ========= Refer to the :ref:`nordic_segger` page to learn about debugging Nordic based -boards if using an external JLink debugger. If using a Laird Connectivity +boards if using an external JLink debugger. If using a Ezurio USB-SWD Programmer Board, pyOCD can be used for debugging. Testing Bluetooth on the BL654 Sensor Board @@ -238,7 +238,7 @@ the board are working properly with Zephyr: 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/lairdconnect/bl654_sensor_board/bl654_sensor_board.dts`. +:zephyr_file:`boards/ezurio/bl654_sensor_board/bl654_sensor_board.dts`. References @@ -247,6 +247,6 @@ References .. target-notes:: .. _Bosch BME280 sensor website: https://www.bosch-sensortec.com/products/environmental-sensors/humidity-sensors-bme280/ -.. _BL654 website: https://connectivity.lairdtech.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series +.. _BL654 website: https://ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series .. _pyOCD website: https://github.com/pyocd/pyOCD -.. _USB-SWD Programmer website: https://www.lairdconnect.com/usb-swd-programmer +.. _USB-SWD Programmer website: https://www.ezurio.com/usb-swd-programmer diff --git a/boards/lairdconnect/bl654_sensor_board/doc/img/bl654_sensor_board.jpg b/boards/ezurio/bl654_sensor_board/doc/img/bl654_sensor_board.jpg similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/doc/img/bl654_sensor_board.jpg rename to boards/ezurio/bl654_sensor_board/doc/img/bl654_sensor_board.jpg diff --git a/boards/lairdconnect/bl654_sensor_board/doc/img/bl654_sensor_board_usb_swd_programmer.jpg b/boards/ezurio/bl654_sensor_board/doc/img/bl654_sensor_board_usb_swd_programmer.jpg similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/doc/img/bl654_sensor_board_usb_swd_programmer.jpg rename to boards/ezurio/bl654_sensor_board/doc/img/bl654_sensor_board_usb_swd_programmer.jpg diff --git a/boards/lairdconnect/bl654_sensor_board/pre_dt_board.cmake b/boards/ezurio/bl654_sensor_board/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl654_sensor_board/pre_dt_board.cmake rename to boards/ezurio/bl654_sensor_board/pre_dt_board.cmake diff --git a/boards/lairdconnect/bl654_usb/Kconfig b/boards/ezurio/bl654_usb/Kconfig similarity index 100% rename from boards/lairdconnect/bl654_usb/Kconfig rename to boards/ezurio/bl654_usb/Kconfig diff --git a/boards/lairdconnect/bl654_usb/Kconfig.bl654_usb b/boards/ezurio/bl654_usb/Kconfig.bl654_usb similarity index 100% rename from boards/lairdconnect/bl654_usb/Kconfig.bl654_usb rename to boards/ezurio/bl654_usb/Kconfig.bl654_usb diff --git a/boards/lairdconnect/bl654_usb/Kconfig.defconfig b/boards/ezurio/bl654_usb/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bl654_usb/Kconfig.defconfig rename to boards/ezurio/bl654_usb/Kconfig.defconfig diff --git a/boards/lairdconnect/bl654_usb/bl654_usb-pinctrl.dtsi b/boards/ezurio/bl654_usb/bl654_usb-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bl654_usb/bl654_usb-pinctrl.dtsi rename to boards/ezurio/bl654_usb/bl654_usb-pinctrl.dtsi diff --git a/boards/lairdconnect/bl654_usb/bl654_usb.dts b/boards/ezurio/bl654_usb/bl654_usb.dts similarity index 95% rename from boards/lairdconnect/bl654_usb/bl654_usb.dts rename to boards/ezurio/bl654_usb/bl654_usb.dts index fa814f4b80e421..8cde4ae008f983 100644 --- a/boards/lairdconnect/bl654_usb/bl654_usb.dts +++ b/boards/ezurio/bl654_usb/bl654_usb.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +10,8 @@ #include "bl654_usb-pinctrl.dtsi" / { - model = "Laird Connectivity BL654 USB adapter"; - compatible = "lairdconnect,bl654_usb"; + model = "Ezurio BL654 USB adapter"; + compatible = "ezurio,bl654_usb"; chosen { zephyr,sram = &sram0; diff --git a/boards/lairdconnect/bl654_usb/bl654_usb.yaml b/boards/ezurio/bl654_usb/bl654_usb.yaml similarity index 89% rename from boards/lairdconnect/bl654_usb/bl654_usb.yaml rename to boards/ezurio/bl654_usb/bl654_usb.yaml index d927657dc7da7d..4bf396760cc641 100644 --- a/boards/lairdconnect/bl654_usb/bl654_usb.yaml +++ b/boards/ezurio/bl654_usb/bl654_usb.yaml @@ -12,4 +12,4 @@ supported: - pwm - watchdog - counter -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bl654_usb/bl654_usb_defconfig b/boards/ezurio/bl654_usb/bl654_usb_defconfig similarity index 100% rename from boards/lairdconnect/bl654_usb/bl654_usb_defconfig rename to boards/ezurio/bl654_usb/bl654_usb_defconfig diff --git a/boards/lairdconnect/bl654_usb/board.yml b/boards/ezurio/bl654_usb/board.yml similarity index 69% rename from boards/lairdconnect/bl654_usb/board.yml rename to boards/ezurio/bl654_usb/board.yml index dc616554605c4a..13642fbe7124d4 100644 --- a/boards/lairdconnect/bl654_usb/board.yml +++ b/boards/ezurio/bl654_usb/board.yml @@ -1,5 +1,5 @@ board: name: bl654_usb - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/bl654_usb/doc/bl654_usb.rst b/boards/ezurio/bl654_usb/doc/bl654_usb.rst similarity index 86% rename from boards/lairdconnect/bl654_usb/doc/bl654_usb.rst rename to boards/ezurio/bl654_usb/doc/bl654_usb.rst index 3bb3139b61564a..34a64c14aec47d 100644 --- a/boards/lairdconnect/bl654_usb/doc/bl654_usb.rst +++ b/boards/ezurio/bl654_usb/doc/bl654_usb.rst @@ -1,13 +1,13 @@ .. _bl654_usb: -Laird Connectivity BL654 USB (451-00004) -######################################## +Ezurio BL654 USB (451-00004) +############################ Overview ******** -The BL654 USB adapter hardware (Laird Connectivity part 451-00004) provides -support for the Laird Connectivity BL654 module powered by a Nordic +The BL654 USB adapter hardware (Ezurio part 451-00004) provides +support for the Ezurio BL654 module powered by a Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU. This USB adapter has the following features: @@ -105,14 +105,14 @@ Applications for the ``bl654_usb`` board configuration can be built in the usual way (see :ref:`build_an_application` for more details). The ``bl654_usb`` board cannot be used for debugging. The compatible BL654 DVK board can be used for development. Documentation can be found at the :ref:`bl654_dvk` -site and :zephyr_file:`boards/lairdconnect/bl654_dvk/doc/bl654_dvk.rst` +site and :zephyr_file:`boards/ezurio/bl654_dvk/doc/bl654_dvk.rst` Flashing ======== The board supports programming using the built-in bootloader. -The board is factory-programmed with a Laird Connectivity variation of Nordic's +The board is factory-programmed with a Ezurio variation of Nordic's open bootloader from Nordic's nRF5x SDK. With this option, you'll use Nordic's `nrfutil`_ program to create firmware packages supported by this bootloader and flash them to the device. Make sure ``nrfutil`` is installed @@ -175,7 +175,7 @@ the board is working properly with Zephyr: You can build and flash the example to make sure Zephyr is running correctly on your board. The LED definitions can be found in -:zephyr_file:`boards/lairdconnect/bl654_usb/bl654_usb.dts`. +:zephyr_file:`boards/ezurio/bl654_usb/bl654_usb.dts`. References @@ -183,8 +183,8 @@ References .. target-notes:: -.. _BL654 USB Dongle Quick Start Guide: https://www.lairdconnect.com/documentation/user-guide-bl654-usb-nordic-sdk-zephyr -.. _BL654 website: https://connectivity.lairdtech.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series +.. _BL654 USB Dongle Quick Start Guide: https://www.ezurio.com/documentation/user-guide-bl654-usb-nordic-sdk-zephyr +.. _BL654 website: https://ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl654-series .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _Creating a secure bootloader image: https://www.lairdconnect.com/documentation/application-note-creating-secure-bootloader-image-bl654-usb +.. _Creating a secure bootloader image: https://www.ezurio.com/documentation/application-note-creating-secure-bootloader-image-bl654-usb .. _nrfutil: https://github.com/NordicSemiconductor/pc-nrfutil diff --git a/boards/lairdconnect/bl654_usb/doc/img/bl654_usb.jpg b/boards/ezurio/bl654_usb/doc/img/bl654_usb.jpg similarity index 100% rename from boards/lairdconnect/bl654_usb/doc/img/bl654_usb.jpg rename to boards/ezurio/bl654_usb/doc/img/bl654_usb.jpg diff --git a/boards/lairdconnect/bl654_usb/doc/img/bl654_usb_pcb.jpg b/boards/ezurio/bl654_usb/doc/img/bl654_usb_pcb.jpg similarity index 100% rename from boards/lairdconnect/bl654_usb/doc/img/bl654_usb_pcb.jpg rename to boards/ezurio/bl654_usb/doc/img/bl654_usb_pcb.jpg diff --git a/boards/lairdconnect/bl654_usb/doc/img/bl654_usb_reset.jpg b/boards/ezurio/bl654_usb/doc/img/bl654_usb_reset.jpg similarity index 100% rename from boards/lairdconnect/bl654_usb/doc/img/bl654_usb_reset.jpg rename to boards/ezurio/bl654_usb/doc/img/bl654_usb_reset.jpg diff --git a/boards/lairdconnect/bl654_usb/pre_dt_board.cmake b/boards/ezurio/bl654_usb/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bl654_usb/pre_dt_board.cmake rename to boards/ezurio/bl654_usb/pre_dt_board.cmake diff --git a/boards/lairdconnect/bt510/Kconfig b/boards/ezurio/bt510/Kconfig similarity index 100% rename from boards/lairdconnect/bt510/Kconfig rename to boards/ezurio/bt510/Kconfig diff --git a/boards/lairdconnect/bt510/Kconfig.bt510 b/boards/ezurio/bt510/Kconfig.bt510 similarity index 100% rename from boards/lairdconnect/bt510/Kconfig.bt510 rename to boards/ezurio/bt510/Kconfig.bt510 diff --git a/boards/lairdconnect/bt510/Kconfig.defconfig b/boards/ezurio/bt510/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bt510/Kconfig.defconfig rename to boards/ezurio/bt510/Kconfig.defconfig diff --git a/boards/lairdconnect/bt510/board.cmake b/boards/ezurio/bt510/board.cmake similarity index 100% rename from boards/lairdconnect/bt510/board.cmake rename to boards/ezurio/bt510/board.cmake diff --git a/boards/lairdconnect/bt510/board.yml b/boards/ezurio/bt510/board.yml similarity index 67% rename from boards/lairdconnect/bt510/board.yml rename to boards/ezurio/bt510/board.yml index 1a9760895ecf19..e4692ed4526735 100644 --- a/boards/lairdconnect/bt510/board.yml +++ b/boards/ezurio/bt510/board.yml @@ -1,5 +1,5 @@ board: name: bt510 - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/bt510/bt510-pinctrl.dtsi b/boards/ezurio/bt510/bt510-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bt510/bt510-pinctrl.dtsi rename to boards/ezurio/bt510/bt510-pinctrl.dtsi diff --git a/boards/lairdconnect/bt510/bt510.dts b/boards/ezurio/bt510/bt510.dts similarity index 96% rename from boards/lairdconnect/bt510/bt510.dts rename to boards/ezurio/bt510/bt510.dts index 984b098e5d53dc..adc8337862c08d 100644 --- a/boards/lairdconnect/bt510/bt510.dts +++ b/boards/ezurio/bt510/bt510.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +11,8 @@ #include / { - model = "Laird Sentrius BT510 Sensor"; - compatible = "lairdconnect,bt510"; + model = "Ezurio Sentrius BT510 Sensor"; + compatible = "ezurio,bt510"; chosen { zephyr,console = &uart0; diff --git a/boards/lairdconnect/bt510/bt510.yaml b/boards/ezurio/bt510/bt510.yaml similarity index 88% rename from boards/lairdconnect/bt510/bt510.yaml rename to boards/ezurio/bt510/bt510.yaml index c9b6823d188156..198b538eecd449 100644 --- a/boards/lairdconnect/bt510/bt510.yaml +++ b/boards/ezurio/bt510/bt510.yaml @@ -13,4 +13,4 @@ supported: - watchdog - i2c - sm351lt -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bt510/bt510_defconfig b/boards/ezurio/bt510/bt510_defconfig similarity index 100% rename from boards/lairdconnect/bt510/bt510_defconfig rename to boards/ezurio/bt510/bt510_defconfig diff --git a/boards/lairdconnect/bt510/doc/bt510.rst b/boards/ezurio/bt510/doc/bt510.rst similarity index 94% rename from boards/lairdconnect/bt510/doc/bt510.rst rename to boards/ezurio/bt510/doc/bt510.rst index 13459f69ea7222..2d0dbcbf5069bb 100644 --- a/boards/lairdconnect/bt510/doc/bt510.rst +++ b/boards/ezurio/bt510/doc/bt510.rst @@ -1,7 +1,7 @@ .. _bt510: -Laird Connectivity Sentrius BT510 Sensor -######################################## +Ezurio Sentrius BT510 Sensor +############################ Overview ******** @@ -162,7 +162,7 @@ A non-standard layout is used to include access to the sensor debug UART. Connectivity to the programmer/debugger must be modified to match the pinout shown above. -Laird Connectivity provide the USB-SWD programming board (750-03239) that supports +Ezurio provide the USB-SWD programming board (750-03239) that supports this connector layout, refer to the `USB SWD Programmer product page`_ . @@ -244,7 +244,7 @@ the board are working properly with Zephyr: You can build and flash the examples to make sure Zephyr is running correctly on your board. The button, LED and sensor device definitions can be found in -:zephyr_file:`boards/lairdconnect/bt510/bt510.dts`. +:zephyr_file:`boards/ezurio/bt510/bt510.dts`. References @@ -252,9 +252,9 @@ References .. target-notes:: -.. _Sentrius BT510 website: https://www.lairdconnect.com/iot-devices/iot-sensors/bt510-bluetooth-5-long-range-ip67-multi-sensor +.. _Sentrius BT510 website: https://www.ezurio.com/iot-devices/iot-sensors/bt510-bluetooth-5-long-range-ip67-multi-sensor .. _TagConnect TC2050 product page: https://www.tag-connect.com/product/tc2050-idc-050 -.. _USB SWD Programmer product page: https://www.lairdconnect.com/wireless-modules/programming-kits/usb-swd-programming-kit +.. _USB SWD Programmer product page: https://www.ezurio.com/wireless-modules/programming-kits/usb-swd-programming-kit .. _MAX3232 datasheet: https://www.ti.com/lit/ds/symlink/max3232.pdf .. _Silabs 7055 datasheet: https://www.silabs.com/documents/public/data-sheets/Si7050-1-3-4-5-A20.pdf .. _ST Microelectronics LIS2DH datasheet: https://www.st.com/resource/en/datasheet/lis2dh.pdf diff --git a/boards/lairdconnect/bt510/doc/img/bt510.jpg b/boards/ezurio/bt510/doc/img/bt510.jpg similarity index 100% rename from boards/lairdconnect/bt510/doc/img/bt510.jpg rename to boards/ezurio/bt510/doc/img/bt510.jpg diff --git a/boards/lairdconnect/bt510/doc/img/bt510_back.jpg b/boards/ezurio/bt510/doc/img/bt510_back.jpg similarity index 100% rename from boards/lairdconnect/bt510/doc/img/bt510_back.jpg rename to boards/ezurio/bt510/doc/img/bt510_back.jpg diff --git a/boards/lairdconnect/bt510/doc/img/bt510_prog.jpg b/boards/ezurio/bt510/doc/img/bt510_prog.jpg similarity index 100% rename from boards/lairdconnect/bt510/doc/img/bt510_prog.jpg rename to boards/ezurio/bt510/doc/img/bt510_prog.jpg diff --git a/boards/lairdconnect/bt510/pre_dt_board.cmake b/boards/ezurio/bt510/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bt510/pre_dt_board.cmake rename to boards/ezurio/bt510/pre_dt_board.cmake diff --git a/boards/lairdconnect/bt610/Kconfig b/boards/ezurio/bt610/Kconfig similarity index 100% rename from boards/lairdconnect/bt610/Kconfig rename to boards/ezurio/bt610/Kconfig diff --git a/boards/lairdconnect/bt610/Kconfig.bt610 b/boards/ezurio/bt610/Kconfig.bt610 similarity index 100% rename from boards/lairdconnect/bt610/Kconfig.bt610 rename to boards/ezurio/bt610/Kconfig.bt610 diff --git a/boards/lairdconnect/bt610/Kconfig.defconfig b/boards/ezurio/bt610/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/bt610/Kconfig.defconfig rename to boards/ezurio/bt610/Kconfig.defconfig diff --git a/boards/lairdconnect/bt610/board.cmake b/boards/ezurio/bt610/board.cmake similarity index 100% rename from boards/lairdconnect/bt610/board.cmake rename to boards/ezurio/bt610/board.cmake diff --git a/boards/lairdconnect/bt610/board.yml b/boards/ezurio/bt610/board.yml similarity index 67% rename from boards/lairdconnect/bt610/board.yml rename to boards/ezurio/bt610/board.yml index c5a846a0d8d4ae..0e4f29742c5d4f 100644 --- a/boards/lairdconnect/bt610/board.yml +++ b/boards/ezurio/bt610/board.yml @@ -1,5 +1,5 @@ board: name: bt610 - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/bt610/bt610-pinctrl.dtsi b/boards/ezurio/bt610/bt610-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/bt610/bt610-pinctrl.dtsi rename to boards/ezurio/bt610/bt610-pinctrl.dtsi diff --git a/boards/lairdconnect/bt610/bt610.dts b/boards/ezurio/bt610/bt610.dts similarity index 98% rename from boards/lairdconnect/bt610/bt610.dts rename to boards/ezurio/bt610/bt610.dts index c6b9bad9910ac8..9570f499d54638 100644 --- a/boards/lairdconnect/bt610/bt610.dts +++ b/boards/ezurio/bt610/bt610.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +11,8 @@ #include / { - model = "Laird BT610 Sensor"; - compatible = "lairdconnect,bt610"; + model = "Ezurio BT610 Sensor"; + compatible = "ezurio,bt610"; chosen { zephyr,console = &uart0; @@ -77,7 +78,6 @@ mcuboot-button0 = &button1; mcuboot-led0 = &led1; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; mag1: mag_1 { diff --git a/boards/lairdconnect/bt610/bt610.yaml b/boards/ezurio/bt610/bt610.yaml similarity index 91% rename from boards/lairdconnect/bt610/bt610.yaml rename to boards/ezurio/bt610/bt610.yaml index 80cbe9975da151..5b96d98c5275e2 100644 --- a/boards/lairdconnect/bt610/bt610.yaml +++ b/boards/ezurio/bt610/bt610.yaml @@ -19,4 +19,4 @@ supported: - counter - sm351lt - qspi -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/bt610/bt610_defconfig b/boards/ezurio/bt610/bt610_defconfig similarity index 100% rename from boards/lairdconnect/bt610/bt610_defconfig rename to boards/ezurio/bt610/bt610_defconfig diff --git a/boards/lairdconnect/bt610/doc/bt610.rst b/boards/ezurio/bt610/doc/bt610.rst similarity index 98% rename from boards/lairdconnect/bt610/doc/bt610.rst rename to boards/ezurio/bt610/doc/bt610.rst index baf9827e3d62d0..20527ceb1e08a5 100644 --- a/boards/lairdconnect/bt610/doc/bt610.rst +++ b/boards/ezurio/bt610/doc/bt610.rst @@ -1,7 +1,7 @@ .. _bt610: -Laird Connectivity Sentrius BT610 Sensor -######################################## +Ezurio Sentrius BT610 Sensor +############################ Overview ******** @@ -598,7 +598,7 @@ on the board are working properly with Zephyr: You can build and flash the examples to make sure Zephyr is running correctly on your board. The button, LED and sensor device definitions can be found in -:zephyr_file:`boards/lairdconnect/bt610/bt610.dts`. +:zephyr_file:`boards/ezurio/bt610/bt610.dts`. References @@ -606,10 +606,10 @@ References .. target-notes:: -.. _Sentrius BT610 website: https://www.lairdconnect.com/iot-devices/iot-sensors/sentrius-bt610-io-sensor +.. _Sentrius BT610 website: https://www.ezurio.com/iot-devices/iot-sensors/sentrius-bt610-io-sensor .. _Honeywell SM351LT datasheet: https://sensing.honeywell.com/honeywell-sensing-nanopower-series-datasheet-50095501-c-en.pdf .. _MAX3232 datasheet: https://www.ti.com/lit/ds/symlink/max3232.pdf .. _TI TMUX1204 datasheet: https://www.ti.com/lit/gpn/TMUX1204 .. _TI TCA9538 datasheet: https://www.ti.com/lit/gpn/TCA9538 .. _Macronix MX25R6435FZNIL0 datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/7913/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.5.pdf -.. _BT610 Zephyr Application Thermistor Calibration: https://www.lairdconnect.com/technology/bt610-thermistor-coefficient-calculator +.. _BT610 Zephyr Application Thermistor Calibration: https://www.ezurio.com/technology/bt610-thermistor-coefficient-calculator diff --git a/boards/lairdconnect/bt610/doc/img/bt610_back.jpg b/boards/ezurio/bt610/doc/img/bt610_back.jpg similarity index 100% rename from boards/lairdconnect/bt610/doc/img/bt610_back.jpg rename to boards/ezurio/bt610/doc/img/bt610_back.jpg diff --git a/boards/lairdconnect/bt610/doc/img/bt610_board.jpg b/boards/ezurio/bt610/doc/img/bt610_board.jpg similarity index 100% rename from boards/lairdconnect/bt610/doc/img/bt610_board.jpg rename to boards/ezurio/bt610/doc/img/bt610_board.jpg diff --git a/boards/lairdconnect/bt610/doc/img/bt610_front.jpg b/boards/ezurio/bt610/doc/img/bt610_front.jpg similarity index 100% rename from boards/lairdconnect/bt610/doc/img/bt610_front.jpg rename to boards/ezurio/bt610/doc/img/bt610_front.jpg diff --git a/boards/lairdconnect/bt610/pre_dt_board.cmake b/boards/ezurio/bt610/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/bt610/pre_dt_board.cmake rename to boards/ezurio/bt610/pre_dt_board.cmake diff --git a/boards/lairdconnect/index.rst b/boards/ezurio/index.rst similarity index 61% rename from boards/lairdconnect/index.rst rename to boards/ezurio/index.rst index 5c3a6d6621a2a9..5352513a1f378c 100644 --- a/boards/lairdconnect/index.rst +++ b/boards/ezurio/index.rst @@ -1,6 +1,6 @@ -.. _boards-lairdconnect: +.. _boards-ezurio: -Laird Connectivity +Ezurio ################## .. toctree:: diff --git a/boards/lairdconnect/mg100/Kconfig b/boards/ezurio/mg100/Kconfig similarity index 100% rename from boards/lairdconnect/mg100/Kconfig rename to boards/ezurio/mg100/Kconfig diff --git a/boards/lairdconnect/mg100/Kconfig.defconfig b/boards/ezurio/mg100/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/mg100/Kconfig.defconfig rename to boards/ezurio/mg100/Kconfig.defconfig diff --git a/boards/lairdconnect/mg100/Kconfig.mg100 b/boards/ezurio/mg100/Kconfig.mg100 similarity index 100% rename from boards/lairdconnect/mg100/Kconfig.mg100 rename to boards/ezurio/mg100/Kconfig.mg100 diff --git a/boards/lairdconnect/mg100/board.cmake b/boards/ezurio/mg100/board.cmake similarity index 100% rename from boards/lairdconnect/mg100/board.cmake rename to boards/ezurio/mg100/board.cmake diff --git a/boards/lairdconnect/mg100/board.yml b/boards/ezurio/mg100/board.yml similarity index 67% rename from boards/lairdconnect/mg100/board.yml rename to boards/ezurio/mg100/board.yml index 25a3ace314f714..4c62320fc5eb7e 100644 --- a/boards/lairdconnect/mg100/board.yml +++ b/boards/ezurio/mg100/board.yml @@ -1,5 +1,5 @@ board: name: mg100 - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/mg100/doc/img/mg100.jpg b/boards/ezurio/mg100/doc/img/mg100.jpg similarity index 100% rename from boards/lairdconnect/mg100/doc/img/mg100.jpg rename to boards/ezurio/mg100/doc/img/mg100.jpg diff --git a/boards/lairdconnect/mg100/doc/index.rst b/boards/ezurio/mg100/doc/index.rst similarity index 90% rename from boards/lairdconnect/mg100/doc/index.rst rename to boards/ezurio/mg100/doc/index.rst index 611f0db54658a0..b665997a762ca3 100644 --- a/boards/lairdconnect/mg100/doc/index.rst +++ b/boards/ezurio/mg100/doc/index.rst @@ -1,7 +1,7 @@ .. _mg100: -Laird Connectivity Sentrius™ MG100 Gateway -########################################## +Ezurio Sentrius™ MG100 Gateway +############################## Overview ******** @@ -17,7 +17,7 @@ and network certifications and End Device carrier approvals. Develop your application directly on the integrated Cortex M4F microcontroller using Zephyr RTOS, enabling your application development with a secure, open source RTOS with more than just kernel services. Remotely debug your fleet of devices with the `Memfault Platform`_. Take advantage of the -Zephyr community and Laird Connectivity’s multi featured Out of Box (OOB) sample source code +Zephyr community and Ezurio’s `Canvas Software Suite`_ to accelerate your development. covering all aspects of the product's capabilities and hardware interfaces. The MG100 also delivers complete antenna flexibility with internal or external antenna options available, and the optional battery backup provides uninterrupted reporting of remote Bluetooth sensor data. @@ -162,7 +162,7 @@ Applications for the ``mg100`` board configuration can be built and flashed in the usual way. (see :ref:`build_an_application` and :ref:`application_run` for more details) -The `Laird Connectivity USB-SWD Programming Kit`_ contains all the necessary +The `Ezurio USB-SWD Programming Kit`_ contains all the necessary hardware to enable programming and debugging an MG100. Flashing @@ -204,10 +204,9 @@ Segger IC. Software ******** -MG100 Out-of-Box Demo Software +Canvas Software Suite ============================== -The MG100 ships with an out of the box software demo. -Check out the `BLE Gateway OOB Demo`_ source code and documentation. +The MG100 is a supported hardware platform for `Canvas Software Suite`_. Testing Bluetooth on the MG100 ============================== @@ -231,19 +230,19 @@ the board are working properly with Zephyr: 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/lairdconnect/mg100/mg100.dts`. +:zephyr_file:`boards/ezurio/mg100/mg100.dts`. References ********** .. target-notes:: -.. _MG100 website: https://www.lairdconnect.com/iot-devices/iot-gateways/sentrius-mg100-gateway-lte-mnb-iot-and-bluetooth-5 +.. _MG100 website: https://www.ezurio.com/iot-devices/iot-gateways/sentrius-mg100-gateway-lte-mnb-iot-and-bluetooth-5 .. _nRF52840 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.1.pdf .. _Sierra Wireless HL7800: https://source.sierrawireless.com/devices/hl-series/hl7800/#sthash.641qTTwA.dpbs .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _BLE Gateway OOB Demo: https://github.com/LairdCP/Pinnacle-100-Firmware-Manifest .. _Macronix MX25R6435F datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/7913/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.5.pdf -.. _Laird Connectivity USB-SWD Programming Kit: https://www.lairdconnect.com/wireless-modules/programming-kits/usb-swd-programming-kit +.. _Ezurio USB-SWD Programming Kit: https://www.ezurio.com/wireless-modules/programming-kits/usb-swd-programming-kit .. _Memfault Platform: https://docs.memfault.com/docs/mcu/pinnacle-100-guide .. _nRF52840: https://www.nordicsemi.com/products/nrf52840 +.. _Canvas Software Suite: https://www.ezurio.com/canvas/software-suite diff --git a/boards/lairdconnect/mg100/mg100-pinctrl.dtsi b/boards/ezurio/mg100/mg100-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/mg100/mg100-pinctrl.dtsi rename to boards/ezurio/mg100/mg100-pinctrl.dtsi diff --git a/boards/lairdconnect/mg100/mg100.dts b/boards/ezurio/mg100/mg100.dts similarity index 98% rename from boards/lairdconnect/mg100/mg100.dts rename to boards/ezurio/mg100/mg100.dts index 7c6fbb92d246a5..a9b782eb67ceeb 100644 --- a/boards/lairdconnect/mg100/mg100.dts +++ b/boards/ezurio/mg100/mg100.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +12,7 @@ / { model = "MG100"; - compatible = "lairdconnect,mg100"; + compatible = "ezurio,mg100"; chosen { zephyr,console = &uart0; @@ -65,7 +66,6 @@ mcuboot-button0 = &button1; mcuboot-led0 = &led1; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/lairdconnect/mg100/mg100.yaml b/boards/ezurio/mg100/mg100.yaml similarity index 91% rename from boards/lairdconnect/mg100/mg100.yaml rename to boards/ezurio/mg100/mg100.yaml index 917eb7f0d86006..54de18e63ee291 100644 --- a/boards/lairdconnect/mg100/mg100.yaml +++ b/boards/ezurio/mg100/mg100.yaml @@ -18,4 +18,4 @@ supported: - spi - watchdog - netif:modem -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/mg100/mg100_defconfig b/boards/ezurio/mg100/mg100_defconfig similarity index 100% rename from boards/lairdconnect/mg100/mg100_defconfig rename to boards/ezurio/mg100/mg100_defconfig diff --git a/boards/lairdconnect/mg100/pre_dt_board.cmake b/boards/ezurio/mg100/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/mg100/pre_dt_board.cmake rename to boards/ezurio/mg100/pre_dt_board.cmake diff --git a/boards/lairdconnect/pinnacle_100_dvk/Kconfig b/boards/ezurio/pinnacle_100_dvk/Kconfig similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/Kconfig rename to boards/ezurio/pinnacle_100_dvk/Kconfig diff --git a/boards/lairdconnect/pinnacle_100_dvk/Kconfig.defconfig b/boards/ezurio/pinnacle_100_dvk/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/Kconfig.defconfig rename to boards/ezurio/pinnacle_100_dvk/Kconfig.defconfig diff --git a/boards/lairdconnect/pinnacle_100_dvk/Kconfig.pinnacle_100_dvk b/boards/ezurio/pinnacle_100_dvk/Kconfig.pinnacle_100_dvk similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/Kconfig.pinnacle_100_dvk rename to boards/ezurio/pinnacle_100_dvk/Kconfig.pinnacle_100_dvk diff --git a/boards/lairdconnect/pinnacle_100_dvk/board.cmake b/boards/ezurio/pinnacle_100_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/board.cmake rename to boards/ezurio/pinnacle_100_dvk/board.cmake diff --git a/boards/lairdconnect/pinnacle_100_dvk/board.yml b/boards/ezurio/pinnacle_100_dvk/board.yml similarity index 71% rename from boards/lairdconnect/pinnacle_100_dvk/board.yml rename to boards/ezurio/pinnacle_100_dvk/board.yml index 1741e687ace1ba..8ed639a9a0a211 100644 --- a/boards/lairdconnect/pinnacle_100_dvk/board.yml +++ b/boards/ezurio/pinnacle_100_dvk/board.yml @@ -1,5 +1,5 @@ board: name: pinnacle_100_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: nrf52840 diff --git a/boards/lairdconnect/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg b/boards/ezurio/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg rename to boards/ezurio/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg diff --git a/boards/lairdconnect/pinnacle_100_dvk/doc/index.rst b/boards/ezurio/pinnacle_100_dvk/doc/index.rst similarity index 91% rename from boards/lairdconnect/pinnacle_100_dvk/doc/index.rst rename to boards/ezurio/pinnacle_100_dvk/doc/index.rst index 6feaa13833d460..9650d0c8e25ea6 100644 --- a/boards/lairdconnect/pinnacle_100_dvk/doc/index.rst +++ b/boards/ezurio/pinnacle_100_dvk/doc/index.rst @@ -1,7 +1,7 @@ .. _pinnacle_100_dvk: -Laird Connectivity Pinnacle 100 DVK -################################### +Ezurio Pinnacle 100 DVK +####################### Overview ******** @@ -14,7 +14,7 @@ internal antennas. Develop your application directly on the M4F controller using Zephyr RTOS to cut BOM costs and power consumption. Take advantage of the Zephyr community, -Laird Connectivity’s sample code (cellular, Bluetooth) and hardware interfaces, +Ezurio’s sample code (cellular, Bluetooth) and hardware interfaces, or use our hosted mode AT commands set firmware. Extremely power conscious, the Pinnacle 100 is ideal for battery-powered @@ -174,10 +174,9 @@ Segger IC. Software ******** -Pinnacle 100 Out-of-Box Demo Software -===================================== -The Pinnacle 100 development kit ships with an out of the box software demo. -Check out the `Pinnacle 100 OOB Demo`_ source code and documentation. +Canvas Software Suite +============================== +The Pinnacle 100 is a supported hardware platform for `Canvas Software Suite`_. Sample Applications =================== @@ -205,16 +204,16 @@ the board are working properly with Zephyr: 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/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.dts`. +:zephyr_file:`boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.dts`. References ********** .. target-notes:: -.. _Pinnacle 100 website: https://www.lairdconnect.com/wireless-modules/cellular-solutions/pinnacle-100-cellular-modem +.. _Pinnacle 100 website: https://www.ezurio.com/wireless-modules/cellular-solutions/pinnacle-100-cellular-modem .. _nRF52840 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.1.pdf .. _Sierra Wireless HL7800: https://source.sierrawireless.com/devices/hl-series/hl7800/#sthash.641qTTwA.dpbs .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _Pinnacle 100 OOB Demo: https://github.com/LairdCP/Pinnacle_100_oob_demo .. _Pinnacle 100 Sample Applications: https://github.com/LairdCP/Pinnacle_100_Sample_Applications +.. _Canvas Software Suite: https://www.ezurio.com/canvas/software-suite diff --git a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk-pinctrl.dtsi b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk-pinctrl.dtsi rename to boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk-pinctrl.dtsi diff --git a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.dts b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.dts similarity index 98% rename from boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.dts rename to boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.dts index 1e3006dd0d325d..175f71938c73a7 100644 --- a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.dts +++ b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +12,7 @@ / { model = "Pinnacle 100 Dev Kit"; - compatible = "lairdconnect,pinnacle-100-dvk"; + compatible = "ezurio,pinnacle-100-dvk"; chosen { zephyr,console = &uart0; @@ -81,7 +82,6 @@ mcuboot-button0 = &button1; mcuboot-led0 = &led1; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.yaml b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml similarity index 92% rename from boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.yaml rename to boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml index c4bd8252d19475..3d44a009e2d06d 100644 --- a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk.yaml +++ b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml @@ -19,4 +19,4 @@ supported: - usb_device - watchdog - netif:modem -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk_defconfig b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk_defconfig similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/pinnacle_100_dvk_defconfig rename to boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk_defconfig diff --git a/boards/lairdconnect/pinnacle_100_dvk/pre_dt_board.cmake b/boards/ezurio/pinnacle_100_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/pinnacle_100_dvk/pre_dt_board.cmake rename to boards/ezurio/pinnacle_100_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/rm1xx_dvk/Kconfig.defconfig b/boards/ezurio/rm1xx_dvk/Kconfig.defconfig similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/Kconfig.defconfig rename to boards/ezurio/rm1xx_dvk/Kconfig.defconfig diff --git a/boards/lairdconnect/rm1xx_dvk/Kconfig.rm1xx_dvk b/boards/ezurio/rm1xx_dvk/Kconfig.rm1xx_dvk similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/Kconfig.rm1xx_dvk rename to boards/ezurio/rm1xx_dvk/Kconfig.rm1xx_dvk diff --git a/boards/lairdconnect/rm1xx_dvk/board.cmake b/boards/ezurio/rm1xx_dvk/board.cmake similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/board.cmake rename to boards/ezurio/rm1xx_dvk/board.cmake diff --git a/boards/lairdconnect/rm1xx_dvk/board.yml b/boards/ezurio/rm1xx_dvk/board.yml similarity index 69% rename from boards/lairdconnect/rm1xx_dvk/board.yml rename to boards/ezurio/rm1xx_dvk/board.yml index 1e7ddd8f806789..4a8792eecc57d7 100644 --- a/boards/lairdconnect/rm1xx_dvk/board.yml +++ b/boards/ezurio/rm1xx_dvk/board.yml @@ -1,5 +1,5 @@ board: name: rm1xx_dvk - vendor: lairdconnect + vendor: ezurio socs: - name: nrf51822 diff --git a/boards/lairdconnect/rm1xx_dvk/doc/img/RM186-DVK.jpg b/boards/ezurio/rm1xx_dvk/doc/img/RM186-DVK.jpg similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/doc/img/RM186-DVK.jpg rename to boards/ezurio/rm1xx_dvk/doc/img/RM186-DVK.jpg diff --git a/boards/lairdconnect/rm1xx_dvk/doc/img/RM186-SM.jpg b/boards/ezurio/rm1xx_dvk/doc/img/RM186-SM.jpg similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/doc/img/RM186-SM.jpg rename to boards/ezurio/rm1xx_dvk/doc/img/RM186-SM.jpg diff --git a/boards/lairdconnect/rm1xx_dvk/doc/index.rst b/boards/ezurio/rm1xx_dvk/doc/index.rst similarity index 93% rename from boards/lairdconnect/rm1xx_dvk/doc/index.rst rename to boards/ezurio/rm1xx_dvk/doc/index.rst index bd006dc058a521..f530c9b791fd58 100644 --- a/boards/lairdconnect/rm1xx_dvk/doc/index.rst +++ b/boards/ezurio/rm1xx_dvk/doc/index.rst @@ -1,12 +1,12 @@ .. _rm1xx_dvk: -Laird Connectivity RM1xx DVK -############################ +Ezurio RM1xx DVK +################ Overview ******** -Laird Connectivity's RM1xx is a module which integrates both LoRa and +Ezurio's RM1xx is a module which integrates both LoRa and BLE communications, powered by a Nordic Semiconductor nRF51822 ARM Cortex-M0 CPU and on-board Semtech SX1272 LoRa RF chip. This board supports the RM1xx on the RM1xx development board - RM191 for the @@ -32,13 +32,13 @@ This development kit has the following features: :align: center :alt: RM1xx development kit (DVK) - RM1xx development kit (DVK) (Credit: Laird Connectivity) + RM1xx development kit (DVK) (Credit: Ezurio) .. figure:: img/RM186-SM.jpg :align: center :alt: RM1xx module - RM1xx module (Credit: Laird Connectivity) + RM1xx module (Credit: Ezurio) More information about the module can be found on the `RM1xx homepage`_. @@ -172,7 +172,7 @@ References .. target-notes:: -.. _RM1xx homepage: https://www.lairdconnect.com/wireless-modules/lorawan-solutions/sentrius-rm1xx-lora-ble-module +.. _RM1xx homepage: https://www.ezurio.com/wireless-modules/lorawan-solutions/sentrius-rm1xx-lora-ble-module .. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com .. _Adesto AT25DF041B datasheet: https://www.dialog-semiconductor.com/sites/default/files/ds-at25df041b_040.pdf .. _Semtech SX1272 datasheet: https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/440000001NCE/v_VBhk1IolDgxwwnOpcS_vTFxPfSEPQbuneK3mWsXlU diff --git a/boards/lairdconnect/rm1xx_dvk/pre_dt_board.cmake b/boards/ezurio/rm1xx_dvk/pre_dt_board.cmake similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/pre_dt_board.cmake rename to boards/ezurio/rm1xx_dvk/pre_dt_board.cmake diff --git a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk-pinctrl.dtsi b/boards/ezurio/rm1xx_dvk/rm1xx_dvk-pinctrl.dtsi similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/rm1xx_dvk-pinctrl.dtsi rename to boards/ezurio/rm1xx_dvk/rm1xx_dvk-pinctrl.dtsi diff --git a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.dts b/boards/ezurio/rm1xx_dvk/rm1xx_dvk.dts similarity index 96% rename from boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.dts rename to boards/ezurio/rm1xx_dvk/rm1xx_dvk.dts index 8d364bfa27aa0d..f0b860ac45381a 100644 --- a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.dts +++ b/boards/ezurio/rm1xx_dvk/rm1xx_dvk.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Laird Connectivity + * Copyright (c) 2024 Ezurio * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +11,8 @@ #include / { - model = "Laird Connectivity RM1XX_DVK"; - compatible = "lairdconnect,rm1xx_dvk"; + model = "Ezurio RM1XX_DVK"; + compatible = "ezurio,rm1xx_dvk"; chosen { zephyr,console = &uart0; @@ -37,7 +38,6 @@ sw0 = &button2; lora0 = &lora0; watchdog0 = &wdt0; - spi-flash0 = &at25; }; }; diff --git a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.yaml b/boards/ezurio/rm1xx_dvk/rm1xx_dvk.yaml similarity index 89% rename from boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.yaml rename to boards/ezurio/rm1xx_dvk/rm1xx_dvk.yaml index c673fd4d55ec26..2dd24375a5b7db 100644 --- a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk.yaml +++ b/boards/ezurio/rm1xx_dvk/rm1xx_dvk.yaml @@ -14,4 +14,4 @@ supported: testing: ignore_tags: - net -vendor: lairdconnect +vendor: ezurio diff --git a/boards/lairdconnect/rm1xx_dvk/rm1xx_dvk_defconfig b/boards/ezurio/rm1xx_dvk/rm1xx_dvk_defconfig similarity index 100% rename from boards/lairdconnect/rm1xx_dvk/rm1xx_dvk_defconfig rename to boards/ezurio/rm1xx_dvk/rm1xx_dvk_defconfig diff --git a/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.dts b/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.dts index 090a29a1981874..a8db5b677f23ec 100644 --- a/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.dts +++ b/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.dts @@ -41,7 +41,6 @@ aliases { led0 = &user_led; sw0 = &user_button; - spi-flash0 = &w25q64jvssiq_spi; }; }; diff --git a/boards/gaisler/gr716a_mini/gr716a_mini.dts b/boards/gaisler/gr716a_mini/gr716a_mini.dts index 745caa64f671b5..fb42de635a0667 100644 --- a/boards/gaisler/gr716a_mini/gr716a_mini.dts +++ b/boards/gaisler/gr716a_mini/gr716a_mini.dts @@ -12,9 +12,7 @@ / { model = "GR716-MINI Development Board"; compatible = "gaisler,gr716a-mini"; - aliases { - spi-flash0 = &flash0; - }; + chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; diff --git a/boards/gd/gd32a503v_eval/gd32a503v_eval.dts b/boards/gd/gd32a503v_eval/gd32a503v_eval.dts index dc6e0325452bef..41fd7b2d75d979 100644 --- a/boards/gd/gd32a503v_eval/gd32a503v_eval.dts +++ b/boards/gd/gd32a503v_eval/gd32a503v_eval.dts @@ -35,7 +35,6 @@ aliases { led0 = &led1; led1 = &led2; - spi-flash0 = &nor_flash; }; }; diff --git a/boards/gd/gd32f450i_eval/gd32f450i_eval.dts b/boards/gd/gd32f450i_eval/gd32f450i_eval.dts index 4e2f87c4015b81..4a9f9d4fb6a883 100644 --- a/boards/gd/gd32f450i_eval/gd32f450i_eval.dts +++ b/boards/gd/gd32f450i_eval/gd32f450i_eval.dts @@ -71,7 +71,6 @@ sw0 = &user_key; pwm-led0 = &pwm_led; eeprom-0 = &eeprom0; - spi-flash0 = &nor_flash; watchdog0 = &fwdgt; }; }; diff --git a/boards/gd/gd32f450z_eval/gd32f450z_eval.dts b/boards/gd/gd32f450z_eval/gd32f450z_eval.dts index c636a5647c7d05..f01fd488b4c3e9 100644 --- a/boards/gd/gd32f450z_eval/gd32f450z_eval.dts +++ b/boards/gd/gd32f450z_eval/gd32f450z_eval.dts @@ -71,7 +71,6 @@ sw0 = &user_key; pwm-led0 = &pwm_led; eeprom-0 = &eeprom0; - spi-flash0 = &nor_flash; watchdog0 = &fwdgt; }; }; diff --git a/boards/gd/gd32f470i_eval/gd32f470i_eval.dts b/boards/gd/gd32f470i_eval/gd32f470i_eval.dts index 306d190b3d4a86..1bff660f1c6f67 100644 --- a/boards/gd/gd32f470i_eval/gd32f470i_eval.dts +++ b/boards/gd/gd32f470i_eval/gd32f470i_eval.dts @@ -71,7 +71,6 @@ sw0 = &user_key; pwm-led0 = &pwm_led; eeprom-0 = &eeprom0; - spi-flash0 = &nor_flash; watchdog0 = &fwdgt; }; }; diff --git a/boards/gd/gd32vf103v_eval/gd32vf103v_eval.dts b/boards/gd/gd32vf103v_eval/gd32vf103v_eval.dts index cea9c00b7e99e3..bee944f7fdc9f4 100644 --- a/boards/gd/gd32vf103v_eval/gd32vf103v_eval.dts +++ b/boards/gd/gd32vf103v_eval/gd32vf103v_eval.dts @@ -84,7 +84,6 @@ led1 = &led2; sw0 = &key_cet; pwm-led0 = &pwm_led; - spi-flash0 = &nor_flash; watchdog0 = &fwdgt; }; }; diff --git a/boards/hardkernel/odroid_go/Kconfig.defconfig b/boards/hardkernel/odroid_go/Kconfig.defconfig index 345a0f4f64ee63..58874c1f51408f 100644 --- a/boards/hardkernel/odroid_go/Kconfig.defconfig +++ b/boards/hardkernel/odroid_go/Kconfig.defconfig @@ -12,7 +12,7 @@ config SPI default y if DISK_DRIVER_SDMMC config ESP_SPIRAM - default y + default y if !MCUBOOT choice SPIRAM_TYPE default SPIRAM_TYPE_ESPPSRAM64 @@ -25,10 +25,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ODROID_GO_ESP32_PROCPU if BOARD_ODROID_GO_ESP32_APPCPU diff --git a/boards/hardkernel/odroid_go/odroid_go_procpu.dts b/boards/hardkernel/odroid_go/odroid_go_procpu.dts index 0d150d08f16038..c7de3a9c576e4a 100644 --- a/boards/hardkernel/odroid_go/odroid_go_procpu.dts +++ b/boards/hardkernel/odroid_go/odroid_go_procpu.dts @@ -20,6 +20,7 @@ zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,display = &ili9341; + zephyr,bt-hci = &esp32_bt_hci; }; leds { @@ -206,3 +207,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/heltec/heltec_wifi_lora32_v2/Kconfig.defconfig b/boards/heltec/heltec_wifi_lora32_v2/Kconfig.defconfig index 4f459aa0ca4250..a2979499b658f6 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/Kconfig.defconfig +++ b/boards/heltec/heltec_wifi_lora32_v2/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_HELTEC_WIFI_LORA32_V2_ESP32_PROCPU if BOARD_HELTEC_WIFI_LORA32_V2_ESP32_APPCPU diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts index 5fdec28fe33892..4c7cedf82b5fc9 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts @@ -55,6 +55,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -149,5 +150,9 @@ }; }; +&esp32_bt_hci { + status = "okay"; +}; + /* Required by the ssd1306_128x64 shield which enables the OLED display */ arduino_i2c: &i2c0 {}; diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/Kconfig.defconfig b/boards/heltec/heltec_wireless_stick_lite_v3/Kconfig.defconfig index 82915e44b949b0..c1aa6f030c7670 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/Kconfig.defconfig +++ b/boards/heltec/heltec_wireless_stick_lite_v3/Kconfig.defconfig @@ -13,10 +13,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_HELTEC_WIRELESS_STICK_LITE_V3_ESP32S3_PROCPU if BOARD_HELTEC_WIRELESS_STICK_LITE_V3_ESP32S3_APPCPU diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts index ca455d9d780259..854eb101fe4d7f 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts @@ -72,6 +72,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -205,3 +206,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/infineon/cy8ckit_062s4/doc/index.rst b/boards/infineon/cy8ckit_062s4/doc/index.rst index f3a026b3b6bc87..1dfdb93bd307d0 100644 --- a/boards/infineon/cy8ckit_062s4/doc/index.rst +++ b/boards/infineon/cy8ckit_062s4/doc/index.rst @@ -50,7 +50,7 @@ The board configuration supports the following hardware features: +-----------+------------+-----------------------+ The default configuration can be found in the Kconfig -:zephyr_file:`boards/cypress/cy8ckit_062s4/cy8ckit_062s4_defconfig`. +:zephyr_file:`boards/infineon/cy8ckit_062s4/cy8ckit_062s4_defconfig`. Clock Configuration =================== diff --git a/boards/infineon/cy8cproto_062_4343w/Kconfig.defconfig b/boards/infineon/cy8cproto_062_4343w/Kconfig.defconfig index 270370c7660152..5573b7f0417731 100644 --- a/boards/infineon/cy8cproto_062_4343w/Kconfig.defconfig +++ b/boards/infineon/cy8cproto_062_4343w/Kconfig.defconfig @@ -36,13 +36,6 @@ config UART bool default y -config BT_UART - default y - -choice BT_HCI_BUS_TYPE - default BT_H4 -endchoice - endif # BT # Heap Pool Size diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 7997344dd540ae..b9e74ac685d0ba 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -25,7 +25,7 @@ zephyr,flash = &flash0; zephyr,console = &uart5; zephyr,shell-uart = &uart5; - zephyr,bt_uart = &uart2; + zephyr,bt-hci = &bt_hci_uart; }; }; @@ -58,17 +58,22 @@ uart2: &scb2 { /* HW Flow control must be enabled for HCI H4 */ hw-flow-control; - bt-hci { - status = "okay"; - compatible = "infineon,cyw43xxx-bt-hci"; - bt-reg-on-gpios = <&gpio_prt3 4 (GPIO_ACTIVE_HIGH)>; - - /* Configuration UART speeds for firmware download (fw-download-speed) and - * HCI operation (hci-operation-speed). - * If hci-operation-speed or fw-download-speed are not defined in bt-hci{...} - * node, cyw43xx driver will use bus/current-speed as default speed. - */ - fw-download-speed = <3000000>; + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + + murata-1dx { + status = "okay"; + compatible = "infineon,cyw43xxx-bt-hci"; + bt-reg-on-gpios = <&gpio_prt3 4 (GPIO_ACTIVE_HIGH)>; + + /* Configuration UART speeds for firmware download (fw-download-speed) + * and HCI operation (hci-operation-speed). + * If hci-operation-speed or fw-download-speed are not defined in + * bt-hci{...} node, cyw43xx driver will use bus/current-speed as + * default speed. + */ + fw-download-speed = <3000000>; + }; }; }; diff --git a/boards/infineon/cy8cproto_062_4343w/doc/index.rst b/boards/infineon/cy8cproto_062_4343w/doc/index.rst index e1be366086c4ed..a5934089f0b31a 100644 --- a/boards/infineon/cy8cproto_062_4343w/doc/index.rst +++ b/boards/infineon/cy8cproto_062_4343w/doc/index.rst @@ -74,7 +74,7 @@ The board configuration supports the following hardware features: The default configuration can be found in the Kconfig -:zephyr_file:`boards/cypress/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig` +:zephyr_file:`boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig` System Clock diff --git a/boards/infineon/cy8cproto_063_ble/Kconfig.defconfig b/boards/infineon/cy8cproto_063_ble/Kconfig.defconfig index 2d079f63a6b485..4123455e9f93b7 100644 --- a/boards/infineon/cy8cproto_063_ble/Kconfig.defconfig +++ b/boards/infineon/cy8cproto_063_ble/Kconfig.defconfig @@ -6,8 +6,6 @@ if BOARD_CY8CPROTO_063_BLE -choice BT_HCI_BUS_TYPE - default BT_PSOC6_BLESS if BT -endchoice +# No defaults to change for now endif # BOARD_CY8CPROTO_063_BLE diff --git a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts index 0f96ff07a774f3..5516895fddd8b1 100644 --- a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts +++ b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts @@ -27,6 +27,7 @@ zephyr,flash = &flash0; zephyr,console = &uart5; zephyr,shell-uart = &uart5; + zephyr,bt-hci = &bluetooth; }; /delete-node/ cpu@0; diff --git a/boards/infineon/cy8cproto_063_ble/doc/index.rst b/boards/infineon/cy8cproto_063_ble/doc/index.rst index 8ef38711c8f8ee..86cc9cd5c15958 100644 --- a/boards/infineon/cy8cproto_063_ble/doc/index.rst +++ b/boards/infineon/cy8cproto_063_ble/doc/index.rst @@ -59,7 +59,7 @@ The board configuration supports the following hardware features: The default configurations can be found in -:zephyr_file:`boards/cypress/cy8cproto_063_ble/cy8cproto_063_ble_defconfig` +:zephyr_file:`boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble_defconfig` System Clock ============ diff --git a/boards/infineon/cyw920829m2evk_02/Kconfig.defconfig b/boards/infineon/cyw920829m2evk_02/Kconfig.defconfig new file mode 100644 index 00000000000000..645567a40c7ef0 --- /dev/null +++ b/boards/infineon/cyw920829m2evk_02/Kconfig.defconfig @@ -0,0 +1,13 @@ +# The Infineon AIROC™ CYW20829 Bluetooth® LE evaluation kit (CYW92089M2EVK-02) + +# Copyright (c) 2024 Cypress Semiconductor Corporation. +# SPDX-License-Identifier: Apache-2.0 + +choice AIROC_PART + default CYW20829 if BT +endchoice + +# Heap Pool Size +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 10096 diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts index 638f3efa8815f7..334704b98e038f 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts @@ -13,11 +13,16 @@ model = "The Infineon AIROC™ CYW20829 Bluetooth® LE evaluation kit (CYW92089M2EVK-02)"; compatible = "infineon,cyw920829m2evk_02", "infineon,CYW20829"; + aliases { + watchdog0 = &watchdog0; + }; + chosen { zephyr,sram = &sram0; zephyr,flash = &app_region; zephyr,console = &uart2; zephyr,shell-uart = &uart2; + zephyr,bt-hci = &bluetooth; }; }; @@ -71,6 +76,14 @@ uart2: &scb2 { status = "okay"; }; +&watchdog0 { + status = "okay"; +}; + +&bluetooth { + status = "okay"; +}; + / { flash0: flash@60000000 { compatible = "soc-nv-flash"; @@ -91,15 +104,15 @@ uart2: &scb2 { bootstrap_region: flash@60000050 { compatible = "zephyr,memory-region", "soc-nv-flash"; zephyr,memory-region = "BOOTSTRAP_FLASH"; - reg = <0x60000050 0x2550>; + reg = <0x60000050 DT_SIZE_K(12)>; }; - app_region: flash@60002600 { + app_region: flash@60003050 { compatible = "soc-nv-flash"; - reg = <0x60002600 0x5da00>; + reg = <0x60003050 0x6CFB0>; /* 435kb */ }; - storage_partition: flash@60060000 { + storage_partition: flash@60070000 { compatible = "soc-nv-flash"; - reg = <0x60060000 0x20000>; + reg = <0x60070000 DT_SIZE_K(64)>; }; }; }; diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml index 590385dc4ec7ae..a02da7d1937801 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml @@ -17,5 +17,8 @@ supported: - uart - clock_control - bluetooth + - watchdog + - spi + - i2c vendor: infineon diff --git a/boards/infineon/cyw920829m2evk_02/doc/index.rst b/boards/infineon/cyw920829m2evk_02/doc/index.rst index ac92f59d12a906..fbb6e024392618 100644 --- a/boards/infineon/cyw920829m2evk_02/doc/index.rst +++ b/boards/infineon/cyw920829m2evk_02/doc/index.rst @@ -72,6 +72,17 @@ The AIROC™ CYW20829 Bluetooth® MCU SoC is configured to use the internal IMO the system clock. Other sources for the system clock are provided in the SOC, depending on your system requirements. +Fetch Binary Blobs +****************** + +cyw920829m2evk_02 board requires fetch binary files (e.g Bluetooth controller firmware). + +To fetch Binary Blobs: + +.. code-block:: console + + west blobs fetch hal_infineon + Build blinking led sample ************************* @@ -98,14 +109,14 @@ The CYW920829M2EVK-02 includes an onboard programmer/debugger (KitProg3) to prov On Windows: -.. code-block:: console +.. code-block:: shell west flash --openocd path/to/infineon/openocd/bin/openocd.exe west debug --openocd path/to/infineon/openocd/bin/openocd.exe On Linux: -.. code-block:: console +.. code-block:: shell west flash --openocd path/to/infineon/openocd/bin/openocd west debug --openocd path/to/infineon/openocd/bin/openocd diff --git a/boards/infineon/cyw920829m2evk_02/support/openocd.cfg b/boards/infineon/cyw920829m2evk_02/support/openocd.cfg index 419ffc13abc1a1..fe70fb383a8a30 100644 --- a/boards/infineon/cyw920829m2evk_02/support/openocd.cfg +++ b/boards/infineon/cyw920829m2evk_02/support/openocd.cfg @@ -8,3 +8,7 @@ source [find interface/kitprog3.cfg] transport select swd source [find target/cyw20829.cfg] + +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + adapter serial $_ZEPHYR_BOARD_SERIAL +} diff --git a/boards/intel/adsp/Kconfig.intel_adsp b/boards/intel/adsp/Kconfig.intel_adsp index 2e4c98447203b2..f5a81c6dfcc633 100644 --- a/boards/intel/adsp/Kconfig.intel_adsp +++ b/boards/intel/adsp/Kconfig.intel_adsp @@ -6,3 +6,4 @@ config BOARD_INTEL_ADSP select SOC_INTEL_CAVS_V25 if BOARD_INTEL_ADSP_CAVS25_TGPH select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM select SOC_INTEL_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL + select SOC_INTEL_ACE30_PTL if BOARD_INTEL_ADSP_ACE30_PTL diff --git a/boards/intel/adsp/board.cmake b/boards/intel/adsp/board.cmake index bcdfc3286467c8..584474544bf2d7 100644 --- a/boards/intel/adsp/board.cmake +++ b/boards/intel/adsp/board.cmake @@ -39,4 +39,12 @@ elseif(CONFIG_BOARD_INTEL_ADSP_ACE20_LNL) set(RIMAGE_SIGN_KEY "otc_private_key_3k.pem" CACHE STRING "default in ace20_lnl/board.cmake") +elseif(CONFIG_BOARD_INTEL_ADSP_ACE30_PTL) + + board_set_rimage_target(ptl) + + set(RIMAGE_SIGN_KEY "otc_private_key.pem" CACHE STRING "default rimage key") + + board_finalize_runner_args(intel_adsp) + endif() diff --git a/boards/intel/adsp/board.yml b/boards/intel/adsp/board.yml index 9295ae0c3eb2fd..8e35014dd66f96 100644 --- a/boards/intel/adsp/board.yml +++ b/boards/intel/adsp/board.yml @@ -7,3 +7,4 @@ boards: - name: 'tgph' - name: ace15_mtpm - name: ace20_lnl + - name: ace30_ptl diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl.dts b/boards/intel/adsp/intel_adsp_ace30_ptl.dts new file mode 100644 index 00000000000000..9e25712bc2c3e2 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_ace30_ptl"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &mem_window3; + }; +}; diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl.yaml b/boards/intel/adsp/intel_adsp_ace30_ptl.yaml new file mode 100644 index 00000000000000..bdfe837bd082fb --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl.yaml @@ -0,0 +1,10 @@ +identifier: intel_adsp/ace30_ptl +name: ACE 3.0 Panther Lake Audio DSP +type: mcu +arch: xtensa +toolchain: + - xt-clang +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig b/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig new file mode 100644 index 00000000000000..913d2a8c3e3a90 --- /dev/null +++ b/boards/intel/adsp/intel_adsp_ace30_ptl_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_BUILD_OUTPUT_BIN=n + +CONFIG_DAI_SSP_HAS_POWER_CONTROL=y + +CONFIG_DCACHE_LINE_SIZE=64 diff --git a/boards/intel/ish/Kconfig.defconfig b/boards/intel/ish/Kconfig.defconfig index fdedc70fd29b52..6112d43c0499e9 100644 --- a/boards/intel/ish/Kconfig.defconfig +++ b/boards/intel/ish/Kconfig.defconfig @@ -9,4 +9,5 @@ config TEST_EXTRA_STACK_SIZE endif # TEST config SYS_CLOCK_TICKS_PER_SEC - default 2048 if HPET_TIMER # HPET is 32768 HZ + default 2048 if HPET_TIMER # HPET timer's frequency is 32768 HZ + default 2000 if APIC_TIMER_TSC # APIC timer's frequency is 19.2 MHZ or 100 MHZ diff --git a/boards/intel/socfpga_std/cyclonev_socdk/cyclonev_socdk.dts b/boards/intel/socfpga_std/cyclonev_socdk/cyclonev_socdk.dts index 5218c62f2c7bd5..a45c0768273ec7 100644 --- a/boards/intel/socfpga_std/cyclonev_socdk/cyclonev_socdk.dts +++ b/boards/intel/socfpga_std/cyclonev_socdk/cyclonev_socdk.dts @@ -63,7 +63,7 @@ status = "okay"; eeprom: eeprom@51 { - compatible = "atmel,at24"; + compatible = "microchip,at24lc32a", "atmel,at24"; status = "okay"; reg = <0x51>; size = <4096>; diff --git a/boards/ite/it82xx2_evb/it82xx2_evb.dts b/boards/ite/it82xx2_evb/it82xx2_evb.dts index bd623e969c54f6..29e8ad721c88d0 100644 --- a/boards/ite/it82xx2_evb/it82xx2_evb.dts +++ b/boards/ite/it82xx2_evb/it82xx2_evb.dts @@ -25,7 +25,7 @@ chosen { zephyr,console = &uart1; zephyr,shell-uart = &uart1; - zephyr,bt-uart = &uart2; + zephyr,bt-hci = &bt_hci_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,flash-controller = &flashctrl; @@ -115,6 +115,11 @@ status = "okay"; current-speed = <460800>; clock-frequency = <1843200>; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; &ite_uart1_wrapper { diff --git a/boards/ite/it8xxx2_evb/it8xxx2_evb.dts b/boards/ite/it8xxx2_evb/it8xxx2_evb.dts index c111e9092aa15d..0ee42f981f0848 100644 --- a/boards/ite/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/ite/it8xxx2_evb/it8xxx2_evb.dts @@ -25,7 +25,7 @@ chosen { zephyr,console = &uart1; zephyr,shell-uart = &uart1; - zephyr,bt-uart = &uart2; + zephyr,bt-hci = &bt_hci_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,flash-controller = &flashctrl; @@ -105,6 +105,11 @@ status = "okay"; current-speed = <460800>; clock-frequency = <1843200>; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; &ite_uart1_wrapper { status = "okay"; diff --git a/boards/kincony/kincony_kc868_a32/Kconfig.defconfig b/boards/kincony/kincony_kc868_a32/Kconfig.defconfig index e8705a11f98507..4d4613b36ad538 100644 --- a/boards/kincony/kincony_kc868_a32/Kconfig.defconfig +++ b/boards/kincony/kincony_kc868_a32/Kconfig.defconfig @@ -10,10 +10,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_KINCONY_KC868_A32_ESP32_PROCPU if BOARD_KINCONY_KC868_A32_ESP32_APPCPU diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts index 5b60336d1bb2e6..be7da2765efaf0 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -203,3 +204,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/lilygo/index.rst b/boards/lilygo/index.rst new file mode 100644 index 00000000000000..8333f6918677f9 --- /dev/null +++ b/boards/lilygo/index.rst @@ -0,0 +1,10 @@ +.. _boards-lilygo: + +Lilygo +###### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/lilygo/ttgo_lora32/Kconfig.defconfig b/boards/lilygo/ttgo_lora32/Kconfig.defconfig new file mode 100644 index 00000000000000..d77a95c89b0762 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/Kconfig.defconfig @@ -0,0 +1,25 @@ +# Lilygo ttgo LoRa32 board configuration + +# Copyright (c) 2024 Lothar Felten +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_TTGO_LORA32_ESP32_PROCPU + +config ENTROPY_GENERATOR + default y + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 65535 if WIFI && BT + default 51200 if WIFI + default 40960 if BT + default 4096 + +endif # BOARD_TTGO_LORA32_ESP32_PROCPU + +if BOARD_TTGO_LORA32_ESP32_APPCPU + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + default 256 + +endif # BOARD_TTGO_LORA32_ESP32_APPCPU diff --git a/boards/lilygo/ttgo_lora32/Kconfig.sysbuild b/boards/lilygo/ttgo_lora32/Kconfig.sysbuild new file mode 100644 index 00000000000000..3a2d17ac5cfd06 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/lilygo/ttgo_lora32/Kconfig.ttgo_lora32 b/boards/lilygo/ttgo_lora32/Kconfig.ttgo_lora32 new file mode 100644 index 00000000000000..b1cac2dac488dc --- /dev/null +++ b/boards/lilygo/ttgo_lora32/Kconfig.ttgo_lora32 @@ -0,0 +1,9 @@ +# TTGO LoRa32 board configuration + +# Copyright (c) 2024 Lothar Felten +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_TTGO_LORA32 + select SOC_ESP32_PICO_D4 + select SOC_ESP32_PROCPU if BOARD_TTGO_LORA32_ESP32_PROCPU + select SOC_ESP32_APPCPU if BOARD_TTGO_LORA32_ESP32_APPCPU diff --git a/boards/lilygo/ttgo_lora32/board.cmake b/boards/lilygo/ttgo_lora32/board.cmake new file mode 100644 index 00000000000000..91b3caa2c75d51 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/board.cmake @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +# the default ESP32 baud rate is not supported +board_runner_args(esp32 "--esp-baud-rate=1500000") diff --git a/boards/lilygo/ttgo_lora32/board.yml b/boards/lilygo/ttgo_lora32/board.yml new file mode 100644 index 00000000000000..8cccfbbf7d2676 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/board.yml @@ -0,0 +1,5 @@ +board: + name: ttgo_lora32 + vendor: lilygo + socs: + - name: esp32 diff --git a/boards/lilygo/ttgo_lora32/doc/img/ttgo_lora32.webp b/boards/lilygo/ttgo_lora32/doc/img/ttgo_lora32.webp new file mode 100644 index 00000000000000..4d240e9d6b996f Binary files /dev/null and b/boards/lilygo/ttgo_lora32/doc/img/ttgo_lora32.webp differ diff --git a/boards/lilygo/ttgo_lora32/doc/index.rst b/boards/lilygo/ttgo_lora32/doc/index.rst new file mode 100644 index 00000000000000..b149fa6fa0c55a --- /dev/null +++ b/boards/lilygo/ttgo_lora32/doc/index.rst @@ -0,0 +1,245 @@ +.. _ttgo_lora32: + +Lilygo TTGO LoRa32 +################## + +Overview +******** + +The Lilygo TTGO LoRa32 is a development board for LoRa applications baesed on the ESP32-PICO-D4. + +It's available in two versions supporting two different frequency ranges and features the following integrated components: + +- ESP32-PICO-D4 chip (240MHz dual core, 600 DMIPS, 520KB SRAM, Wi-Fi) +- SSD1306, 128x64 px, 0.96" screen +- SX1278 (433MHz) or SX1276 (868/915/923MHz) LoRa radio frontend +- JST GH 2-pin battery connector +- TF card slot + +Some of the ESP32 I/O pins are accessible on the board's pin headers. + +.. figure:: img/ttgo_lora32.webp + :align: center + :alt: Lilygo TTGO LoRa32 module + :width: 400 px + + Lilygo TTGO LoRa32 module + +Functional Description +********************** + +The following table below describes the key components, interfaces, and controls +of the Lilygo TTGO LoRa32 board. + +.. _SX127x: https://www.semtech.com/products/wireless-rf/lora-connect/sx1276#documentation +.. _ESP32-PICO-D4: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf +.. _SSD1306: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf + ++------------------+-------------------------------------------------------------------------+ +| Key Component | Description | ++==================+=========================================================================+ +| ESP32-PICO-D4 | This `ESP32-PICO-D4`_ module provides complete Wi-Fi and Bluetooth | +| | functionalities and integrates a 4-MB SPI flash. | ++------------------+-------------------------------------------------------------------------+ +| Diagnostic LED | One user LED connected to the GPIO pin. | ++------------------+-------------------------------------------------------------------------+ +| USB Port | USB interface. Power supply for the board as well as the | +| | serial communication interface between a computer and the board. | +| | Micro-USB type connector. | ++------------------+-------------------------------------------------------------------------+ +| Power Switch | Sliding power switch. | ++------------------+-------------------------------------------------------------------------+ +| LCD screen | Built-in OLED display \(`SSD1306`_, 0.96", 128x64 px\) controlled | +| | by I2C interface | ++------------------+-------------------------------------------------------------------------+ +| SX1276/SX1278 | LoRa radio frontend chip, connected via SPI. | +| | Use SX1276 for 433MHz and SX1276 for 868/915/923MHz. | ++------------------+-------------------------------------------------------------------------+ +| TF card slot | TF card slot wired to the SD interface of the MCU. | ++------------------+-------------------------------------------------------------------------+ + + +Start Application Development +***************************** + +Before powering up your Lilygo TTGO LoRa32, please make sure that the board is in good +condition with no obvious signs of damage. + +System requirements +******************* + +Prerequisites +============= + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +Simple boot +=========== + +The board could be loaded using the single binary image, without 2nd stage bootloader. +It is the default option when building the application without additional configuration. + +.. note:: + + Simple boot does not provide any security features nor OTA updates. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be build (and flash) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + +.. code-block:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the ESP32-PICO-D4 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :app: samples/hello_world + :board: ttgo_lora32/esp32/procpu + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32-PICO-D4 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │   └── zephyr + │   ├── zephyr.elf + │   └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be build one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ttgo_lora32/esp32/procpu + :goals: build + +The usual ``flash`` target will work with the ``ttgo_lora32`` board +configuration. Here is an example for the :ref:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ttgo_lora32/esp32/procpu + :goals: flash + +The default baud rate for the Lilygo TTGO LoRa32 is set to 1500000bps. If experiencing issues when flashing, +try using different values by using ``--esp-baud-rate `` option during +``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). + +You can also open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! ttgo_lora32 + +LoRa samples +============ + +There are two LoRa samples that will work out of the box with this board. + +To build the LoRa transmit sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :app: samples/drivers/lora/send + :board: ttgo_lora32/esp32/procpu + :goals: build + :west-args: --sysbuild + :compact: + +To build the LoRa receive sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :app: samples/drivers/lora/receive + :board: ttgo_lora32/esp32/procpu + :goals: build + :west-args: --sysbuild + :compact: + +Debugging +********* + +Lilygo TTGO LoRa32 debugging is not supported due to pinout limitations. + +Related Documents +***************** +- `Lilygo TTGO LoRa32 schematic `_ (PDF) +- `Lilygo TTGO LoRa32 documentation `_ +- `Lilygo github repo `_ +- `ESP32-PICO-D4 Datasheet `_ (PDF) +- `ESP32 Datasheet `_ (PDF) +- `ESP32 Hardware Reference `_ diff --git a/boards/lilygo/ttgo_lora32/support/openocd.cfg b/boards/lilygo/ttgo_lora32/support/openocd.cfg new file mode 100644 index 00000000000000..338e6e4e6eae9a --- /dev/null +++ b/boards/lilygo/ttgo_lora32/support/openocd.cfg @@ -0,0 +1,5 @@ +set ESP_RTOS none +set ESP32_ONLYCPU 1 + +source [find interface/ftdi/esp32_devkitj_v1.cfg] +source [find target/esp32.cfg] diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi b/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi new file mode 100644 index 00000000000000..5f043ddb945d67 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Lothar Felten + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim3_default: spim3_default { + group1 { + pinmux = , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + +}; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts new file mode 100644 index 00000000000000..c5eb19c240f3d9 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/dts-v1/; + +#include + +/ { + model = "ttgo LoRa32 APPCPU"; + compatible = "espressif,esp32"; + + chosen { + zephyr,sram = &sram0; + zephyr,ipc_shm = &shm0; + zephyr,ipc = &ipm0; + }; +}; + +&ipm0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&flash0 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 60kB for the bootloader */ + boot_partition: partition@1000 { + label = "mcuboot"; + reg = <0x00001000 0x0000F000>; + read-only; + }; + + /* Reserve 1024kB for the application in slot 0 */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + /* Reserve 1024kB for the application in slot 1 */ + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + /* Reserve 256kB for the scratch partition */ + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.yaml b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.yaml new file mode 100644 index 00000000000000..f048566726012b --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.yaml @@ -0,0 +1,27 @@ +identifier: ttgo_lora32/esp32/appcpu +name: TTGO LoRa32 APPCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - uart +testing: + ignore_tags: + - net + - bluetooth + - flash + - cpp + - posix + - watchdog + - logging + - kernel + - pm + - gpio + - crypto + - eeprom + - heap + - cmsis_rtos + - jwt + - zdsp +vendor: lilygo diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig new file mode 100644 index 00000000000000..100bb882567619 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_CLOCK_CONTROL=y +CONFIG_MINIMAL_LIBC=y diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts new file mode 100644 index 00000000000000..d8dfad087e3e97 --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024 Lothar Felten + * + * SPDX-License-Identifier: Apache-2.0 + */ +/dts-v1/; + +#include +#include "ttgo_lora32-pinctrl.dtsi" +#include + +/ { + model = "ttgo LoRa32 PROCPU"; + compatible = "lilygo,ttgo-lora32"; + + aliases { + led0 = &green_led; + uart-0 = &uart0; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + lora0 = &lora0; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,display = &ssd1306_128x64; + }; + + leds { + compatible = "gpio-leds"; + + green_led: led_0 { + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + label = "Green - LED0"; + }; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +/* OLED display */ +&i2c0 { + status = "okay"; + clock-frequency = ; + sda-gpios = <&gpio0 21 GPIO_OPEN_DRAIN>; + scl-gpios = <&gpio0 22 GPIO_OPEN_DRAIN>; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + ssd1306_128x64: ssd1306@3c { + compatible = "solomon,ssd1306fb"; + reg = <0x3c>; + width = <128>; + height = <64>; + segment-offset = <0>; + page-offset = <0>; + display-offset = <0>; + multiplex-ratio = <63>; + segment-remap; + com-invdir; + prechargep = <0x22>; + }; +}; + +&spi3 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim3_default>; + pinctrl-names = "default"; + cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + lora0: lora@0 { + compatible = "semtech,sx1276"; + reg = <0>; + reset-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + dio-gpios = + /* SX1276 D0 -> GPIO26 */ + <&gpio0 26 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + /* SX1276 D1 -> GPIO35 */ + <&gpio1 3 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + /* SX1276 D1 -> GPIO34 */ + <&gpio1 2 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + spi-max-frequency = <1000000>; + power-amplifier-output = "pa-boost"; + }; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&timer3 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&flash0 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 60kB for the bootloader */ + boot_partition: partition@1000 { + label = "mcuboot"; + reg = <0x00001000 0x0000F000>; + read-only; + }; + + /* Reserve 1024kB for the application in slot 0 */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + /* Reserve 1024kB for the application in slot 1 */ + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + /* Reserve 256kB for the scratch partition */ + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml new file mode 100644 index 00000000000000..f4d0e25cc59d2d --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml @@ -0,0 +1,21 @@ +identifier: ttgo_lora32/esp32/procpu +name: TTGO LoRa32 PROCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - i2c + - spi + - watchdog + - uart + - pinmux + - display + - lora + - nvs +testing: + ignore_tags: + - net + - bluetooth +vendor: lilygo diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig new file mode 100644 index 00000000000000..ee9920cda6870e --- /dev/null +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + +CONFIG_GPIO=y +CONFIG_I2C=y diff --git a/boards/lilygo/ttgo_t8c3/Kconfig.defconfig b/boards/lilygo/ttgo_t8c3/Kconfig.defconfig new file mode 100644 index 00000000000000..eb2f107cd0d3e8 --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Lothar Felten +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 65535 if WIFI && BT + default 51200 if WIFI + default 40960 if BT + default 4096 diff --git a/boards/lilygo/ttgo_t8c3/Kconfig.sysbuild b/boards/lilygo/ttgo_t8c3/Kconfig.sysbuild new file mode 100644 index 00000000000000..3a2d17ac5cfd06 --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/lilygo/ttgo_t8c3/Kconfig.ttgo_t8c3 b/boards/lilygo/ttgo_t8c3/Kconfig.ttgo_t8c3 new file mode 100644 index 00000000000000..60cd233a9b4a3c --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/Kconfig.ttgo_t8c3 @@ -0,0 +1,5 @@ +# Copyright 2024 Lothar Felten +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_TTGO_T8C3 + select SOC_ESP32C3_FX4 diff --git a/boards/lilygo/ttgo_t8c3/board.cmake b/boards/lilygo/ttgo_t8c3/board.cmake new file mode 100644 index 00000000000000..2f04d1fe8861ea --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/lilygo/ttgo_t8c3/board.yml b/boards/lilygo/ttgo_t8c3/board.yml new file mode 100644 index 00000000000000..8b1084a449353b --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/board.yml @@ -0,0 +1,5 @@ +board: + name: ttgo_t8c3 + vendor: lilygo + socs: + - name: esp32c3 diff --git a/boards/lilygo/ttgo_t8c3/doc/img/ttgo_t8c3.webp b/boards/lilygo/ttgo_t8c3/doc/img/ttgo_t8c3.webp new file mode 100644 index 00000000000000..ea11307794fac8 Binary files /dev/null and b/boards/lilygo/ttgo_t8c3/doc/img/ttgo_t8c3.webp differ diff --git a/boards/lilygo/ttgo_t8c3/doc/index.rst b/boards/lilygo/ttgo_t8c3/doc/index.rst new file mode 100644 index 00000000000000..73e092bb94ca0d --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/doc/index.rst @@ -0,0 +1,233 @@ +.. _ttgo_t8c3: + +Lilygo TTGO T8-C3 +################# + +Overview +******** + +Lilygo TTGO T8-C3 is an IoT mini development board based on the +Espressif ESP32-C3 WiFi/Bluetooth dual-mode chip. + +It features the following integrated components: + +- ESP32-C3 chip (160MHz single core, 400KB SRAM, Wi-Fi) +- on board antenna and IPEX connector +- USB-C connector for power and communication +- JST GH 2-pin battery connector +- LED + +.. figure:: img/ttgo_t8c3.webp + :align: center + :alt: TTGO T8-C3 + + Lilygo TTGO T8-C3 + +Functional Description +********************** +This board is based on the ESP32-C3 with 4MB of flash, WiFi and BLE support. It +has an USB-C port for programming and debugging, integrated battery charging +and an on-board antenna. The fitted U.FL external antenna connector can be +enabled by moving a 0-ohm resistor. + +Connections and IOs +=================== + +The TTGO T8-C3 board configuration supports the following hardware features: + ++-----------+------------+------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==================+ +| PMP | on-chip | arch/riscv | ++-----------+------------+------------------+ +| INTMTRX | on-chip | intc_esp32c3 | ++-----------+------------+------------------+ +| PINMUX | on-chip | pinctrl_esp32 | ++-----------+------------+------------------+ +| USB UART | on-chip | serial_esp32_usb | ++-----------+------------+------------------+ +| GPIO | on-chip | gpio_esp32 | ++-----------+------------+------------------+ +| UART | on-chip | uart_esp32 | ++-----------+------------+------------------+ +| I2C | on-chip | i2c_esp32 | ++-----------+------------+------------------+ +| SPI | on-chip | spi_esp32_spim | ++-----------+------------+------------------+ +| TWAI | on-chip | can_esp32_twai | ++-----------+------------+------------------+ + +Start Application Development +***************************** + +Before powering up your Lilygo TTGO T8-C3, please make sure that the board is in good +condition with no obvious signs of damage. + +System requirements +******************* + +Prerequisites +============= + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +Simple boot +=========== + +The board could be loaded using the single binary image, without 2nd stage bootloader. +It is the default option when building the application without additional configuration. + +.. note:: + + Simple boot does not provide any security features nor OTA updates. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be build (and flash) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + ``` + CONFIG_BOOTLOADER_MCUBOOT=y + ``` + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the ESP32-C3 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :app: samples/hello_world + :board: ttgo_t8c3 + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32-C3 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │   └── zephyr + │   ├── zephyr.elf + │   └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be build one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ttgo_t8c3 + :goals: build + +The usual ``flash`` target will work with the ``ttgo_t8c3`` board +configuration. Here is an example for the :ref:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ttgo_t8c3 + :goals: flash + +The default baud rate for the Lilygo TTGO T8-C3 is set to 1500000bps. If experiencing issues when flashing, +try using different values by using ``--esp-baud-rate `` option during +``west flash`` (e.g. ``west flash --esp-baud-rate 115200``). + +You can also open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! ttgo_t8c3 + +Sample applications +=================== + +The following samples will run out of the box on the TTGO T8-C3 board. + +To build the blinky sample: + +.. zephyr-app-commands:: + :tool: west + :app: samples/basic/blinky + :board: ttgo_t8c3 + :goals: build + +To build the bluetooth beacon sample: + +.. zephyr-app-commands:: + :tool: west + :app: samples/bluetooth/beacon + :board: ttgo_t8c3 + :goals: build + + +Related Documents +***************** +.. _`Lilygo TTGO T8-C3 schematic`: https://github.com/Xinyuan-LilyGO/T8-C3/blob/main/Schematic/T8-C3_V1.1.pdf +.. _`Lilygo github repo`: https://github.com/Xinyuan-LilyGo +.. _`Espressif ESP32-C3 datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf +.. _`Espressif ESP32-C3 technical reference manual`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf +.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/lilygo/ttgo_t8c3/support/openocd.cfg b/boards/lilygo/ttgo_t8c3/support/openocd.cfg new file mode 100644 index 00000000000000..02754ff2a73c1f --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/support/openocd.cfg @@ -0,0 +1,6 @@ +set ESP_RTOS none + +source [find interface/esp_usb_jtag.cfg] + +source [find target/esp32c3.cfg] +adapter_khz 5000 diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3-pinctrl.dtsi b/boards/lilygo/ttgo_t8c3/ttgo_t8c3-pinctrl.dtsi new file mode 100644 index 00000000000000..72cf16f3765aec --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3-pinctrl.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright 2024 Lothar Felten + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + ; + }; + /* GPIO6 is CS */ + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + twai_default: twai_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts new file mode 100644 index 00000000000000..a38f5777762ddb --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts @@ -0,0 +1,133 @@ +/* + * Copyright 2024 Lothar Felten + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "ttgo_t8c3-pinctrl.dtsi" + +/ { + model = "Lilygo TTGO T8-C3"; + compatible = "lilygo,ttgo-t8c3"; + + aliases { + led0 = &green_led; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; + zephyr,canbus = &twai; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + label = "Green - LED0"; + }; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&usb_serial { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&trng0 { + status = "okay"; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&twai { + status = "okay"; + pinctrl-0 = <&twai_default>; + pinctrl-names = "default"; +}; + +&wifi { + status = "okay"; +}; + +&esp32_bt_hci{ + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000F000>; + read-only; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 0x00100000>; + }; + + slot1_partition: partition@110000 { + label = "image-1"; + reg = <0x00110000 0x00100000>; + }; + + scratch_partition: partition@210000 { + label = "image-scratch"; + reg = <0x00210000 0x00040000>; + }; + + storage_partition: partition@250000 { + label = "storage"; + reg = <0x00250000 0x00006000>; + }; + }; +}; diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml new file mode 100644 index 00000000000000..e2fc320098a435 --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml @@ -0,0 +1,18 @@ +identifier: ttgo_t8c3 +name: TTGO T8C3 +type: mcu +arch: riscv +toolchain: + - zephyr +supported: + - gpio + - i2c + - spi + - uart + - watchdog + - can +testing: + ignore_tags: + - net + - bluetooth +vendor: lilygo diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig b/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig new file mode 100644 index 00000000000000..ef633ce56a18e2 --- /dev/null +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/luatos/esp32c3_luatos_core/Kconfig.defconfig b/boards/luatos/esp32c3_luatos_core/Kconfig.defconfig index 054ac2567296e2..f6ad1adaa1cb9a 100644 --- a/boards/luatos/esp32c3_luatos_core/Kconfig.defconfig +++ b/boards/luatos/esp32c3_luatos_core/Kconfig.defconfig @@ -9,7 +9,3 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 51200 if WIFI default 40960 if BT default 4096 - -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts index 00a6983355781f..cfdfd771d13ec7 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts @@ -15,5 +15,6 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dtsi b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dtsi index 904668716f6eff..c7b5b627547590 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dtsi +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dtsi @@ -130,3 +130,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/luatos/esp32s3_luatos_core/Kconfig.defconfig b/boards/luatos/esp32s3_luatos_core/Kconfig.defconfig index 093805f235b016..a14482e325d1c2 100644 --- a/boards/luatos/esp32s3_luatos_core/Kconfig.defconfig +++ b/boards/luatos/esp32s3_luatos_core/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32S3_LUATOS_CORE_ESP32S3_PROCPU || BOARD_ESP32S3_LUATOS_CORE_ESP32S3_PROCPU_USB if BOARD_ESP32S3_LUATOS_CORE_ESP32S3_APPCPU || BOARD_ESP32S3_LUATOS_CORE_ESP32S3_APPCPU_USB diff --git a/boards/luatos/esp32s3_luatos_core/doc/index.rst b/boards/luatos/esp32s3_luatos_core/doc/index.rst index 94bc0f685d3921..1acb1bb15c59d4 100644 --- a/boards/luatos/esp32s3_luatos_core/doc/index.rst +++ b/boards/luatos/esp32s3_luatos_core/doc/index.rst @@ -232,7 +232,7 @@ If CH343 chip is disabled, You need use the following command to build: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: esp32s3_luatos_core_usb/esp32s3/procpu + :board: esp32s3_luatos_core/esp32s3/procpu/usb :goals: build The usual ``flash`` target will work with the ``esp32s3_luatos_core`` board diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core.dtsi b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core.dtsi index 883280c7b3172e..60365fdcd65a36 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core.dtsi +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core.dtsi @@ -141,3 +141,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts index 8c44d0cebd7943..2a04d5680668a2 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts @@ -26,5 +26,6 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts index 0a707724f9f0a5..a4182a4ba80ae4 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts @@ -25,6 +25,7 @@ zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; + zephyr,bt_hci = &esp32_bt_hci; }; }; diff --git a/boards/m5stack/m5stack_atom_lite/Kconfig.defconfig b/boards/m5stack/m5stack_atom_lite/Kconfig.defconfig index d56d34b22d783c..2b223f5409bed4 100644 --- a/boards/m5stack/m5stack_atom_lite/Kconfig.defconfig +++ b/boards/m5stack/m5stack_atom_lite/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_M5STACK_ATOM_LITE_ESP32_PROCPU if BOARD_M5STACK_ATOM_LITE_ESP32_APPCPU diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts index e4fae9d25434df..3a8557f6794366 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts @@ -24,6 +24,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -180,3 +181,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/m5stack_atoms3/Kconfig.defconfig b/boards/m5stack/m5stack_atoms3/Kconfig.defconfig index c0dadaceeb4d1f..f3b59178417cea 100644 --- a/boards/m5stack/m5stack_atoms3/Kconfig.defconfig +++ b/boards/m5stack/m5stack_atoms3/Kconfig.defconfig @@ -14,10 +14,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_M5STACK_ATOMS3_ESP32S3_PROCPU if BOARD_M5STACK_ATOMS3_ESP32S3_APPCPU diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts index aa80e0b8356733..dd20fb00a8d9e0 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts @@ -9,6 +9,7 @@ #include "m5stack_atoms3-pinctrl.dtsi" #include "grove_connectors.dtsi" #include +#include / { model = "M5Stack AtomS3 PROCPU"; @@ -21,6 +22,7 @@ zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,display = &st7789v; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -48,6 +50,45 @@ regulator-boot-on; }; + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi2>; + dc-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; /* G33 */ + reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* G34 */ + write-only; + #address-cells = <1>; + #size-cells = <0>; + + st7789v: st7789v@0 { + compatible = "sitronix,st7789v"; + reg = <0>; + mipi-max-frequency = <27000000>; + + width = <128>; + height = <128>; + x-offset = <2>; + y-offset = <1>; + + vcom = <0x28>; + gctrl = <0x35>; + vrhs = <0x10>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x55>; + lcm = <0x0c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 00]; + pwctrl1-param = [a4 a1]; + pvgam-param = [d0 00 02 07 0a 28 32 44 42 06 0e 12 14 17]; + nvgam-param = [d0 00 02 07 0a 28 31 54 47 0e 1c 17 1b 1e]; + ram-param = [00 E0]; + rgb-param = [40 02 14]; + mipi-mode = ; + }; + + }; + }; &usb_serial { @@ -91,36 +132,6 @@ status = "okay"; pinctrl-0 = <&spim2_default>; pinctrl-names = "default"; - - st7789v: st7789v@0 { - compatible = "sitronix,st7789v"; - reg = <0>; - spi-max-frequency = <27000000>; - cmd-data-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; /* G33 */ - reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* G34 */ - - width = <128>; - height = <128>; - x-offset = <2>; - y-offset = <1>; - - vcom = <0x28>; - gctrl = <0x35>; - vrhs = <0x10>; - vdvs = <0x20>; - mdac = <0x00>; - gamma = <0x01>; - colmod = <0x55>; - lcm = <0x0c>; - porch-param = [0c 0c 00 33 33]; - cmd2en-param = [5a 69 02 00]; - pwctrl1-param = [a4 a1]; - pvgam-param = [d0 00 02 07 0a 28 32 44 42 06 0e 12 14 17]; - nvgam-param = [d0 00 02 07 0a 28 31 54 47 0e 1c 17 1b 1e]; - ram-param = [00 E0]; - rgb-param = [40 02 14]; - }; - }; &gpio0 { @@ -177,3 +188,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/m5stack_atoms3_lite/Kconfig.defconfig b/boards/m5stack/m5stack_atoms3_lite/Kconfig.defconfig index 8039b4762cde2a..f0f262cd1f3a65 100644 --- a/boards/m5stack/m5stack_atoms3_lite/Kconfig.defconfig +++ b/boards/m5stack/m5stack_atoms3_lite/Kconfig.defconfig @@ -14,10 +14,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD config KERNEL_MEM_POOL default y -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_M5STACK_ATOMS3_LITE_ESP32S3_PROCPU if BOARD_M5STACK_ATOMS3_LITE_ESP32S3_APPCPU diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts index 9f2cc845558586..166ee2014ca01c 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts @@ -22,6 +22,7 @@ zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -145,3 +146,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/m5stack_core2/Kconfig.defconfig b/boards/m5stack/m5stack_core2/Kconfig.defconfig index 2c0a21ef88da25..fd9614d6cbbfb8 100644 --- a/boards/m5stack/m5stack_core2/Kconfig.defconfig +++ b/boards/m5stack/m5stack_core2/Kconfig.defconfig @@ -15,10 +15,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD config KERNEL_MEM_POOL default y -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - config GPIO_HOGS_INIT_PRIORITY default 70 diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts index fec843884ca835..841dcdf38bef11 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts +++ b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts @@ -34,6 +34,7 @@ zephyr,display = &ili9342c; zephyr,code-partition = &slot0_partition; zephyr,rtc = &pfc8563_rtc; + zephyr,bt-hci = &esp32_bt_hci; }; leds { @@ -283,3 +284,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/m5stack_stamps3/Kconfig.defconfig b/boards/m5stack/m5stack_stamps3/Kconfig.defconfig index 70493b8d4751db..903059dffbc8a5 100644 --- a/boards/m5stack/m5stack_stamps3/Kconfig.defconfig +++ b/boards/m5stack/m5stack_stamps3/Kconfig.defconfig @@ -14,10 +14,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD config KERNEL_MEM_POOL default y -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_M5STACK_STAMPS3_ESP32S3_PROCPU if BOARD_M5STACK_STAMPS3_ESP32S3_APPCPU diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts index 522518f7e077ce..9e231fba57f0db 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -185,3 +186,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/m5stickc_plus/Kconfig.defconfig b/boards/m5stack/m5stickc_plus/Kconfig.defconfig index aea1b614a01ac2..a6b957227be56a 100644 --- a/boards/m5stack/m5stickc_plus/Kconfig.defconfig +++ b/boards/m5stack/m5stickc_plus/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - config GPIO_HOGS_INIT_PRIORITY default 70 diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts index b397c7d5b05fda..28779d87ecb4ba 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts @@ -9,6 +9,7 @@ #include "m5stickc_plus-pinctrl.dtsi" #include #include +#include / { model = "M5StickC Plus PROCPU"; @@ -33,6 +34,7 @@ zephyr,code-partition = &slot0_partition; zephyr,rtc = &bm8563; zephyr,display = &st7789v; + zephyr,bt-hci = &esp32_bt_hci; }; leds { @@ -58,6 +60,44 @@ zephyr,code = ; }; }; + + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi3>; + dc-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + write-only; + #address-cells = <1>; + #size-cells = <0>; + + st7789v: st7789v@0 { + compatible = "sitronix,st7789v"; + reg = <0>; + mipi-max-frequency = <20000000>; + + width = <135>; + height = <240>; + x-offset = <53>; + y-offset = <40>; + + vcom = <0x28>; + gctrl = <0x35>; + vrhs = <0x10>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x55>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 00]; + pwctrl1-param = [a4 a1]; + pvgam-param = [d0 00 02 07 0a 28 32 44 42 06 0e 12 14 17]; + nvgam-param = [d0 00 02 07 0a 28 31 54 47 0e 1c 17 1b 1e]; + ram-param = [00 F0]; + rgb-param = [40 02 14]; + mipi-mode = ; + }; + }; }; &uart0 { @@ -152,34 +192,6 @@ status = "okay"; pinctrl-0 = <&spim3_default>; pinctrl-names = "default"; - st7789v: st7789v@0 { - compatible = "sitronix,st7789v"; - reg = <0>; - spi-max-frequency = <20000000>; - cmd-data-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; - reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; - - width = <135>; - height = <240>; - x-offset = <53>; - y-offset = <40>; - - vcom = <0x28>; - gctrl = <0x35>; - vrhs = <0x10>; - vdvs = <0x20>; - mdac = <0x00>; - gamma = <0x01>; - colmod = <0x55>; - lcm = <0x2c>; - porch-param = [0c 0c 00 33 33]; - cmd2en-param = [5a 69 02 00]; - pwctrl1-param = [a4 a1]; - pvgam-param = [d0 00 02 07 0a 28 32 44 42 06 0e 12 14 17]; - nvgam-param = [d0 00 02 07 0a 28 31 54 47 0e 1c 17 1b 1e]; - ram-param = [00 F0]; - rgb-param = [40 02 14]; - }; }; &timer0 { @@ -240,3 +252,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/m5stack/stamp_c3/Kconfig.defconfig b/boards/m5stack/stamp_c3/Kconfig.defconfig index 4ce7fe02e12004..dcc3a4225487de 100644 --- a/boards/m5stack/stamp_c3/Kconfig.defconfig +++ b/boards/m5stack/stamp_c3/Kconfig.defconfig @@ -9,11 +9,3 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 51200 if WIFI default 40960 if BT default 4096 - -if BT - -choice BT_HCI_BUS_TYPE - default BT_ESP32 -endchoice - -endif # BT diff --git a/boards/m5stack/stamp_c3/stamp_c3.dts b/boards/m5stack/stamp_c3/stamp_c3.dts index e9d519a2a5f8f9..ef026e94454414 100644 --- a/boards/m5stack/stamp_c3/stamp_c3.dts +++ b/boards/m5stack/stamp_c3/stamp_c3.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -129,3 +130,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.dts b/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.dts index 2439b0c2aca0b8..e405794d79573a 100644 --- a/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.dts +++ b/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.dts @@ -82,7 +82,6 @@ red-pwm-led = &pwm_led1_red; blue-pwm-led = &pwm_led2_blue; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/native/native_posix/Kconfig.defconfig b/boards/native/native_posix/Kconfig.defconfig index 6db6f0aee1b5a9..70d597b4192e00 100644 --- a/boards/native/native_posix/Kconfig.defconfig +++ b/boards/native/native_posix/Kconfig.defconfig @@ -22,11 +22,6 @@ config ETH_NATIVE_POSIX endif # NETWORKING -choice BT_HCI_BUS_TYPE - default BT_USERCHAN - depends on BT_HCI -endchoice - if CONSOLE config POSIX_ARCH_CONSOLE diff --git a/boards/native/native_sim/Kconfig.defconfig b/boards/native/native_sim/Kconfig.defconfig index 02d6b1d6465998..0cb80bbcf45246 100644 --- a/boards/native/native_sim/Kconfig.defconfig +++ b/boards/native/native_sim/Kconfig.defconfig @@ -22,11 +22,6 @@ config ETH_NATIVE_POSIX endif # NETWORKING -choice BT_HCI_BUS_TYPE - default BT_USERCHAN - depends on BT_HCI -endchoice - if CONSOLE config POSIX_ARCH_CONSOLE diff --git a/boards/native/native_sim/native_sim.dts b/boards/native/native_sim/native_sim.dts index 87d6297f7491d3..95b5ee5c065226 100644 --- a/boards/native/native_sim/native_sim.dts +++ b/boards/native/native_sim/native_sim.dts @@ -24,6 +24,7 @@ zephyr,display = &sdl_dc; zephyr,canbus = &can_loopback0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_userchan; }; aliases { @@ -218,4 +219,9 @@ #dma-cells = <1>; stack-size = <4096>; }; + + bt_hci_userchan: bt_hci_userchan { + compatible = "zephyr,bt-hci-userchan"; + status = "okay"; + }; }; diff --git a/boards/native/nrf_bsim/Kconfig.defconfig b/boards/native/nrf_bsim/Kconfig.defconfig index 81f90836b543b6..2ff17802977fdc 100644 --- a/boards/native/nrf_bsim/Kconfig.defconfig +++ b/boards/native/nrf_bsim/Kconfig.defconfig @@ -39,7 +39,7 @@ config SYS_CLOCK_TICKS_PER_SEC default 32768 config BT_CTLR - default y if BOARD_NRF52_BSIM || BOARD_NRF5340BSIM_NRF5340_CPUNET + default y if BOARD_NRF52_BSIM || BOARD_NRF5340BSIM_NRF5340_CPUNET || BOARD_NRF54L15BSIM_NRF54L15_CPUAPP depends on BT config HEAP_MEM_POOL_ADD_SIZE_BOARD @@ -60,9 +60,8 @@ if BOARD_NRF5340BSIM_NRF5340_CPUAPP config IPC_SERVICE_BACKEND_RPMSG_SHMEM_RESET default y if IPC_SERVICE_BACKEND_RPMSG -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC -endchoice +config BT_HCI_IPC + default y if BT endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis.c b/boards/native/nrf_bsim/common/cmsis/cmsis.c index 1694bc1da3406a..e80aea6b4ff607 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis.c +++ b/boards/native/nrf_bsim/common/cmsis/cmsis.c @@ -35,6 +35,11 @@ void NVIC_EnableIRQ(IRQn_Type IRQn) hw_irq_ctrl_enable_irq(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); } +uint32_t NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return hw_irq_ctrl_is_irq_enabled(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn); +} + void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_MCU_N, IRQn, priority); diff --git a/boards/native/nrf_bsim/doc/nrf54l15bsim.rst b/boards/native/nrf_bsim/doc/nrf54l15bsim.rst index bb113510c4a0aa..8c0b2fb64f01db 100644 --- a/boards/native/nrf_bsim/doc/nrf54l15bsim.rst +++ b/boards/native/nrf_bsim/doc/nrf54l15bsim.rst @@ -32,11 +32,12 @@ on the simulated nRF54L15 SOC. .. warning:: This target is experimental, and even though it includes models of the RADIO, it does not yet - include models of the AAR, CCM, ECB or CLOCK peripherals, so the BLE and 802.15.4 stacks cannot - be run on it yet. + include models of the AAR, CCM or ECB peripherals, so the BLE and 802.15.4 stacks can only be + run without encryption or privacy features so far. This boards include models of some of the nRF54L15 SOC peripherals: +* CLOCK (Clock control) * DPPI (Distributed Programmable Peripheral Interconnect) * EGU (Event Generator Unit) * FICR (Factory Information Configuration Registers) diff --git a/boards/native/nrf_bsim/nrf52_bsim.dts b/boards/native/nrf_bsim/nrf52_bsim.dts index bb6321c4d53104..ad3ac181ae7d64 100644 --- a/boards/native/nrf_bsim/nrf52_bsim.dts +++ b/boards/native/nrf_bsim/nrf52_bsim.dts @@ -38,8 +38,6 @@ zephyr,flash = &flash0; /* UART used by the BT controller UART HCI driver by default: */ zephyr,bt-c2h-uart = &uart1; - /* UART used by the BT host UART HCI driver by default: */ - zephyr,bt-uart = &uart1; }; soc { @@ -117,4 +115,9 @@ pinctrl-1 = <&uart1_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; diff --git a/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index aa1f235e16e589..11073e6182de3d 100644 --- a/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -43,7 +43,7 @@ chosen { zephyr,entropy = &rng_hci; zephyr,flash = &flash0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts index ec34448017e5b1..bdcd1f2300bc49 100644 --- a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts +++ b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts @@ -59,7 +59,6 @@ /delete-node/ watchdog@109000; /delete-node/ gpio@10a000; /delete-node/ gpiote@10c000; - /delete-node/ clock@10e000; }; /delete-node/ spu@50003000; /delete-node/ gpiote@5000d000; @@ -96,6 +95,11 @@ }; &radio { + status = "okay"; /* This feature is not yet supported by the RADIO model */ /delete-property/ dfe-supported; }; + +&clock { + status = "okay"; +}; diff --git a/boards/nordic/nrf21540dk/doc/index.rst b/boards/nordic/nrf21540dk/doc/index.rst index fdc726056360dc..8ea583edb1a09f 100644 --- a/boards/nordic/nrf21540dk/doc/index.rst +++ b/boards/nordic/nrf21540dk/doc/index.rst @@ -32,7 +32,7 @@ The CPU provides support for the following devices: nRF21540 DK (Credit: Nordic Semiconductor) More information about the board can be found at the `nRF21540 website`_. -The `Nordic Semiconductor Infocenter`_ contains the processor's and front end +`nRF21540 Product Specification`_ contains the processor's and front end module's information and the datasheet. Hardware @@ -83,7 +83,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF52840 Product Specification`_ and `Nordic Semiconductor Infocenter`_ +See `nRF52840 Product Specification`_ and `nRF21540 DK Hardware guide`_ for a complete list of nRF21540 Development Kit board hardware features. Connections and IOs @@ -229,8 +229,8 @@ References .. target-notes:: -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF21540 DK Hardware guide: https://docs.nordicsemi.com/bundle/ug_nrf21540_dk/page/UG/nrf21540_DK/intro.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html .. _nRF21540 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF21540 -.. _nRF52840 Product Specification: http://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf -.. _nRF21540 Product Specification: http://infocenter.nordicsemi.com/pdf/nRF21540_PS_v1.0.pdf +.. _nRF52840 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf52840/page/keyfeatures_html5.html +.. _nRF21540 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf21540/page/keyfeatures_html5.html diff --git a/boards/nordic/nrf51dk/doc/index.rst b/boards/nordic/nrf51dk/doc/index.rst index b97e70e9613195..c905dc0f4764b1 100644 --- a/boards/nordic/nrf51dk/doc/index.rst +++ b/boards/nordic/nrf51dk/doc/index.rst @@ -29,7 +29,7 @@ Semiconductor nRF51822 ARM Cortex-M0 CPU and the following devices: nRF51 DK (Credit: Nordic Semiconductor) More information about the board can be found at the -`nRF51 DK website`_. The `Nordic Semiconductor Infocenter`_ +`nRF51 DK website`_. The `nRF51 Development Kit User Guide`_ contains the processor's information and the datasheet. @@ -75,7 +75,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF51 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF51 DK website`_ and `nRF51 Development Kit User Guide`_ for a complete list of nRF51 Development Kit board hardware features. Connections and IOs @@ -156,4 +156,4 @@ References .. target-notes:: .. _nRF51 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF51-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF51 Development Kit User Guide: https://docs.nordicsemi.com/bundle/nRF51-Series-DK/resource/nRF51_Development_Kit_User_Guide_v1.2.pdf diff --git a/boards/nordic/nrf51dongle/doc/index.rst b/boards/nordic/nrf51dongle/doc/index.rst index 720ff3a59861d9..d8183371654a83 100644 --- a/boards/nordic/nrf51dongle/doc/index.rst +++ b/boards/nordic/nrf51dongle/doc/index.rst @@ -29,7 +29,7 @@ Semiconductor nRF51822 ARM Cortex-M0 CPU and the following devices: nRF51 Dongle (Credit: Nordic Semiconductor) More information about the board can be found at the -`nRF51 Dongle website`_. The `Nordic Semiconductor Infocenter`_ +`nRF51 Dongle website`_. The `Nordic Semiconductor TechDocs`_ contains the processor's information and the datasheet. @@ -75,7 +75,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF51 Dongle website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF51 Dongle website`_ and `Nordic Semiconductor TechDocs`_ for a complete list of nRF51 Dongle hardware features. Connections and IOs @@ -141,4 +141,4 @@ References .. target-notes:: .. _nRF51 Dongle website: http://www.nordicsemi.com/eng/Products/nRF51-Dongle -.. _Nordic Semiconductor Infocenter: http://infocenter.nordicsemi.com/ +.. _Nordic Semiconductor TechDocs: https://docs.nordicsemi.com/ diff --git a/boards/nordic/nrf52833dk/doc/index.rst b/boards/nordic/nrf52833dk/doc/index.rst index d182053d506475..027f471586fed2 100644 --- a/boards/nordic/nrf52833dk/doc/index.rst +++ b/boards/nordic/nrf52833dk/doc/index.rst @@ -27,7 +27,7 @@ the following devices: * :abbr:`WDT (Watchdog Timer)` More information about the board can be found at the -`nRF52833 DK website`_. The `Nordic Semiconductor Infocenter`_ +`nRF52833 DK website`_. `nRF52833 Product Specification`_ contains the processor's information and the datasheet. @@ -80,7 +80,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF52833 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF52833 DK website`_ and `nRF52833 DK Hardware guide`_ for a complete list of nRF52833 Development Kit board hardware features. Connections and IOs @@ -212,9 +212,9 @@ References .. target-notes:: .. _nRF52833 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF52833 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf52833/page/keyfeatures_html5.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _nRF52833 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52833_OPS_v0.7.pdf +.. _nRF52833 DK Hardware guide: https://docs.nordicsemi.com/bundle/ug_nrf52833_dk/page/UG/dk/intro.html .. _nrf52833dk_nrf52820: diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml index b2d59ed4e4157c..62e323927982e3 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml @@ -10,6 +10,7 @@ ram: 32 flash: 256 supported: - usb_device + - usbd - ble - gpio - watchdog diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml index cd3ed1b54d2349..8ab244fd648b1d 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml @@ -14,6 +14,7 @@ supported: - arduino_i2c - arduino_spi - usb_device + - usbd - ble - gpio - pwm diff --git a/boards/nordic/nrf52840dk/doc/index.rst b/boards/nordic/nrf52840dk/doc/index.rst index 953c86fd19022b..faa7f07d5c931c 100644 --- a/boards/nordic/nrf52840dk/doc/index.rst +++ b/boards/nordic/nrf52840dk/doc/index.rst @@ -32,7 +32,7 @@ Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU and the following devices: nRF52840 DK (Credit: Nordic Semiconductor) More information about the board can be found at the `nRF52840 DK website`_. -The `Nordic Semiconductor Infocenter`_ contains the processor's information +`nRF52840 Product Specification`_ contains the processor's information and the datasheet. @@ -84,7 +84,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF52840 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF52840 DK website`_ and `nRF52840 DK Hardware guide`_ for a complete list of nRF52840 Development Kit board hardware features. Connections and IOs @@ -244,7 +244,7 @@ References .. target-notes:: .. _nRF52840 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF52840 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf52840/page/keyfeatures_html5.html +.. _nRF52840 DK Hardware guide: https://docs.nordicsemi.com/bundle/ug_nrf52840_dk/page/UG/dk/intro.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _nRF52840 Product Specification: http://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf .. _nRF52811 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811 diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.dts b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.dts index 60c3ecf55a127a..2bcffc80b0ab99 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.dts +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.dts @@ -131,7 +131,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml index 09723d66d5fde9..313a975e6d04f7 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml @@ -22,6 +22,7 @@ supported: - pwm - spi - usb_device + - usbd - watchdog - netif:openthread vendor: nordic diff --git a/boards/nordic/nrf52840dongle/doc/index.rst b/boards/nordic/nrf52840dongle/doc/index.rst index 235b0ea4b35b4f..9aa6f74811f3ed 100644 --- a/boards/nordic/nrf52840dongle/doc/index.rst +++ b/boards/nordic/nrf52840dongle/doc/index.rst @@ -31,7 +31,7 @@ Semiconductor nRF52840 ARM Cortex-M4F CPU and the following devices: nRF52840 Dongle More information about the board can be found at the -`nRF52840 Dongle website`_. The `Nordic Semiconductor Infocenter`_ +`nRF52840 Dongle website`_. The `nRF52840 Dongle guide`_ contains the processor's information and the datasheet. @@ -82,7 +82,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF52840 Dongle website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF52840 Dongle website`_ and `nRF52840 Dongle Hardware description`_ for a complete list of nRF52840 Dongle board hardware features. Connections and IOs @@ -334,12 +334,12 @@ References .. _nRF52840 Dongle website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle -.. _Nordic Semiconductor Infocenter: - https://infocenter.nordicsemi.com +.. _nRF52840 Dongle guide: https://docs.nordicsemi.com/bundle/ug_nrf52840_dk/page/UG/dk/intro.html +.. _nRF52840 Dongle Hardware description: https://docs.nordicsemi.com/bundle/ug_nrf52840_dongle/page/UG/nrf52840_Dongle/hw_description.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html .. _Nordic Semiconductor USB DFU: - https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Fsdk_app_serial_dfu_bootloader.html + https://docs.nordicsemi.com/bundle/sdk_nrf5_v17.1.0/page/sdk_app_serial_dfu_bootloader.html .. _nrfutil: https://github.com/NordicSemiconductor/pc-nrfutil .. _MCUboot: diff --git a/boards/nordic/nrf52dk/doc/index.rst b/boards/nordic/nrf52dk/doc/index.rst index 07f241eac1efed..4ebcac44e6c253 100644 --- a/boards/nordic/nrf52dk/doc/index.rst +++ b/boards/nordic/nrf52dk/doc/index.rst @@ -32,7 +32,7 @@ the following devices: nRF52 DK (Credit: Nordic Semiconductor) More information about the board can be found at the -`nRF52 DK website`_. The `Nordic Semiconductor Infocenter`_ +`nRF52 DK website`_. `nRF52832 Product Specification`_ contains the processor's information and the datasheet. @@ -82,7 +82,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `nRF52 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF52 DK website`_ and `nRF52832 Product Specification`_ for a complete list of nRF52 Development Kit board hardware features. Connections and IOs @@ -403,7 +403,7 @@ References .. target-notes:: .. _nRF52 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF52832 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf52832/page/nrf52832_ps.html .. _nrf52dk_nrf52805: diff --git a/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig b/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig index c8d07e2adfab8c..62316a2aeb0965 100644 --- a/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig +++ b/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig @@ -53,9 +53,8 @@ config FLASH_LOAD_SIZE endif # BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP_NS -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/nordic/nrf5340_audio_dk/doc/index.rst b/boards/nordic/nrf5340_audio_dk/doc/index.rst index 558f995be66257..f7b23c0d6de635 100644 --- a/boards/nordic/nrf5340_audio_dk/doc/index.rst +++ b/boards/nordic/nrf5340_audio_dk/doc/index.rst @@ -35,7 +35,7 @@ The nRF5340 Audio DK comes with the following hardware features: :align: center :alt: nRF5340 DK -More information about the board can be found at the `nRF5340 Audio DK website`_. The `Nordic Semiconductor Infocenter`_ +More information about the board can be found at the `nRF5340 Audio DK website`_. The `nRF5340 Audio DK hardware guide`_ contains the processor's information and the datasheet. nRF5340 SoC @@ -53,13 +53,13 @@ The ``nrf5340_audio_dk/nrf5340/cpuapp`` build target provides support for the ap core on the nRF5340 SoC. The ``nrf5340_audio_dk/nrf5340/cpunet`` build target provides support for the network core on the nRF5340 SoC. -The `Nordic Semiconductor Infocenter`_ contains the processor's information and +The `nRF5340 Audio DK hardware guide`_ contains the processor's information and the datasheet. Supported Features ================== -See :ref:`nrf5340dk_nrf5340` and `Nordic Semiconductor Infocenter`_ +See :ref:`nrf5340dk_nrf5340` and `nRF5340 Audio DK hardware guide`_ for a complete list of nRF5340 Audio DK board hardware features. @@ -106,4 +106,4 @@ References .. _nRF5340 Audio DK website: https://www.nordicsemi.com/Products/Development-hardware/nrf5340-audio-dk -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF5340 Audio DK hardware guide: https://docs.nordicsemi.com/bundle/ug_nrf5340_audio/page/UG/nrf5340_audio/intro.html diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi index 8504e23ed7e507..7f62b862639457 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi @@ -13,7 +13,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; watchdog0 = &wdt0; }; diff --git a/boards/nordic/nrf5340dk/Kconfig.defconfig b/boards/nordic/nrf5340dk/Kconfig.defconfig index 67d7c7db9d553e..972d8433c90162 100644 --- a/boards/nordic/nrf5340dk/Kconfig.defconfig +++ b/boards/nordic/nrf5340dk/Kconfig.defconfig @@ -60,9 +60,8 @@ config MBOX_NRFX_IPC if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/nordic/nrf5340dk/doc/index.rst b/boards/nordic/nrf5340dk/doc/index.rst index f8ce8a2a84b8af..e933f43bdb4b5f 100644 --- a/boards/nordic/nrf5340dk/doc/index.rst +++ b/boards/nordic/nrf5340dk/doc/index.rst @@ -48,7 +48,7 @@ nRF5340 SoC provides support for the following devices: More information about the board can be found at the `nRF5340 DK website`_. -The `Nordic Semiconductor Infocenter`_ +The `nRF5340 DK Product Specification`_ contains the processor's information and the datasheet. @@ -132,7 +132,7 @@ hardware features: +-----------+------------+----------------------+ Other hardware features have not been enabled yet for this board. -See `Nordic Semiconductor Infocenter`_ +See `nRF5340 DK Product Specification`_ for a complete list of nRF5340 DK board hardware features. Connections and IOs @@ -326,5 +326,5 @@ References https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau .. _nRF5340 DK website: https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF5340-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF5340 DK Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf5340/page/keyfeatures_html5.html .. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi b/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi index 70ba32524500eb..df46b7c64277c2 100644 --- a/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi +++ b/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; @@ -133,7 +133,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml index c1e36526e1fec0..50ed4733871437 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml @@ -15,6 +15,7 @@ supported: - pwm - watchdog - usb_device + - usbd - netif:openthread - gpio - spi diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml index 664378db8872ee..4c366d2f363f5d 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml @@ -13,6 +13,7 @@ supported: - pwm - watchdog - usb_device + - usbd - netif:openthread - gpio - spi diff --git a/boards/nordic/nrf54h20dk/Kconfig.defconfig b/boards/nordic/nrf54h20dk/Kconfig.defconfig index 74fe93905ac335..e37975f96adf47 100644 --- a/boards/nordic/nrf54h20dk/Kconfig.defconfig +++ b/boards/nordic/nrf54h20dk/Kconfig.defconfig @@ -3,9 +3,8 @@ if BOARD_NRF54H20DK_NRF54H20_CPUAPP -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT endif # BOARD_NRF54H20DK_NRF54H20_CPUAPP diff --git a/boards/nordic/nrf54h20dk/board.cmake b/boards/nordic/nrf54h20dk/board.cmake index 6361f7fe7b4a0d..0c8376c1714e12 100644 --- a/boards/nordic/nrf54h20dk/board.cmake +++ b/boards/nordic/nrf54h20dk/board.cmake @@ -3,13 +3,12 @@ include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD) - if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD) - set( - JLINK_TOOL_OPT - "-jlinkscriptfile ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpurad.JLinkScript" - ) + if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP) + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuapp.JLinkScript) + else() + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpurad.JLinkScript) endif() - board_runner_args(jlink "--device=CORTEX-M33" "--speed=4000" "--tool-opt=${JLINK_TOOL_OPT}") + board_runner_args(jlink "--device=CORTEX-M33" "--speed=4000" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) endif() diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index f67ddfb80bf48e..834448f33e4cc1 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include / { reserved-memory { @@ -92,6 +93,27 @@ }; }; + ram21_region: memory@2f890000 { + compatible = "nordic,owned-memory"; + status = "disabled"; + reg = <0x2f890000 DT_SIZE_K(64)>; + perm-read; + perm-write; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2f890000 0x10000>; + + dma_fast_region: memory@8000 { + compatible = "zephyr,memory-region"; + reg = <0x8000 DT_SIZE_K(16)>; + status = "disabled"; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM21"; + zephyr,memory-attr = <( DT_MEM_CACHEABLE )>; + }; + }; + cpuppr_ram3x_region: memory@2fc00000 { compatible = "nordic,owned-memory"; reg = <0x2fc00000 DT_SIZE_K(64)>; @@ -170,11 +192,11 @@ #size-cells = <1>; cpuapp_slot0_partition: partition@a6000 { - reg = <0xa6000 DT_SIZE_K(512)>; + reg = <0xa6000 DT_SIZE_K(296)>; }; - cpuppr_code_partition: partition@126000 { - reg = <0x126000 DT_SIZE_K(64)>; + cpuppr_code_partition: partition@f0000 { + reg = <0xf0000 DT_SIZE_K(64)>; }; }; @@ -187,8 +209,12 @@ #address-cells = <1>; #size-cells = <1>; - storage_partition: partition@136000 { - reg = <0x136000 DT_SIZE_K(24)>; + dfu_partition: partition@100000 { + reg = < 0x100000 DT_SIZE_K(892) >; + }; + + storage_partition: partition@1df000 { + reg = < 0x1df000 DT_SIZE_K(24) >; }; }; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi index efa58b2ffb59be..da3effb5af8fe6 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi @@ -66,4 +66,17 @@ ; }; }; + + /omit-if-no-ref/ pwm130_default: pwm130_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm130_sleep: pwm130_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 2c5d61a27e8bba..bf14d775f7218b 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -25,7 +25,7 @@ zephyr,sram = &cpuapp_data; zephyr,shell-uart = &uart136; zephyr,ieee802154 = &cpuapp_ieee802154; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,canbus = &can120; }; @@ -35,6 +35,8 @@ led1 = &led1; led2 = &led2; led3 = &led3; + resetinfo = &cpuapp_resetinfo; + pwm-led0 = &pwm_led2; sw0 = &button0; sw1 = &button1; sw2 = &button2; @@ -94,6 +96,18 @@ label = "Green LED 3"; }; }; + + pwmleds { + compatible = "pwm-leds"; + /* + * LEDs are connected to GPIO Port 9 - pins 0-3. There is no valid hardware + * configuration to pass PWM signal on pis 0 and 1. First valid config is P9.2. + * Signal on PWM130's channel 0 can be passed directly on GPIO Port 9 pin 2. + */ + pwm_led2: pwm_led_2 { + pwms = <&pwm130 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; }; &cpuapp_ram0x_region { @@ -108,6 +122,10 @@ status = "okay"; }; +&ram21_region { + status = "okay"; +}; + &cpuapp_bellboard { status = "okay"; interrupts = <96 NRF_DEFAULT_IRQ_PRIORITY>; @@ -137,6 +155,11 @@ ipc0: &cpuapp_cpurad_ipc { rx-region = <&cpurad_cpuapp_ipc_shm>; tx-blocks = <32>; rx-blocks = <32>; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; &cpuapp_cpusys_ipc { @@ -156,6 +179,10 @@ ipc0: &cpuapp_cpurad_ipc { status = "okay"; }; +&dma_fast_region { + status = "okay"; +}; + &cpuapp_rx_partitions { status = "okay"; }; @@ -252,3 +279,16 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&can120_default>; pinctrl-names = "default"; }; + +&pwm130 { + status = "okay"; + pinctrl-0 = <&pwm130_default>; + pinctrl-1 = <&pwm130_sleep>; + pinctrl-names = "default", "sleep"; + memory-regions = <&cpuapp_dma_region>; +}; + +&adc { + memory-regions = <&cpuapp_dma_region>; + status = "okay"; +}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.yaml index f33351c61afe1f..560a4cfa294bce 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.yaml @@ -10,12 +10,13 @@ toolchain: - xtools - zephyr ram: 256 -flash: 512 +flash: 296 supported: - can - counter - gpio + - i2c - pwm - spi - watchdog - - usb_device + - usbd diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr.yaml index 190d835f580907..af81ae6e28edf6 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuppr.yaml @@ -12,3 +12,4 @@ flash: 62 supported: - gpio - pwm + - spi diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index f8aff548436c8f..8bba620c456393 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -31,6 +31,7 @@ }; aliases { ipc-to-cpusys = &cpurad_cpusys_ipc; + resetinfo = &cpurad_resetinfo; }; }; diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript new file mode 100644 index 00000000000000..ffa1beed1ed652 --- /dev/null +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript @@ -0,0 +1,41 @@ +// Debug Halting Control and Status Register +__constant U32 _DHCSR_ADDR = 0xE000EDF0; +__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); +__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); +__constant U32 _DHCSR_C_HALT = (1 << 1); + +// Debug Exception and Monitor Control Register +__constant U32 _DEMCR_ADDR = 0xE000EDFC; +__constant U32 _DEMCR_VC_CORERESET = (1 << 0); +__constant U32 _DEMCR_TRCENA = (1 << 24); + +// CPU wait enable register +__constant U32 _CPUCONF_CPUWAIT_ADDR = 0x5201150C; + +int ResetTarget(void) { + // ADAC reset + JLINK_CORESIGHT_WriteDP(2, 0x04000010); + JLINK_CORESIGHT_WriteAP(0, 0xA3030000); + JLINK_CORESIGHT_WriteAP(0, 0x00000004); + JLINK_CORESIGHT_WriteAP(0, 0x01020000); + + JLINK_SYS_Sleep(100); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + + // Halt the CPU + JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); + + // Set vector catch on reset (to halt the CPU immediately after reset) + JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + + // Disable CPU wait + JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + + // Clear vector catch stuff + JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); + + return 0; +} diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript index 2fb7e32302e236..2f1802801c11c1 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript @@ -1,4 +1,48 @@ -void ConfigTargetSettings(void) { - JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); - CORESIGHT_IndexAHBAPToUse = 1; +// Debug Halting Control and Status Register +__constant U32 _DHCSR_ADDR = 0xE000EDF0; +__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); +__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); +__constant U32 _DHCSR_C_HALT = (1 << 1); + +// Debug Exception and Monitor Control Register +__constant U32 _DEMCR_ADDR = 0xE000EDFC; +__constant U32 _DEMCR_VC_CORERESET = (1 << 0); +__constant U32 _DEMCR_TRCENA = (1 << 24); + +// CPU wait enable register +__constant U32 _CPUCONF_CPUWAIT_ADDR = 0x5301150C; + +int ConfigTargetSettings(void) { + JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); + CORESIGHT_IndexAHBAPToUse = 1; + + return 0; +} + +int ResetTarget(void) { + // ADAC reset + JLINK_CORESIGHT_WriteDP(2, 0x04000010); + JLINK_CORESIGHT_WriteAP(0, 0xA3030000); + JLINK_CORESIGHT_WriteAP(0, 0x00000004); + JLINK_CORESIGHT_WriteAP(0, 0x01030000); + + JLINK_SYS_Sleep(100); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + JLINK_CORESIGHT_ReadAP(2); + + // Halt the CPU + JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); + + // Set vector catch on reset (to halt the CPU immediately after reset) + JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + + // Disable CPU wait + JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + + // Clear vector catch stuff + JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); + + return 0; } diff --git a/boards/nordic/nrf54l15pdk/nrf54l15_cpuapp_common.dtsi b/boards/nordic/nrf54l15pdk/nrf54l15_cpuapp_common.dtsi index 2fa2ec36428dab..2938f33f226107 100644 --- a/boards/nordic/nrf54l15pdk/nrf54l15_cpuapp_common.dtsi +++ b/boards/nordic/nrf54l15pdk/nrf54l15_cpuapp_common.dtsi @@ -14,14 +14,12 @@ zephyr,console = &uart20; zephyr,shell-uart = &uart20; zephyr,uart-mcumgr = &uart20; + zephyr,bt-mon-uart = &uart20; + zephyr,bt-c2h-uart = &uart20; zephyr,flash-controller = &rram_controller; zephyr,flash = &cpuapp_rram; zephyr,ieee802154 = &ieee802154; }; - - aliases { - spi-flash0 = &mx25r64; - }; }; &cpuapp_sram { diff --git a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-common.dtsi b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-common.dtsi index 75dbe784097931..9668cbe5bbf202 100644 --- a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-common.dtsi +++ b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-common.dtsi @@ -27,6 +27,19 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + /* + * PWM signal can be exposed on GPIO pin only within same domain. + * There is only one domain which contains both PWM and GPIO: + * PWM20/21/22 and GPIO Port P1. + * Only LEDs connected to P1 can work with PWM, for example LED1. + */ + pwm_led1: pwm_led_1 { + pwms = <&pwm20 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + buttons { compatible = "gpio-keys"; button0: button_0 { @@ -56,6 +69,7 @@ led1 = &led1; led2 = &led2; led3 = &led3; + pwm-led0 = &pwm_led1; sw0 = &button0; sw1 = &button1; sw2 = &button2; @@ -77,3 +91,10 @@ pinctrl-1 = <&uart30_sleep>; pinctrl-names = "default", "sleep"; }; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm20_default>; + pinctrl-1 = <&pwm20_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-pinctrl.dtsi b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-pinctrl.dtsi index 043d35adcf41e4..0b6e2056a82e12 100644 --- a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-pinctrl.dtsi +++ b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15-pinctrl.dtsi @@ -64,4 +64,17 @@ low-power-enable; }; }; + + /omit-if-no-ref/ pwm20_default: pwm20_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm20_sleep: pwm20_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; }; diff --git a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15_common_0_2_1.dtsi b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15_common_0_2_1.dtsi index bfe673ec966e52..a37cf23096670b 100644 --- a/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15_common_0_2_1.dtsi +++ b/boards/nordic/nrf54l15pdk/nrf54l15pdk_nrf54l15_common_0_2_1.dtsi @@ -35,3 +35,18 @@ &button3 { gpios = <&gpio2 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; }; + +&pinctrl { + /omit-if-no-ref/ pwm20_default: pwm20_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm20_sleep: pwm20_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; +}; diff --git a/boards/nordic/nrf9131ek/doc/index.rst b/boards/nordic/nrf9131ek/doc/index.rst index 4e328e0bb0ec81..accd403a286835 100644 --- a/boards/nordic/nrf9131ek/doc/index.rst +++ b/boards/nordic/nrf9131ek/doc/index.rst @@ -32,8 +32,8 @@ Cortex-M33F CPU with ARMv8-M Security Extension and the following devices: nRF9131 EK (Credit: Nordic Semiconductor) -The `Nordic Semiconductor Infocenter`_ -contains the processor's information and the datasheet. +The `Nordic Semiconductor TechDocs`_ will soon +contain the processor's information and the datasheet. Hardware @@ -225,5 +225,5 @@ References .. _IDAU: https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Nordic Semiconductor TechDocs: https://docs.nordicsemi.com/ .. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common.dtsi b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common.dtsi index 2c3b8481d2ae86..9b87986d6f4405 100644 --- a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common.dtsi +++ b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common.dtsi @@ -67,7 +67,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &gd25wb256; }; }; diff --git a/boards/nordic/nrf9151dk/doc/index.rst b/boards/nordic/nrf9151dk/doc/index.rst index 40979cc90898cc..4017347c4f84b7 100644 --- a/boards/nordic/nrf9151dk/doc/index.rst +++ b/boards/nordic/nrf9151dk/doc/index.rst @@ -196,5 +196,5 @@ References .. _IDAU: https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau .. _nRF9151 website: https://www.nordicsemi.com/Products/nRF9151 -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Nordic Semiconductor TechDocs: https://docs.nordicsemi.com/ .. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common.dtsi b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common.dtsi index 958e864c63cdc5..ad4b623cf8f823 100644 --- a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common.dtsi +++ b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common.dtsi @@ -128,7 +128,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &gd25wb256; }; }; diff --git a/boards/nordic/nrf9160dk/doc/index.rst b/boards/nordic/nrf9160dk/doc/index.rst index 0527bbe00b5ad0..70fd2c2fc46ec0 100644 --- a/boards/nordic/nrf9160dk/doc/index.rst +++ b/boards/nordic/nrf9160dk/doc/index.rst @@ -33,7 +33,7 @@ Cortex-M33F CPU with ARMv8-M Security Extension and the following devices: nRF9160 DK (Credit: Nordic Semiconductor) More information about the board can be found at the -`nRF9160 DK website`_. The `Nordic Semiconductor Infocenter`_ +`nRF9160 DK website`_. `nRF9160 Product Specification`_ contains the processor's information and the datasheet. @@ -108,7 +108,7 @@ Remember to also enable routing for this additional hardware in the firmware for :ref:`nrf9160dk_nrf52840` (see :ref:`nrf9160dk_board_controller_firmware`). Other hardware features have not been enabled yet for this board. -See `nRF9160 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF9160 DK website`_ and `nRF9160 Product Specification`_ for a complete list of nRF9160 DK board hardware features. Connections and IOs @@ -282,7 +282,7 @@ SiP. More information about the board can be found at the `Nordic Low power cellular IoT`_ website. -The `Nordic Semiconductor Infocenter`_ +`nRF52840 Product Specification`_ contains the processor's information and the datasheet. @@ -526,6 +526,7 @@ References .. _nRF9160 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF9160-DK .. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ .. _Nordic Low power cellular IoT: https://www.nordicsemi.com/Products/Low-power-cellular-IoT -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF9160 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf9160/page/nRF9160_html5_keyfeatures.html +.. _nRF52840 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf52840/page/keyfeatures_html5.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html -.. _nRF9160 DK board control section in the nRF9160 DK User Guide: https://infocenter.nordicsemi.com/topic/ug_nrf91_dk/UG/nrf91_DK/board_controller.html +.. _nRF9160 DK board control section in the nRF9160 DK User Guide: https://docs.nordicsemi.com/bundle/ug_nrf9160_dk/page/UG/nrf91_DK/hw_description/nrf9160_board_controller.html diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common_0_14_0.dtsi b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common_0_14_0.dtsi index ee4f736bf8b76f..896531d75808f9 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common_0_14_0.dtsi +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common_0_14_0.dtsi @@ -4,12 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/ { - aliases { - spi-flash0 = &mx25r64; - }; -}; - &interface_to_nrf52840 { gpio-map = <0 0 &gpio0 17 0>, <1 0 &gpio0 18 0>, diff --git a/boards/nordic/nrf9161dk/doc/index.rst b/boards/nordic/nrf9161dk/doc/index.rst index 8b3a7fb0236820..251c8467a214c2 100644 --- a/boards/nordic/nrf9161dk/doc/index.rst +++ b/boards/nordic/nrf9161dk/doc/index.rst @@ -27,7 +27,7 @@ Cortex-M33F CPU with ARMv8-M Security Extension and the following devices: * :abbr:`IDAU (Implementation Defined Attribution Unit)` More information about the board can be found at the -`nRF9161 DK website`_. The `Nordic Semiconductor Infocenter`_ +`nRF9161 DK website`_. `nRF9161 Product Specification`_ contains the processor's information and the datasheet. @@ -84,7 +84,7 @@ hardware features: .. _nrf9161dk_additional_hardware: Other hardware features have not been enabled yet for this board. -See `nRF9161 DK website`_ and `Nordic Semiconductor Infocenter`_ +See `nRF9161 DK website`_ and `nRF9161 Product Specification`_ for a complete list of nRF9161 DK board hardware features. Connections and IOs @@ -199,5 +199,5 @@ References .. _IDAU: https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau .. _nRF9161 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF9161-DK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _nRF9161 Product Specification: https://docs.nordicsemi.com/bundle/ps_nrf9161/page/nRF9161_html5_keyfeatures.html .. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common.dtsi b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common.dtsi index 8168a8317e417e..93c9c140c6a6f0 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common.dtsi +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common.dtsi @@ -128,7 +128,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &gd25wb256; }; }; diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common_0_7_0.dtsi b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common_0_7_0.dtsi index ae67df77b2244d..5336ca3ba0667a 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common_0_7_0.dtsi +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common_0_7_0.dtsi @@ -23,9 +23,3 @@ t-exit-dpd = <30000>; }; }; - -/ { - aliases { - spi-flash0 = &gd25lb256; - }; -}; diff --git a/boards/nordic/thingy52/doc/index.rst b/boards/nordic/thingy52/doc/index.rst index e56f00df343702..e83968f7469846 100644 --- a/boards/nordic/thingy52/doc/index.rst +++ b/boards/nordic/thingy52/doc/index.rst @@ -41,7 +41,7 @@ processor, a set of environmental sensors, a pushbutton, and two RGB LEDs. nRF52 Thingy:52 (Credit: Nordic Semiconductor) More information about the board can be found at the `nRF52 DK website`_. The -`Nordic Semiconductor Infocenter`_ contains the processor's information and the +`Nordic Thingy:52 guide`_ contains the processor's information and the datasheet. @@ -390,4 +390,4 @@ References .. target-notes:: .. _nRF52 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/Nordic-Thingy-52 -.. _Nordic Semiconductor Infocenter: http://infocenter.nordicsemi.com/ +.. _Nordic Thingy:52 guide: https://docs.nordicsemi.com/bundle/ug_thingy52/page/UG/thingy52/intro/frontpage.html diff --git a/boards/nordic/thingy53/Kconfig.defconfig b/boards/nordic/thingy53/Kconfig.defconfig index 701bd9be4e6fae..92eac11503dbef 100644 --- a/boards/nordic/thingy53/Kconfig.defconfig +++ b/boards/nordic/thingy53/Kconfig.defconfig @@ -55,9 +55,8 @@ endif # BOARD_THINGY53_NRF5340_CPUAPP_NS if !TRUSTED_EXECUTION_SECURE -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/nordic/thingy53/doc/index.rst b/boards/nordic/thingy53/doc/index.rst index e2f8b000f17ab0..f82626e16842c9 100644 --- a/boards/nordic/thingy53/doc/index.rst +++ b/boards/nordic/thingy53/doc/index.rst @@ -22,7 +22,7 @@ The ``thingy53/nrf5340/cpuapp`` build target provides support for the applicatio core on the nRF5340 SoC. The ``thingy53/nrf5340/cpunet`` build target provides support for the network core on the nRF5340 SoC. -The `Nordic Semiconductor Infocenter`_ contains the processor's information and +The `Nordic Thingy:53 Hardware guide`_ contains the processor's information and the datasheet. Programming and Debugging @@ -48,4 +48,4 @@ References .. target-notes:: -.. _Nordic Semiconductor Infocenter: http://infocenter.nordicsemi.com/ +.. _Nordic Thingy:53 Hardware guide: https://docs.nordicsemi.com/bundle/ug_thingy53/page/UG/thingy53/intro/frontpage.html diff --git a/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi b/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi index 017fa9e8a26740..782174d48b0159 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi +++ b/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi @@ -14,6 +14,7 @@ zephyr,bt-mon-uart = &cdc_acm_uart; zephyr,bt-c2h-uart = &cdc_acm_uart; zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/nuvoton/npcx4m8f_evb/npcx4m8f_evb.dts b/boards/nuvoton/npcx4m8f_evb/npcx4m8f_evb.dts index b90d94b0c9e93e..2993b816956d30 100644 --- a/boards/nuvoton/npcx4m8f_evb/npcx4m8f_evb.dts +++ b/boards/nuvoton/npcx4m8f_evb/npcx4m8f_evb.dts @@ -26,7 +26,6 @@ i2c-0 = &i2c0_0; watchdog0 = &twd0; peci-0 = &peci0; - spi-flash0 = &int_flash; kscan0 = &kscan_input; }; diff --git a/boards/nuvoton/npcx7m6fb_evb/npcx7m6fb_evb.dts b/boards/nuvoton/npcx7m6fb_evb/npcx7m6fb_evb.dts index a1c6d72403be6c..34a8cc9de74d56 100644 --- a/boards/nuvoton/npcx7m6fb_evb/npcx7m6fb_evb.dts +++ b/boards/nuvoton/npcx7m6fb_evb/npcx7m6fb_evb.dts @@ -28,8 +28,6 @@ i2c-0 = &i2c0_0; watchdog0 = &twd0; peci-0 = &peci0; - /* For samples/drivers/spi_flash */ - spi-flash0 = &int_flash; /* For kscan test suites */ kscan0 = &kscan_input; }; diff --git a/boards/nuvoton/npcx9m6f_evb/npcx9m6f_evb.dts b/boards/nuvoton/npcx9m6f_evb/npcx9m6f_evb.dts index 841883cc38c22d..fe186dca262074 100644 --- a/boards/nuvoton/npcx9m6f_evb/npcx9m6f_evb.dts +++ b/boards/nuvoton/npcx9m6f_evb/npcx9m6f_evb.dts @@ -31,8 +31,6 @@ /* For watchdog sample */ watchdog0 = &twd0; peci-0 = &peci0; - /* For samples/drivers/spi_flash */ - spi-flash0 = &int_flash; /* For kscan test suites */ kscan0 = &kscan_input; }; diff --git a/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki_defconfig b/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki_defconfig index 4e555333a7eaeb..e59234cb73c742 100644 --- a/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki_defconfig +++ b/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki_defconfig @@ -21,6 +21,3 @@ CONFIG_UART_CONSOLE=y # Enable RMC CONFIG_FLASH=y - -# m2l31x has 4 MPU regions and can't afford to enable CONFIG_USERSPACE -CONFIG_USERSPACE=n diff --git a/boards/nxp/frdm_k22f/doc/index.rst b/boards/nxp/frdm_k22f/doc/index.rst index f0f98048561c7e..b92fa508cd0223 100644 --- a/boards/nxp/frdm_k22f/doc/index.rst +++ b/boards/nxp/frdm_k22f/doc/index.rst @@ -26,7 +26,7 @@ MCUs. Hardware ******** -- MK22FN512VLH12 (120 MHz, 1 MB flash memory, 256 KB RAM, low-power, +- MK22FN512VLH12 (120 MHz, 512 KB flash memory, 128 KB RAM, low-power, crystal-less USB, and 64 pin Low profile Quad Flat Package (LQFP)) - Dual role USB interface with micro-B USB connector - RGB LED diff --git a/boards/nxp/frdm_k22f/frdm_k22f.dts b/boards/nxp/frdm_k22f/frdm_k22f.dts index 587aaa65ee1085..5c1117a2b57919 100644 --- a/boards/nxp/frdm_k22f/frdm_k22f.dts +++ b/boards/nxp/frdm_k22f/frdm_k22f.dts @@ -1,12 +1,13 @@ /* * Copyright (c) 2018 Prevas A/S + * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; -#include +#include #include #include "frdm_k22f-pinctrl.dtsi" #include @@ -203,23 +204,23 @@ zephyr_udc0: &usbotg { boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x00010000>; + reg = <0x00000000 DT_SIZE_K(64)>; read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 3 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 0x00028800>; + reg = <0x00010000 (DT_SIZE_K(180) + DT_SIZE_K(6))>; }; - slot1_partition: partition@38800 { + slot1_partition: partition@3E800 { label = "image-1"; - reg = <0x00038800 0x00028000>; + reg = <0x0003E800 DT_SIZE_K(180)>; }; - storage_partition: partition@60800 { + storage_partition: partition@6B800 { label = "storage"; - reg = <0x00060800 0x0001f800>; + reg = <0x0006B800 DT_SIZE_K(82)>; }; }; diff --git a/boards/nxp/frdm_k64f/frdm_k64f.dts b/boards/nxp/frdm_k64f/frdm_k64f.dts index 4c42385a794edb..7fbc1943ec9021 100644 --- a/boards/nxp/frdm_k64f/frdm_k64f.dts +++ b/boards/nxp/frdm_k64f/frdm_k64f.dts @@ -233,23 +233,23 @@ zephyr_udc0: &usbotg { boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x00010000>; + reg = <0x00000000 DT_SIZE_K(64)>; read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 0x00069000>; + reg = <0x00010000 (DT_SIZE_K(416) + DT_SIZE_K(8))>; }; - slot1_partition: partition@79000 { + slot1_partition: partition@7a000 { label = "image-1"; - reg = <0x00079000 0x00068000>; + reg = <0x0007a000 DT_SIZE_K(416)>; }; - storage_partition: partition@e1000 { + storage_partition: partition@e2000 { label = "storage"; - reg = <0x000e1000 0x0001f000>; + reg = <0x000e2000 DT_SIZE_K(120)>; }; }; }; @@ -272,7 +272,7 @@ zephyr_udc0: &usbotg { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,interface-type = "rmii-25MHz"; + microchip,interface-type = "rmii-25MHz"; }; }; diff --git a/boards/nxp/frdm_k64f/frdm_k64f.yaml b/boards/nxp/frdm_k64f/frdm_k64f.yaml index b4de8b219e1075..ca78929f69e129 100644 --- a/boards/nxp/frdm_k64f/frdm_k64f.yaml +++ b/boards/nxp/frdm_k64f/frdm_k64f.yaml @@ -25,5 +25,6 @@ supported: - pwm - spi - usb_device + - usbd - watchdog vendor: nxp diff --git a/boards/nxp/frdm_k82f/frdm_k82f.dts b/boards/nxp/frdm_k82f/frdm_k82f.dts index 44b88975f4d71f..96640fe64323f7 100644 --- a/boards/nxp/frdm_k82f/frdm_k82f.dts +++ b/boards/nxp/frdm_k82f/frdm_k82f.dts @@ -27,7 +27,6 @@ sw1 = &user_button_1; magn0 = &fxos8700; accel0 = &fxos8700; - spi-flash0 = &mx25u32; }; chosen { @@ -159,14 +158,14 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(48)>; + reg = <0x0 DT_SIZE_K(44)>; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ - slot0_partition: partition@c000 { + slot0_partition: partition@b000 { label = "image-0"; - reg = <0xc000 DT_SIZE_K(100)>; + reg = <0xb000 (DT_SIZE_K(96) + DT_SIZE_K(8))>; }; slot1_partition: partition@25000 { label = "image-1"; diff --git a/boards/nxp/frdm_ke17z512/Kconfig.frdm_ke17z512 b/boards/nxp/frdm_ke17z512/Kconfig.frdm_ke17z512 new file mode 100644 index 00000000000000..0ac331398d2df2 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/Kconfig.frdm_ke17z512 @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_KE17Z512 + select SOC_MKE17Z9 + select SOC_PART_NUMBER_MKE17Z512VLL9 diff --git a/boards/nxp/frdm_ke17z512/board.cmake b/boards/nxp/frdm_ke17z512/board.cmake new file mode 100644 index 00000000000000..4c09a06e95ed46 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(linkserver "--device=MKE17Z512xxx9:FRDM-KE17Z512") +board_runner_args(jlink "--device=MKE17Z512xxx9" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_ke17z512/board.yml b/boards/nxp/frdm_ke17z512/board.yml new file mode 100644 index 00000000000000..46839e065b1dd3 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/board.yml @@ -0,0 +1,5 @@ +board: + name: frdm_ke17z512 + vendor: nxp + socs: + - name: mke17z9 diff --git a/boards/nxp/frdm_ke17z512/doc/frdm_ke17z512.webp b/boards/nxp/frdm_ke17z512/doc/frdm_ke17z512.webp new file mode 100644 index 00000000000000..d068f9257636a0 Binary files /dev/null and b/boards/nxp/frdm_ke17z512/doc/frdm_ke17z512.webp differ diff --git a/boards/nxp/frdm_ke17z512/doc/index.rst b/boards/nxp/frdm_ke17z512/doc/index.rst new file mode 100644 index 00000000000000..d9dc4385a79809 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/doc/index.rst @@ -0,0 +1,198 @@ +.. _frdm_ke17z512: + +NXP FRDM-KE17Z512 +################## + +Overview +******** + +The FRDM-KE17Z512 is a development board for NXP Kinetis KE1xZ 32-bit +MCU-based platforms. The onboard OpenSDAv2 serial and debug adapter, +running an open source bootloader, offers options for serial +communication, flash programming, and run-control debugging. + +.. figure:: frdm_ke17z512.webp + :align: center + :alt: FRDM-KE17Z512 + + FRDM-KE17Z512 (Credit: NXP) + +Hardware +******** + +- MKE17Z512VLL9 MCU (up to 96 MHz, 512 KB flash memory, 96 KB RAM, + and 100 Low profile Quad Flat Package (LQFP)) +- 3.3 V or 5 V MCU operation +- 6-axis FXOS8700CQ digital accelerometer and magnetometer +- RGB LED +- Two user push-buttons +- Thermistor +- Arduino compatible I/O pin header +- OpenSDA on-board debugger +- Two Touch Electrodes + +For more information about the KE1xZ SoC and the FRDM-KE17Z512 board, see +these NXP reference documents: + +- `KE1xZ Website`_ +- `KE1xZ Fact Sheet`_ +- `KE1xZ Reference Manual`_ +- `FRDM-KE17Z512 Website`_ +- `FRDM-KE17Z512 Quick Start Guide`_ +- `FRDM-KE17Z512 Reference Manual`_ + +Supported Features +================== + +The frdm_ke17z512 board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | uart polling; | +| | | uart interrupt | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +``boards/nxp/frdm_ke17z512/frdm_ke17z512_defconfig``. + +Other hardware features are not currently supported by the port. + +System Clock +============ + +The KE17Z9 SoC is configured to run at 48 MHz using the FIRC. + +Serial Port +=========== + +The KE17Z9 SoC has three LPUARTs. UART2 is configured for the console. + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use Linkserver. + +Early versions of this board have an outdated version of the OpenSDA bootloader +and require an update. Please see the `DAPLink Bootloader Update`_ page for +instructions to update from the CMSIS-DAP bootloader to the DAPLink bootloader. + +Option 1: Linkserver +-------------------- + +Install the :ref:`linkserver-debug-host-tools` and make sure they are in your +search path. LinkServer works with the default CMSIS-DAP firmware included in +the on-board debugger. + +Linkserver is the default for this board, ``west flash`` and ``west debug`` will +call the linkserver runner. + +Option 2: :ref:`opensda-jlink-onboard-debug-probe` +-------------------------------------------------- + +Install the :ref:`jlink-debug-host-tools` and make sure they are in your search +path. + +Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program +the `Segger J-Link OpenSDA V2.1 Firmware`_. +Use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Regardless of your choice in debug probe, we will use the OpenSDA +microcontroller as a usb-to-serial adapter for the serial console. + +Connect a USB cable from your PC to J10. + +Use the following settings with your serial terminal of choice (minicom, putty, +etc.): + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_ke17z512 + :goals: flash + +Open a serial terminal, reset the board (press the SW1 button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.6.0-xxxx-gxxxxxxxxxxxx *** + Hello World! frdm_ke17z512/mke17z9 + +Debugging +========= + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_ke17z512 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.6.0-xxxx-gxxxxxxxxxxxx *** + Hello World! frdm_ke17z512/mke17z9 + +.. _FRDM-KE17Z512 Website: + https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/frdm-development-board-for-96-mhz-ke17z-ke13z-ke12z-with-512-kb-flash-mcus:FRDM-KE17Z512 + +.. _FRDM-KE17Z512 Quick Start Guide: + https://www.nxp.com/docs/en/quick-reference-guide/FRDMKE17Z512QSG.pdf + +.. _FRDM-KE17Z512 Reference Manual: + https://www.nxp.com/docs/en/reference-manual/KE1XZP100M96SF0RM.pdf + +.. _KE1xZ Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/ke-series-arm-cortex-m4-m0-plus/ke1xz-arm-cortex-m0-plus-5v-main-stream-mcu-with-nxp-touch-and-can-control:KE1xZ + +.. _KE1xZ Fact Sheet: + https://www.nxp.com/docs/en/fact-sheet/KE1xZMCUFAMFS.pdf + +.. _KE1xZ Reference Manual: + https://www.nxp.com/webapp/Download?colCode=KE1XZP100M72SF0RM + +.. _linkserver-debug-host-tools: + https://www.nxp.com/lgfiles/updates/mcuxpresso/LinkServer_1.5.30.exe + +.. _Segger J-Link OpenSDA V2.1 Firmware: + https://www.segger.com/downloads/jlink/OpenSDA_V2_1.bin + +.. _DAPLink Bootloader Update: + https://os.mbed.com/blog/entry/DAPLink-bootloader-update/ + +.. _jlink-debug-host-tools: + https://www.segger.com/downloads/jlink/JLink_Windows_V794_x86_64.exe diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512-pinctrl.dtsi b/boards/nxp/frdm_ke17z512/frdm_ke17z512-pinctrl.dtsi new file mode 100644 index 00000000000000..cea7e351c9eab0 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512-pinctrl.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +&pinctrl { + + /* Configures pin routing and optionally pin electrical features. */ + lpuart2_default: lpuart2_default { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; +}; diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts new file mode 100644 index 00000000000000..f1f759b9e31325 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts @@ -0,0 +1,76 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_ke17z512-pinctrl.dtsi" +#include + +/ { + model = "NXP Freedom KE17Z512 board"; + compatible = "nxp,ke17z512", "nxp,mke17z9", "nxp,ke1xz"; + + chosen { + zephyr,sram = &sram_u; + zephyr,flash = &flash0; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + }; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &user_button_2; + sw1 = &user_button_3; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + gpios = <&gpiod 10 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + green_led: led_1 { + gpios = <&gpiod 5 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + blue_led: led_2 { + gpios = <&gpiod 12 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_2: button_0 { + label = "User SW2"; + gpios = <&gpioe 14 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + user_button_3: button_1 { + label = "User SW3"; + gpios = <&gpiod 3 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&lpuart2 { + status = "okay"; + pinctrl-0 = <&lpuart2_default>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&gpiod { + status = "okay"; +}; + +&gpioe { + status = "okay"; +}; diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml b/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml new file mode 100644 index 00000000000000..4fb3e6f1ad3556 --- /dev/null +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml @@ -0,0 +1,20 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_ke17z512 +name: NXP FRDM-KE17Z512 +type: mcu +arch: arm +ram: 64 +flash: 512 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - uart +vendor: nxp diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512_defconfig b/boards/nxp/frdm_ke17z512/frdm_ke17z512_defconfig new file mode 100644 index 00000000000000..d1237a34ce714f --- /dev/null +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512_defconfig @@ -0,0 +1,12 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 +CONFIG_PINCTRL=y diff --git a/boards/nxp/frdm_mcxn947/board.c b/boards/nxp/frdm_mcxn947/board.c index 87c4beb2005913..b5394abae3be68 100644 --- a/boards/nxp/frdm_mcxn947/board.c +++ b/boards/nxp/frdm_mcxn947/board.c @@ -106,6 +106,25 @@ static int frdm_mcxn947_init(void) CLOCK_SetupExtClocking(BOARD_XTAL0_CLK_HZ); +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan0), okay) + /* Set up PLL1 for 80 MHz FlexCAN clock */ + const pll_setup_t pll1Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(1U) | SCG_SPLLCTRL_SELI(27U) | + SCG_SPLLCTRL_SELP(13U), + .pllndiv = SCG_SPLLNDIV_NDIV(3U), + .pllpdiv = SCG_SPLLPDIV_PDIV(1U), + .pllmdiv = SCG_SPLLMDIV_MDIV(10U), + .pllRate = 80000000U + }; + + /* Configure PLL1 to the desired values */ + CLOCK_SetPLL1Freq(&pll1Setup); + /* PLL1 Monitor is disabled */ + CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); + /* Set PLL1 CLK0 divider to value 1 */ + CLOCK_SetClkDiv(kCLOCK_DivPLL1Clk0, 1U); +#endif + #if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm1), okay) CLOCK_SetClkDiv(kCLOCK_DivFlexcom1Clk, 1u); CLOCK_AttachClk(kFRO12M_to_FLEXCOMM1); @@ -203,6 +222,11 @@ static int frdm_mcxn947_init(void) CLOCK_AttachClk(kPLL0_to_CTIMER4); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan0), okay) + CLOCK_SetClkDiv(kCLOCK_DivFlexcan0Clk, 1U); + CLOCK_AttachClk(kPLL1_CLK0_to_FLEXCAN0); +#endif + #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc0), okay) CLOCK_SetClkDiv(kCLOCK_DivUSdhcClk, 1u); CLOCK_AttachClk(kFRO_HF_to_USDHC); @@ -274,6 +298,10 @@ static int frdm_mcxn947_init(void) SPC_EnableActiveModeAnalogModules(SPC0, (kSPC_controlCmp0 | kSPC_controlCmp0Dac)); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lptmr0), okay) + CLOCK_SetupClk16KClocking(kCLOCK_Clk16KToVsys); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; diff --git a/boards/nxp/frdm_mcxn947/doc/index.rst b/boards/nxp/frdm_mcxn947/doc/index.rst index d85421664a609c..1ed7faf4b01760 100644 --- a/boards/nxp/frdm_mcxn947/doc/index.rst +++ b/boards/nxp/frdm_mcxn947/doc/index.rst @@ -92,6 +92,10 @@ The FRDM-MCXN947 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | LPCMP | on-chip | sensor(comparator) | +-----------+------------+-------------------------------------+ +| FLEXCAN | on-chip | CAN | ++-----------+------------+-------------------------------------+ +| LPTMR | on-chip | counter | ++-----------+------------+-------------------------------------+ Targets available ================== diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi index 6cf8e3ad6b036d..13e6f47f5e5e82 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi @@ -166,4 +166,14 @@ bias-pull-up; }; }; + + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi index 5d3942fc4596a4..31292bdf72867a 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi @@ -83,6 +83,10 @@ * replace &os_timer with &systick */ &os_timer { + status = "disabled"; +}; + +&systick { status = "okay"; }; @@ -196,3 +200,8 @@ pinctrl-0 = <&pinmux_lpcmp0>; pinctrl-names = "default"; }; + +&flexcan0 { + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dts index 2f30bffe5c892d..f6111bb41f06d5 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dts +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dts @@ -24,6 +24,7 @@ zephyr,code-partition = &slot0_partition; zephyr,console = &flexcomm4_lpuart4; zephyr,shell-uart = &flexcomm4_lpuart4; + zephyr,canbus = &flexcan0; }; aliases{ @@ -142,6 +143,10 @@ status = "okay"; }; +&flexcan0 { + status = "okay"; +}; + &ctimer0 { status = "okay"; }; @@ -169,3 +174,7 @@ zephyr_udc0: &usb1 { &lpcmp0 { status = "okay"; }; + +&lptmr0 { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index ef6ea7114dc969..76f937fb1e5621 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -15,6 +15,7 @@ toolchain: - gnuarmemb - xtools supported: + - can - dma - gpio - spi diff --git a/boards/nxp/frdm_rw612/Kconfig.defconfig b/boards/nxp/frdm_rw612/Kconfig.defconfig new file mode 100644 index 00000000000000..84324bf402e20c --- /dev/null +++ b/boards/nxp/frdm_rw612/Kconfig.defconfig @@ -0,0 +1,14 @@ +# FRDM_RW612 board + +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FRDM_RW612 + +config FLASH_LOAD_SIZE + default 0x400000 if !BOOTLOADER_MCUBOOT && !NXP_MONOLITHIC_BT + +config NET_L2_ETHERNET + default y if DT_HAS_NXP_ENET_MAC_ENABLED && NETWORKING + +endif # BOARD_FRDM_RW612 diff --git a/boards/nxp/frdm_rw612/doc/index.rst b/boards/nxp/frdm_rw612/doc/index.rst index caefff181f0fd4..9f01fbdca8918c 100644 --- a/boards/nxp/frdm_rw612/doc/index.rst +++ b/boards/nxp/frdm_rw612/doc/index.rst @@ -39,7 +39,8 @@ Supported Features +-----------+------------+-----------------------------------+ | USART | on-chip | serial | +-----------+------------+-----------------------------------+ - +| BLE | on-chip | Bluetooth | ++-----------+------------+-----------------------------------+ The default configuration can be found in the defconfig file: @@ -47,6 +48,16 @@ The default configuration can be found in the defconfig file: Other hardware features are not currently supported +Fetch Binary Blobs +****************** + +To support Bluetooth, frdm_rw612 requires fetching binary blobs, which can be +achieved by running the following command: + +.. code-block:: console + + west blobs fetch hal_nxp + Programming and Debugging ************************* @@ -108,6 +119,26 @@ should see the following message in the terminal: ***** Booting Zephyr OS zephyr-v3.6.0 ***** Hello World! frdm_rw612 +Bluetooth +========= + +BLE functionality requires to fetch binary blobs, so make sure to follow +the ``Fetch Binary Blobs`` section first. + +Those binary blobs can be used in two different ways, depending if :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` +is enabled or not: + +- :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` is enabled (default): + +The required binary blob will be linked with the application image directly, forming +one single monolithic image. +The user has nothing else to do other than flashing the application to the board. + +- :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` is disabled: + +In this case, the BLE blob won't be linked with the application, so the user needs to manually +flash the BLE binary blob to the board at the address ``0x18540000``. +The binary blob will be located here: ``/modules/hal/nxp/zephyr/blobs/rw61x/rw61x_sb_ble_a2.bin`` Resources ========= diff --git a/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi b/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi index c9b0bcb8984a1e..278d288bfe8ae5 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi +++ b/boards/nxp/frdm_rw612/frdm_rw612-pinctrl.dtsi @@ -13,4 +13,29 @@ slew-rate = "normal"; }; }; + + pinmux_flexcomm0_usart: pinmux_flexcomm0_usart { + group0 { + pinmux = ; + slew-rate = "normal"; + }; + }; + + pinmux_enet: pinmux_enet { + group0 { + pinmux = ; + slew-rate = "fast"; + }; + }; + + pinmux_mdio: pinmux_mdio { + group0 { + pinmux = ; + slew-rate = "fast"; + }; + }; }; diff --git a/boards/nxp/frdm_rw612/frdm_rw612.dts b/boards/nxp/frdm_rw612/frdm_rw612.dts index ad7237fb6583ec..cafa12afd1dd9f 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.dts +++ b/boards/nxp/frdm_rw612/frdm_rw612.dts @@ -20,6 +20,7 @@ zephyr,sram = &sram_data; zephyr,flash = &w25q512jvfiq; zephyr,console = &flexcomm3; + zephyr,shell-uart = &flexcomm3; }; leds { @@ -38,6 +39,14 @@ pinctrl-names = "default"; }; +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "disabled"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + &hsgpio0 { status = "okay"; }; @@ -55,3 +64,31 @@ spi-max-frequency = <133000000>; }; }; + +&hci { + status = "okay"; + wakeup-source; +}; + +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_mdio>; + pinctrl-names = "default"; + phy: phy@2 { + compatible = "microchip,ksz8081"; + reg = <2>; + status = "okay"; + reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; + int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12.dts b/boards/nxp/hexiwear/hexiwear_mk64f12.dts index d530b6e9036a89..18cc0a3704526e 100644 --- a/boards/nxp/hexiwear/hexiwear_mk64f12.dts +++ b/boards/nxp/hexiwear/hexiwear_mk64f12.dts @@ -28,7 +28,7 @@ zephyr,code-partition = &slot0_partition; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart4; + zephyr,bt-hci = &bt_hci_uart; }; leds { @@ -153,6 +153,11 @@ current-speed = <115200>; pinctrl-0 = <&uart4_default>; pinctrl-names = "default"; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; &gpioa { @@ -181,26 +186,25 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x00010000>; + reg = <0x00000000 DT_SIZE_K(64)>; read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 0x00069000>; + reg = <0x00010000 (DT_SIZE_K(416) + DT_SIZE_K(8))>; }; - slot1_partition: partition@79000 { + slot1_partition: partition@7a000 { label = "image-1"; - reg = <0x00079000 0x00068000>; + reg = <0x0007a000 DT_SIZE_K(416)>; }; - storage_partition: partition@e1000 { + storage_partition: partition@e2000 { label = "storage"; - reg = <0x000e1000 0x0001f000>; + reg = <0x000e2000 DT_SIZE_K(120)>; }; }; }; diff --git a/boards/nxp/imx8mp_evk/doc/index.rst b/boards/nxp/imx8mp_evk/doc/index.rst index 6d6e1b7b556641..c36a9065d31e94 100644 --- a/boards/nxp/imx8mp_evk/doc/index.rst +++ b/boards/nxp/imx8mp_evk/doc/index.rst @@ -226,4 +226,4 @@ References https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-plus-applications-processor:8MPLUSLPD4-EVK .. _i.MX 8M Applications Processor Reference Manual: - https://www.nxp.com/docs/en/reference-manual/IMX8MPRM.pdf + https://www.nxp.com/webapp/Download?colCode=IMX8MPRM diff --git a/boards/nxp/mimxrt1020_evk/doc/index.rst b/boards/nxp/mimxrt1020_evk/doc/index.rst index 4b409031729a62..0043cf5a8a309c 100644 --- a/boards/nxp/mimxrt1020_evk/doc/index.rst +++ b/boards/nxp/mimxrt1020_evk/doc/index.rst @@ -106,6 +106,8 @@ already supported, which can also be re-used on this mimxrt1020_evk board: | UART | on-chip | serial port-polling; | | | | serial port-interrupt | +-----------+------------+-------------------------------------+ +| ENET | on-chip | ethernet | ++-----------+------------+-------------------------------------+ | USB | on-chip | USB device | +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | diff --git a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk-pinctrl.dtsi b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk-pinctrl.dtsi index 9fe3a42bf9f38f..8fdf5ebbc38d17 100644 --- a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk-pinctrl.dtsi @@ -31,21 +31,29 @@ input-enable; }; group1 { - pinmux = <&iomuxc_gpio_ad_b0_04_gpio1_io04>; + pinmux = <&iomuxc_gpio_ad_b0_09_enet_rx_data1>, + <&iomuxc_gpio_ad_b0_11_enet_rx_en>, + <&iomuxc_gpio_ad_b0_14_enet_tx_data0>, + <&iomuxc_gpio_ad_b0_15_enet_tx_data1>, + <&iomuxc_gpio_ad_b0_13_enet_tx_en>, + <&iomuxc_gpio_ad_b0_12_enet_rx_er>; drive-strength = "r0-5"; bias-pull-up; bias-pull-up-value = "100k"; slew-rate = "fast"; - nxp,speed = "100-mhz"; + nxp,speed = "200-mhz"; }; group2 { - pinmux = <&iomuxc_gpio_ad_b0_09_enet_rx_data1>, - <&iomuxc_gpio_ad_b0_11_enet_rx_en>, - <&iomuxc_gpio_ad_b0_14_enet_tx_data0>, - <&iomuxc_gpio_ad_b0_15_enet_tx_data1>, - <&iomuxc_gpio_ad_b0_13_enet_tx_en>, - <&iomuxc_gpio_ad_b0_12_enet_rx_er>, - <&iomuxc_gpio_emc_40_enet_mdio>, + pinmux = <&iomuxc_gpio_ad_b0_10_enet_rx_data0>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + + pinmux_enet_mdio: pinmux_enet_mdio { + group0 { + pinmux = <&iomuxc_gpio_emc_40_enet_mdio>, <&iomuxc_gpio_emc_41_enet_mdc>; drive-strength = "r0-5"; bias-pull-up; @@ -53,7 +61,7 @@ slew-rate = "fast"; nxp,speed = "200-mhz"; }; - group3 { + group1 { pinmux = <&iomuxc_gpio_ad_b1_06_gpio1_io22>; drive-strength = "r0-5"; bias-pull-up; @@ -61,14 +69,20 @@ slew-rate = "slow"; nxp,speed = "100-mhz"; }; - group4 { - pinmux = <&iomuxc_gpio_ad_b0_10_enet_rx_data0>; - drive-strength = "r0-6"; - slew-rate = "slow"; + group2 { + pinmux = <&iomuxc_gpio_ad_b0_04_gpio1_io04>; + drive-strength = "r0-5"; + bias-pull-up; + bias-pull-up-value = "100k"; + slew-rate = "fast"; nxp,speed = "100-mhz"; }; }; + pinmux_ptp: pinmux_ptp { + /* Intentionally empty */ + }; + pinmux_flexcan1: pinmux_flexcan1 { group0 { pinmux = <&iomuxc_gpio_sd_b1_00_flexcan1_tx>, @@ -173,9 +187,7 @@ }; }; - /* intentionally left empty */ - pinmux_ptp: pinmux_ptp { - }; + pinmux_sai3: pinmux_sai3 { group0 { diff --git a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts index 5a5e0caac3ad8d..54358e1588be94 100644 --- a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts @@ -130,6 +130,35 @@ arduino_serial: &lpuart2 { }; }; +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; + phy: phy@0 { + compatible = "microchip,ksz8081"; + reg = <0>; + status = "okay"; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; + +&enet_ptp_clock { + status = "okay"; + pinctrl-0 = <&pinmux_ptp>; + pinctrl-names = "default"; +}; + &lpi2c1 { status = "okay"; pinctrl-0 = <&pinmux_lpi2c1>; diff --git a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts index d30a04f4744079..1dc4f3c6db711f 100644 --- a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts +++ b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts @@ -139,9 +139,9 @@ arduino_serial: &lpuart2 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; diff --git a/boards/nxp/mimxrt1040_evk/CMakeLists.txt b/boards/nxp/mimxrt1040_evk/CMakeLists.txt index 9fc000a98ab3ba..e5e2d4d4140910 100644 --- a/boards/nxp/mimxrt1040_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1040_evk/CMakeLists.txt @@ -4,6 +4,11 @@ # SPDX-License-Identifier: Apache-2.0 # +if (CONFIG_DISPLAY) +message(WARNING " +CONFIG_DISPLAY: Running this firmware on a board without a display may damage the board +") +endif() if(CONFIG_NXP_IMXRT_BOOT_HEADER) zephyr_library() diff --git a/boards/nxp/mimxrt1040_evk/doc/index.rst b/boards/nxp/mimxrt1040_evk/doc/index.rst index a73b6a05b4d0e3..67d35781892950 100644 --- a/boards/nxp/mimxrt1040_evk/doc/index.rst +++ b/boards/nxp/mimxrt1040_evk/doc/index.rst @@ -118,6 +118,10 @@ already supported, which can also be re-used on this mimxrt1040_evk board: +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-----------+------------+-------------------------------------+ +| DISPLAY | on-chip | eLCDIF. Tested with | +| | | :ref:`rk043fn02h_ct`, and | +| | | :ref:`rk043fn66hs_ctg` shields | ++-----------+------------+-------------------------------------+ The default configuration can be found in :zephyr_file:`boards/nxp/mimxrt1040_evk/mimxrt1040_evk_defconfig` diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi index ad26eeecc3fdc3..b9542c2362a566 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi @@ -94,5 +94,35 @@ }; }; + pinmux_lcdif: pinmux_lcdif { + group0 { + pinmux = <&iomuxc_gpio_b0_00_lcdif_clk>, + <&iomuxc_gpio_b0_01_lcdif_enable>, + <&iomuxc_gpio_b0_02_lcdif_hsync>, + <&iomuxc_gpio_b0_03_lcdif_vsync>, + <&iomuxc_gpio_b0_04_lcdif_data00>, + <&iomuxc_gpio_b0_05_lcdif_data01>, + <&iomuxc_gpio_b0_06_lcdif_data02>, + <&iomuxc_gpio_b0_07_lcdif_data03>, + <&iomuxc_gpio_b0_08_lcdif_data04>, + <&iomuxc_gpio_b0_09_lcdif_data05>, + <&iomuxc_gpio_b0_10_lcdif_data06>, + <&iomuxc_gpio_b0_11_lcdif_data07>, + <&iomuxc_gpio_b0_12_lcdif_data08>, + <&iomuxc_gpio_b0_13_lcdif_data09>, + <&iomuxc_gpio_b0_14_lcdif_data10>, + <&iomuxc_gpio_b0_15_lcdif_data11>, + <&iomuxc_gpio_b1_00_lcdif_data12>, + <&iomuxc_gpio_b1_01_lcdif_data13>, + <&iomuxc_gpio_b1_02_lcdif_data14>, + <&iomuxc_gpio_b1_03_lcdif_data15>; + drive-strength = "r0-6"; + input-schmitt-enable; + bias-pull-up; + bias-pull-up-value = "100k"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; }; diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts index fe10790977c1cc..a81167a17202bf 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts @@ -37,6 +37,33 @@ reg = <0x80000000 DT_SIZE_M(32)>; }; + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 19 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + leds { compatible = "gpio-leds"; green_led: led_0 { @@ -163,6 +190,13 @@ pinctrl-names = "default"; }; +nxp_touch_i2c: &lpi2c1 {}; + +zephyr_lcdif: &lcdif { + pinctrl-0 = <&pinmux_lcdif>; + pinctrl-names = "default"; +}; + /* Leave LPI2C3 disabled by default, since it conflicts with LPSPI1 pins */ &lpi2c3 { pinctrl-0 = <&pinmux_lpi2c3>; diff --git a/boards/nxp/mimxrt1050_evk/Kconfig.defconfig b/boards/nxp/mimxrt1050_evk/Kconfig.defconfig index 1db4e04d7770b9..56603850195825 100644 --- a/boards/nxp/mimxrt1050_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1050_evk/Kconfig.defconfig @@ -10,17 +10,6 @@ config DEVICE_CONFIGURATION_DATA config NXP_IMX_EXTERNAL_SDRAM default y - -config INPUT - default y if LVGL - -if INPUT - -config INPUT_FT5336_INTERRUPT - default y - -endif # INPUT - if NETWORKING config NET_L2_ETHERNET @@ -35,39 +24,4 @@ endif # ETH_MCUX endif # NETWORKING -if LVGL - -# LVGL should allocate buffers equal to size of display -config LV_Z_VDB_SIZE - default 100 - -# Enable double buffering -config LV_Z_DOUBLE_VDB - default y - -# Force full refresh. This prevents memory copy associated with partial -# display refreshes, which is not necessary for the eLCDIF driver -config LV_Z_FULL_REFRESH - default y - -config LV_DPI_DEF - default 128 - -config LV_Z_BITS_PER_PIXEL - default 16 - -# Force display buffers to be aligned to cache line size (32 bytes) -config LV_Z_VDB_ALIGN - default 32 - -# Use offloaded render thread -config LV_Z_FLUSH_THREAD - default y - -choice LV_COLOR_DEPTH - default LV_COLOR_DEPTH_16 -endchoice - -endif # LVGL - endif # BOARD_MIMXRT1050_EVK diff --git a/boards/nxp/mimxrt1050_evk/doc/index.rst b/boards/nxp/mimxrt1050_evk/doc/index.rst index c5351b9b636188..df2e4636c26a72 100644 --- a/boards/nxp/mimxrt1050_evk/doc/index.rst +++ b/boards/nxp/mimxrt1050_evk/doc/index.rst @@ -119,7 +119,9 @@ already supported, which can also be re-used on this mimxrt1050_evk board: +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | +-----------+------------+-------------------------------------+ -| DISPLAY | on-chip | display | +| DISPLAY | on-chip | eLCDIF. Tested with | +| | | :ref:`rk043fn02h_ct`, and | +| | | :ref:`rk043fn66hs_ctg` shields | +-----------+------------+-------------------------------------+ | GPIO | on-chip | gpio | +-----------+------------+-------------------------------------+ diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts index 4bd6b5bb441161..bd439a372f980f 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts @@ -8,7 +8,6 @@ #include #include "mimxrt1050_evk-pinctrl.dtsi" -#include #include / { @@ -30,7 +29,6 @@ zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; - zephyr,display = &lcdif; }; sdram0: memory@80000000 { @@ -39,6 +37,33 @@ reg = <0x80000000 DT_SIZE_M(32)>; }; + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + leds { compatible = "gpio-leds"; green_led: led_0 { @@ -56,11 +81,6 @@ }; }; - lvgl_pointer { - compatible = "zephyr,lvgl-pointer-input"; - input = <&ft5336>; - }; - arduino_header: connector { compatible = "arduino-header-r3"; #gpio-cells = <2>; @@ -89,15 +109,6 @@ <20 0 &gpio1 1 0>, /* D14 */ <21 0 &gpio1 0 0>; /* D15 */ }; - - panel { - compatible = "rocktech,rk043fn02h-ct"; - port { - lcd_panel_in: endpoint { - remote-endpoint = <&lcd_panel_out>; - }; - }; - }; }; arduino_serial: &lpuart3 { @@ -112,34 +123,11 @@ arduino_serial: &lpuart3 { pinctrl-names = "default"; }; -&lcdif { - status = "okay"; - width = <480>; - height = <272>; - display-timings { - compatible = "zephyr,panel-timing"; - hsync-len = <41>; - hfront-porch = <4>; - hback-porch = <8>; - vsync-len = <10>; - vfront-porch = <4>; - vback-porch = <2>; - de-active= <1>; - pixelclk-active = <1>; - hsync-active = <0>; - vsync-active = <0>; - clock-frequency = <9210240>; - }; - pixel-format = ; - data-bus-width = "16-bit"; +nxp_touch_i2c: &lpi2c1 {}; + +zephyr_lcdif: &lcdif { pinctrl-0 = <&pinmux_lcdif>; pinctrl-names = "default"; - backlight-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; - port { - lcd_panel_out: endpoint { - remote-endpoint = <&lcd_panel_in>; - }; - }; }; &lpi2c1 { @@ -159,12 +147,6 @@ arduino_serial: &lpuart3 { int1-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; int2-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; - - ft5336: ft5336@38 { - compatible = "focaltech,ft5336"; - reg = <0x38>; - int-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; - }; }; &lpuart1 { @@ -210,9 +192,9 @@ arduino_serial: &lpuart3 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; diff --git a/boards/nxp/mimxrt1060_evk/Kconfig.defconfig b/boards/nxp/mimxrt1060_evk/Kconfig.defconfig index 37dc90279ddee6..899e8b3ffe0f22 100644 --- a/boards/nxp/mimxrt1060_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1060_evk/Kconfig.defconfig @@ -11,16 +11,6 @@ config DEVICE_CONFIGURATION_DATA config NXP_IMX_EXTERNAL_SDRAM default y -config INPUT - default y if LVGL - -if INPUT - -config INPUT_FT5336_INTERRUPT - default y - -endif # INPUT - if NETWORKING config NET_L2_ETHERNET @@ -35,39 +25,4 @@ endif # ETH_MCUX endif # NETWORKING -if LVGL - -# LVGL should allocate buffers equal to size of display -config LV_Z_VDB_SIZE - default 100 - -# Enable double buffering -config LV_Z_DOUBLE_VDB - default y - -# Force full refresh. This prevents memory copy associated with partial -# display refreshes, which is not necessary for the eLCDIF driver -config LV_Z_FULL_REFRESH - default y - -config LV_DPI_DEF - default 128 - -config LV_Z_BITS_PER_PIXEL - default 16 - -# Force display buffers to be aligned to cache line size (32 bytes) -config LV_Z_VDB_ALIGN - default 32 - -# Use offloaded render thread -config LV_Z_FLUSH_THREAD - default y - -choice LV_COLOR_DEPTH - default LV_COLOR_DEPTH_16 -endchoice - -endif # LVGL - endif # BOARD_MIMXRT1060_EVK || BOARD_MIMXRT1060_EVKB diff --git a/boards/nxp/mimxrt1060_evk/doc/index.rst b/boards/nxp/mimxrt1060_evk/doc/index.rst index e33336ea986487..0c9fdd6096eb95 100644 --- a/boards/nxp/mimxrt1060_evk/doc/index.rst +++ b/boards/nxp/mimxrt1060_evk/doc/index.rst @@ -115,7 +115,9 @@ already supported, which can also be re-used on this mimxrt1060_evk board: +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | +-----------+------------+-------------------------------------+ -| DISPLAY | on-chip | display | +| DISPLAY | on-chip | eLCDIF. Tested with | +| | | :ref:`rk043fn02h_ct`, and | +| | | :ref:`rk043fn66hs_ctg` shields | +-----------+------------+-------------------------------------+ | FLASH | on-chip | QSPI flash | +-----------+------------+-------------------------------------+ diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts index 08eb8541432c44..92fa9d6d180e5d 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts @@ -8,7 +8,6 @@ #include #include "mimxrt1060_evk-pinctrl.dtsi" -#include #include / { @@ -30,7 +29,6 @@ zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; zephyr,canbus = &flexcan3; - zephyr,display = &lcdif; }; sdram0: memory@80000000 { @@ -39,6 +37,33 @@ reg = <0x80000000 DT_SIZE_M(32)>; }; + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + leds { compatible = "gpio-leds"; green_led: led-1 { @@ -63,11 +88,6 @@ }; }; - lvgl_pointer { - compatible = "zephyr,lvgl-pointer-input"; - input = <&ft5336>; - }; - arduino_header: connector { compatible = "arduino-header-r3"; #gpio-cells = <2>; @@ -96,15 +116,6 @@ <20 0 &gpio1 17 0>, /* D14 */ <21 0 &gpio1 16 0>; /* D15 */ }; - - panel { - compatible = "rocktech,rk043fn02h-ct"; - port { - lcd_panel_in: endpoint { - remote-endpoint = <&lcd_panel_out>; - }; - }; - }; }; arduino_serial: &lpuart3 { @@ -114,46 +125,17 @@ arduino_serial: &lpuart3 { pinctrl-names = "default", "flowcontrol", "sleep"; }; -&lcdif { - status = "okay"; - width = <480>; - height = <272>; - display-timings { - compatible = "zephyr,panel-timing"; - hsync-len = <41>; - hfront-porch = <4>; - hback-porch = <8>; - vsync-len = <10>; - vfront-porch = <4>; - vback-porch = <2>; - de-active= <1>; - pixelclk-active = <1>; - hsync-active = <0>; - vsync-active = <0>; - clock-frequency = <9210240>; - }; - pixel-format = ; - data-bus-width = "16-bit"; +zephyr_lcdif: &lcdif { pinctrl-0 = <&pinmux_lcdif>; pinctrl-names = "default"; - backlight-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; - port { - lcd_panel_out: endpoint { - remote-endpoint = <&lcd_panel_in>; - }; - }; }; +nxp_touch_i2c: &lpi2c1 {}; + arduino_i2c: &lpi2c1 { status = "okay"; pinctrl-0 = <&pinmux_lpi2c1>; pinctrl-names = "default"; - - ft5336: ft5336@38 { - compatible = "focaltech,ft5336"; - reg = <0x38>; - int-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; - }; }; &lpuart1 { @@ -181,9 +163,9 @@ arduino_i2c: &lpi2c1 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; diff --git a/boards/nxp/mimxrt1064_evk/Kconfig.defconfig b/boards/nxp/mimxrt1064_evk/Kconfig.defconfig index 4ec3c9ebe2f906..6454f9b6329c26 100644 --- a/boards/nxp/mimxrt1064_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1064_evk/Kconfig.defconfig @@ -11,16 +11,6 @@ config DEVICE_CONFIGURATION_DATA config NXP_IMX_EXTERNAL_SDRAM default y -config INPUT - default y if LVGL - -if INPUT - -config INPUT_FT5336_INTERRUPT - default y - -endif # INPUT - if NETWORKING config NET_L2_ETHERNET @@ -35,18 +25,4 @@ endif # ETH_MCUX endif # NETWORKING -if LVGL - -config LV_Z_VDB_SIZE - default 16 - -config LV_DPI_DEF - default 128 - -choice LV_COLOR_DEPTH - default LV_COLOR_DEPTH_16 -endchoice - -endif # LVGL - endif # BOARD_MIMXRT1064_EVK diff --git a/boards/nxp/mimxrt1064_evk/doc/index.rst b/boards/nxp/mimxrt1064_evk/doc/index.rst index fb9195693fd294..5974a47edf15be 100644 --- a/boards/nxp/mimxrt1064_evk/doc/index.rst +++ b/boards/nxp/mimxrt1064_evk/doc/index.rst @@ -111,7 +111,9 @@ configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | +-----------+------------+-------------------------------------+ -| DISPLAY | on-chip | display | +| DISPLAY | on-chip | eLCDIF. Tested with | +| | | :ref:`rk043fn02h_ct`, and | +| | | :ref:`rk043fn66hs_ctg` shields | +-----------+------------+-------------------------------------+ | VIDEO | on-chip | video, using CSI | +-----------+------------+-------------------------------------+ diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts index 00980d3cc4f949..6f752552e72929 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts @@ -8,7 +8,6 @@ #include #include "mimxrt1064_evk-pinctrl.dtsi" -#include #include / { @@ -42,6 +41,33 @@ reg = <0x80000000 DT_SIZE_M(32)>; }; + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + leds { compatible = "gpio-leds"; green_led: led-1 { @@ -100,49 +126,17 @@ <20 0 &gpio1 17 0>, /* D14 */ <21 0 &gpio1 16 0>; /* D15 */ }; - - panel { - compatible = "rocktech,rk043fn02h-ct"; - port { - lcd_panel_in: endpoint { - remote-endpoint = <&lcd_panel_out>; - }; - }; - }; }; -arduino_i2c: &lpi2c1 {}; +nxp_touch_i2c: &lpi2c1 {}; -&lcdif { - status = "okay"; - width = <480>; - height = <272>; - display-timings { - compatible = "zephyr,panel-timing"; - hsync-len = <41>; - hfront-porch = <4>; - hback-porch = <8>; - vsync-len = <10>; - vfront-porch = <4>; - vback-porch = <2>; - de-active= <1>; - pixelclk-active = <1>; - hsync-active = <0>; - vsync-active = <0>; - clock-frequency = <9210240>; - }; - pixel-format = ; - data-bus-width = "16-bit"; +zephyr_lcdif: &lcdif { pinctrl-0 = <&pinmux_lcdif>; pinctrl-names = "default"; - backlight-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; - port { - lcd_panel_out: endpoint { - remote-endpoint = <&lcd_panel_in>; - }; - }; }; +nxp_parallel_i2c: &lpi2c1 {}; + &lpi2c1 { status = "okay"; @@ -241,9 +235,9 @@ arduino_serial: &lpuart3 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi index 62d3bd59998e81..e3bb96e47f01c9 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi @@ -5,6 +5,7 @@ */ #include "mimxrt1160_evk-pinctrl.dtsi" +#include #include / { @@ -91,7 +92,7 @@ reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(16)>; is25wp128: is25wp128@0 { compatible = "nxp,imx-flexspi-nor"; - size = <134217728>; + size = ; reg = <0>; spi-max-frequency = <133000000>; status = "okay"; @@ -103,25 +104,24 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 3 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 0x301000>; + reg = <0x00020000 (DT_SIZE_M(7) + DT_SIZE_K(12))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@723000 { label = "image-1"; - reg = <0x00321000 0x300000>; + reg = <0x00723000 DT_SIZE_M(7)>; }; - storage_partition: partition@621000 { + storage_partition: partition@E23000 { label = "storage"; - reg = <0x00621000 DT_SIZE_K(1984)>; + reg = <0x00E23000 (DT_SIZE_M(2) - DT_SIZE_K(140))>; }; }; }; @@ -150,9 +150,9 @@ compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio12 12 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio9 11 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio12 12 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio9 11 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.dts b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.dts index 2f4e842873f082..379db1b1da5ccb 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.dts +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.dts @@ -36,6 +36,21 @@ aliases { watchdog0 = &wdog1; }; + + /* + * This node describes the GPIO pins mapping of the 44-pin camera + * connector, J2 on the EVK. This camera interface is supported + * on several NXP RT11xx EVKs, such as RT1170 and RT1160 EVK and + * is used with an ov5640 camera module available as a Zephyr shield + */ + nxp_cam_connector: cam-connector { + compatible = "nxp,cam-44pins-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <9 0 &gpio11 15 0>, /* Pin 9, RESETB */ + <17 0 &gpio9 25 0>; /* Pin 17, PWDN */ + }; }; &lpuart1 { @@ -97,3 +112,9 @@ zephyr_udc0: &usb1 { &pit2 { status = "okay"; }; + +nxp_cam_i2c: &lpi2c6 {}; + +nxp_mipi_csi: &mipi_csi2rx {}; + +nxp_csi: &csi {}; diff --git a/boards/nxp/mimxrt1170_evk/doc/index.rst b/boards/nxp/mimxrt1170_evk/doc/index.rst index d6a80009e7c792..40643137bdb821 100644 --- a/boards/nxp/mimxrt1170_evk/doc/index.rst +++ b/boards/nxp/mimxrt1170_evk/doc/index.rst @@ -69,6 +69,7 @@ Hardware - Expansion port - Arduino interface + - M.2 WIFI/BT interface - CAN bus connector @@ -144,8 +145,9 @@ RT1170 EVKB (`mimxrt1170_evk@B//cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | WATCHDOG | on-chip | watchdog | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ -| ENET | on-chip | ethernet - 10/100M (ENET_QOS or | Supported (M7) | No support | -| ENET1G | | GigE not supported yet) | | | +| ENET | on-chip | ethernet - 10/100M | Supported (M7) | No support | ++-----------+------------+-------------------------------------+-----------------+-----------------+ +| ENET1G | on-chip | ethernet - 10/100/1000M | Supported (M7) | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ | SAI | on-chip | i2s | Supported | No support | +-----------+------------+-------------------------------------+-----------------+-----------------+ @@ -168,6 +170,11 @@ RT1170 EVKB (`mimxrt1170_evk@B//cm7/cm4`) +-----------+------------+-------------------------------------+-----------------+-----------------+ | PIT | on-chip | pit | Supported (M7) | Supported (M7) | +-----------+------------+-------------------------------------+-----------------+-----------------+ +| VIDEO | on-chip | CSI; MIPI CSI-2 Rx. Tested with | Supported (M7) | Supported (M7) | +| | | :ref:`nxp_btb44_ov5640` shield | | | ++-----------+------------+-------------------------------------+-----------------+-----------------+ +| UART | NXP NW61x | M.2 WIFI/BT module | Unsupported | Supported (M7) | ++-----------+------------+-------------------------------------+-----------------+-----------------+ The default configuration can be found in the defconfig files: :zephyr_file:`boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_defconfig` @@ -243,6 +250,14 @@ The MIMXRT1170 SoC has six pairs of pinmux/gpio controllers. +---------------------------+----------------+------------------+ | GPIO_AD_20_SAI1_RX_DATA00 | SAI1_RX_DATA00 | SAI | +---------------------------+----------------+------------------+ +| GPIO_DISP_B2_10 | LPUART2_TX | M.2 BT HCI | ++---------------------------+----------------+------------------+ +| GPIO_DISP_B2_11 | LPUART2_RX | M.2 BT HCI | ++---------------------------+----------------+------------------+ +| GPIO_DISP_B2_12 | LPUART2_CTS_B | M.2 BT HCI | ++---------------------------+----------------+------------------+ +| GPIO_DISP_B2_13 | LPUART1_RTS_B | M.2 BT HCI | ++---------------------------+----------------+------------------+ Dual Core samples ***************** @@ -287,9 +302,22 @@ cost of reduced resolution Serial Port =========== -The MIMXRT1170 SoC has 12 UARTs. One is configured for the console and the +The MIMXRT1170 SoC has 12 UARTs. ``LPUART1`` is configured for the console, +``LPUART2`` for the Bluetooth Host Controller Interface (BT HCI), and the remaining are not used. +Fetch Binary Blobs +================== + +The board Bluetooth/WiFi module requires fetching some binary blob files, to do +that run the command: + +.. code-block:: console + + west blobs fetch hal_nxp + +.. note:: Only Bluetooth functionality is currently supported. + Programming and Debugging ************************* @@ -444,3 +472,10 @@ should see the following message in the terminal: .. _NXP MCUXpresso for Visual Studio Code: https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-for-visual-studio-code:MCUXPRESSO-VSC + +ENET1G Driver +============= + +Current default of ethernet driver is to use 100M Ethernet instance ENET. +To use the 1G Ethernet instance ENET1G, include the overlay to west build with +the option `-DEXTRA_DTC_OVERLAY_FILE=nxp,enet1g.overlay` instead. diff --git a/boards/nxp/mimxrt1170_evk/dts/nxp,enet1g.overlay b/boards/nxp/mimxrt1170_evk/dts/nxp,enet1g.overlay new file mode 100644 index 00000000000000..cff3f6bad7c803 --- /dev/null +++ b/boards/nxp/mimxrt1170_evk/dts/nxp,enet1g.overlay @@ -0,0 +1,36 @@ +/* + * Copyright 2023-2024 NXP + * + * ENET_1G binding overlay + */ + +/ { + soc { + /delete-node/ ethernet@40424000; + }; +}; + +&enet1g { + status = "okay"; +}; + +&enet1g_mac { + status = "okay"; +}; + +&enet1g_mdio { + status = "okay"; + enet1g_phy: phy@1 { + status = "okay"; + }; +}; + +&enet1g_ptp_clock { + status = "okay"; +}; + +&pinctrl { + /delete-node/ pinmux_enet; + /delete-node/ pinmux_enet_mdio; + /delete-node/ pinmux_ptp; +}; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi index 43b1642da96f91..d33ed7cfb331f8 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi @@ -85,6 +85,64 @@ pinmux_ptp: pinmux_ptp { }; + pinmux_enet1g: pinmux_enet1g { + group0 { + pinmux = <&iomuxc_gpio_disp_b1_11_enet_1g_tx_clk_io>, // ENET_RGMII_TXC + <&iomuxc_gpio_disp_b1_01_enet_1g_rx_clk>; // ENET_RGMII_RXC + bias-disable; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + group1 { + pinmux = <&iomuxc_gpio_disp_b1_09_enet_1g_tdata00>, // ENET_RGMII_TXD0 + <&iomuxc_gpio_disp_b1_08_enet_1g_tdata01>, // ENET_RGMII_TXD1 + <&iomuxc_gpio_disp_b1_07_enet_1g_tdata02>, // ENET_RGMII_TXD2 + <&iomuxc_gpio_disp_b1_06_enet_1g_tdata03>, // ENET_RGMII_TXD3 + <&iomuxc_gpio_disp_b1_10_enet_1g_tx_en>; // ENET_RGMII_TX_EN + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + group2 { + pinmux = <&iomuxc_gpio_disp_b1_02_enet_1g_rdata00>, // ENET_RGMII_RXD0 + <&iomuxc_gpio_disp_b1_03_enet_1g_rdata01>, // ENET_RGMII_RXD1 + <&iomuxc_gpio_disp_b1_04_enet_1g_rdata02>, // ENET_RGMII_RXD2 + <&iomuxc_gpio_disp_b1_05_enet_1g_rdata03>, // ENET_RGMII_RXD3 + <&iomuxc_gpio_disp_b1_00_enet_1g_rx_en>; // ENET_RGMII_RX_EN + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_enet1g_mdio: pinmux_enet1g_mdio { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_13_gpio11_io14>; // ETHPHY_RST_B + drive-strength = "high"; + bias-pull-down; + slew-rate = "slow"; + }; + group1 { + pinmux = <&iomuxc_gpio_disp_b2_12_gpio_mux5_io13>; // RGMII1_PHY_INTB + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + input-enable; + }; + group2 { + pinmux = <&iomuxc_gpio_emc_b2_19_enet_1g_mdc>, // ENET_RGMII_MDC + <&iomuxc_gpio_emc_b2_20_enet_1g_mdio>; // ENET_RGMII_MDIO + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + }; + + pinmux_enet1g_ptp: pinmux_enet1g_ptp { + }; + pinmux_flexcan3: pinmux_flexcan3 { group0 { pinmux = <&iomuxc_lpsr_gpio_lpsr_01_can3_rx>, @@ -232,6 +290,17 @@ }; }; + pinmux_lpuart2_flowcontrol: pinmux_lpuart2_flowcontrol { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_11_lpuart2_rx>, + <&iomuxc_gpio_disp_b2_10_lpuart2_tx>, + <&iomuxc_gpio_disp_b2_12_lpuart2_cts_b>, + <&iomuxc_gpio_disp_b2_13_lpuart2_rts_b>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + pinmux_sai1: pinmux_sai1 { group0 { pinmux = <&iomuxc_gpio_ad_17_sai1_mclk>, diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi index e70890f911d4f2..c479300c8a9d0f 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi @@ -5,6 +5,7 @@ */ #include "mimxrt1170_evk-pinctrl.dtsi" +#include #include / { @@ -113,9 +114,9 @@ compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - mc,reset-gpio = <&gpio12 12 GPIO_ACTIVE_HIGH>; - mc,interrupt-gpio = <&gpio9 11 GPIO_ACTIVE_HIGH>; - mc,interface-type = "rmii"; + reset-gpios = <&gpio12 12 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio9 11 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; }; }; @@ -125,6 +126,34 @@ pinctrl-names = "default"; }; +&enet1g_mac { + status = "disabled"; + pinctrl-0 = <&pinmux_enet1g>; + pinctrl-names = "default"; + phy-handle = <&enet1g_phy>; + phy-connection-type = "rgmii"; + zephyr,random-mac-address; +}; + +&enet1g_mdio { + status = "disabled"; + pinctrl-0 = <&pinmux_enet1g_mdio>; + pinctrl-names = "default"; + enet1g_phy: phy@1 { + compatible = "realtek,rtl8211f"; + reg = <1>; + status = "disabled"; + reset-gpios = <&gpio11 14 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + }; +}; + +&enet1g_ptp_clock { + status = "disabled"; + pinctrl-0 = <&pinmux_enet1g_ptp>; + pinctrl-names = "default"; +}; + &csi { pinctrl-0 = <&pinmux_csi>; pinctrl-names = "default"; @@ -190,7 +219,7 @@ reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(16)>; is25wp128: is25wp128@0 { compatible = "nxp,imx-flexspi-nor"; - size = <134217728>; + size = ; reg = <0>; spi-max-frequency = <133000000>; status = "okay"; @@ -207,20 +236,20 @@ label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 3 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 0x301000>; + reg = <0x00020000 (DT_SIZE_M(7) + DT_SIZE_K(12))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@723000 { label = "image-1"; - reg = <0x00321000 0x300000>; + reg = <0x00723000 DT_SIZE_M(7)>; }; - storage_partition: partition@621000 { + storage_partition: partition@E23000 { label = "storage"; - reg = <0x00621000 DT_SIZE_K(1984)>; + reg = <0x00E23000 (DT_SIZE_M(2) - DT_SIZE_K(140))>; }; }; }; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.overlay b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.overlay index c92d197f548dee..b65621ee632610 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.overlay +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.overlay @@ -22,9 +22,8 @@ status = "okay"; reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(64)>; w25q512nw:w25q512nw@0 { - /* IS25WP128 flash chip not currently enabled */ compatible = "nxp,imx-flexspi-nor"; - size = ; + size = ; reg = <0>; spi-max-frequency = <133000000>; status = "okay"; @@ -32,10 +31,6 @@ erase-block-size = <4096>; write-block-size = <1>; - /* - * Partitions are present to support dual core operation. - * as flash write is not supported, MCUBoot is not enabled. - */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -45,20 +40,20 @@ label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 3 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 0x301000>; + reg = <0x00020000 (DT_SIZE_M(7) + DT_SIZE_K(12))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@723000 { label = "image-1"; - reg = <0x00321000 0x300000>; + reg = <0x00723000 DT_SIZE_M(7)>; }; - storage_partition: partition@621000 { + storage_partition: partition@E23000 { label = "storage"; - reg = <0x00621000 DT_SIZE_K(1984)>; + reg = <0x00E23000 (DT_SIZE_M(50) - DT_SIZE_K(140))>; }; }; }; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts index 95eff6eb715f58..a9afb3fa4c8fe0 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts @@ -59,6 +59,21 @@ <32 0 &gpio11 16 0>, /* Pin 32, PWR_EN */ <34 0 &gpio9 29 0>; /* Pin 34, BL_PWM */ }; + + /* + * This node describes the GPIO pins mapping of the 44-pin camera + * connector, J2 on the EVK. This camera interface is supported + * on several NXP RT11xx EVKs, such as RT1170 and RT1160 EVK and + * is used with an ov5640 camera module available as a Zephyr shield + */ + nxp_cam_connector: cam-connector { + compatible = "nxp,cam-44pins-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <9 0 &gpio11 15 0>, /* Pin 9, RESETB */ + <17 0 &gpio9 25 0>; /* Pin 17, PWDN */ + }; }; zephyr_lcdif: &lcdif {}; @@ -146,3 +161,9 @@ zephyr_udc0: &usb1 { &pit2 { status = "okay"; }; + +nxp_cam_i2c: &lpi2c6 {}; + +nxp_mipi_csi: &mipi_csi2rx {}; + +nxp_csi: &csi {}; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml index c7e846adf6ab30..da6ffa5b9c7079 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml @@ -28,4 +28,5 @@ supported: - spi - usb_device - watchdog + - video vendor: nxp diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.overlay index a43339de27b615..bc7995fcb4e34f 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.overlay +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -7,8 +7,10 @@ / { chosen { zephyr,flash = &w25q512nw; - /delete-property/ zephyr,flash-controller; - /delete-property/ zephyr,code-partition; + zephyr,flash-controller = &w25q512nw; + zephyr,flash = &w25q512nw; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_uart; }; aliases { @@ -23,9 +25,8 @@ status = "okay"; reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(64)>; w25q512nw:w25q512nw@0 { - /* IS25WP128 flash chip not currently enabled */ compatible = "nxp,imx-flexspi-nor"; - size = ; + size = ; reg = <0>; spi-max-frequency = <133000000>; status = "okay"; @@ -33,10 +34,6 @@ erase-block-size = <4096>; write-block-size = <1>; - /* - * Partitions are present to support dual core operation. - * as flash write is not supported, MCUBoot is not enabled. - */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -46,20 +43,20 @@ label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 3 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 0x301000>; + reg = <0x00020000 (DT_SIZE_M(7) + DT_SIZE_K(12))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@723000 { label = "image-1"; - reg = <0x00321000 0x300000>; + reg = <0x00723000 DT_SIZE_M(7)>; }; - storage_partition: partition@621000 { + storage_partition: partition@E23000 { label = "storage"; - reg = <0x00621000 DT_SIZE_K(1984)>; + reg = <0x00E23000 (DT_SIZE_M(50) - DT_SIZE_K(140))>; }; }; }; @@ -79,3 +76,29 @@ status = "okay"; }; }; + +m2_hci_uart: &lpuart2 { + pinctrl-0 = <&pinmux_lpuart2_flowcontrol>; + pinctrl-1 = <&pinmux_lpuart2_sleep>; + pinctrl-names = "default", "sleep"; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + + m2_bt_module { + compatible = "nxp,bt-hci-uart"; + sdio-reset-gpios = <&gpio9 15 GPIO_ACTIVE_HIGH>; + w-disable-gpios = <&gpio9 30 GPIO_ACTIVE_HIGH>; + hci-operation-speed = <115200>; + hw-flow-control; + fw-download-primary-speed = <115200>; + fw-download-secondary-speed = <3000000>; + fw-download-secondary-flowcontrol; + }; + }; +}; + +&m2_hci_uart { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml index 5cdfdf97c87571..62eeec200ea66a 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml @@ -26,4 +26,5 @@ supported: - spi - usb_device - watchdog + - video vendor: nxp diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts index eccf7d453653f3..c700bfe809fa94 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts @@ -407,17 +407,20 @@ zephyr_udc0: &usbhs { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; + /* The MCUBoot swap-move algorithm uses the last 98 sectors + * of the primary slot0 for swap status and move. + */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 DT_SIZE_K(3076)>; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(98 * 4))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@322000 { label = "image-1"; - reg = <0x00321000 DT_SIZE_K(3072)>; + reg = <0x00382000 DT_SIZE_M(3)>; }; - storage_partition: partition@621000 { + storage_partition: partition@622000 { label = "storage"; - reg = <0x00621000 DT_SIZE_M(57)>; + reg = <0x00682000 (DT_SIZE_M(58) - DT_SIZE_K(520))>; }; }; }; diff --git a/boards/nxp/mimxrt685_evk/doc/index.rst b/boards/nxp/mimxrt685_evk/doc/index.rst index 109dfde16e6858..4e8f9d79f516bd 100644 --- a/boards/nxp/mimxrt685_evk/doc/index.rst +++ b/boards/nxp/mimxrt685_evk/doc/index.rst @@ -110,7 +110,7 @@ already supported, which can also be re-used on this mimxrt685_evk board: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/nxp/mimxrt685_evk/mimxrt685_evk_defconfig` +:zephyr_file:`boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33_defconfig` Other hardware features are not currently supported by the port. @@ -363,7 +363,7 @@ steps: https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i-mx-rt-crossover-mcus/i-mx-rt600-crossover-mcu-with-arm-cortex-m33-and-dsp-cores:i.MX-RT600 .. _i.MX RT685 Datasheet: - https://www.nxp.com/docs/en/data-sheet/DS-RT600.pdf + https://www.nxp.com/docs/en/data-sheet/RT600.pdf .. _i.MX RT685 Reference Manual: https://www.nxp.com/webapp/Download?colCode=UM11147 diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts index a7df8a693efdd7..3464ef6f10a6ca 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts @@ -268,17 +268,20 @@ i2s1: &flexcomm3 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; + /* The MCUBoot swap-move algorithm uses the last 98 sectors + * of the primary slot0 for swap status and move. + */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 DT_SIZE_K(3076)>; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(98 * 4))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@322000 { label = "image-1"; - reg = <0x00321000 DT_SIZE_K(3072)>; + reg = <0x00382000 DT_SIZE_M(3)>; }; - storage_partition: partition@621000 { + storage_partition: partition@622000 { label = "storage"; - reg = <0x00621000 DT_SIZE_M(57)>; + reg = <0x00682000 (DT_SIZE_M(58) - DT_SIZE_K(520))>; }; }; }; diff --git a/boards/nxp/mr_canhubk3/doc/index.rst b/boards/nxp/mr_canhubk3/doc/index.rst index f398e1708575c5..67787ae3ad53bd 100644 --- a/boards/nxp/mr_canhubk3/doc/index.rst +++ b/boards/nxp/mr_canhubk3/doc/index.rst @@ -60,6 +60,7 @@ EMAC on-chip ethernet mdio eMIOS on-chip pwm EDMA on-chip dma +FLEXIO PWM on-chip pwm ============ ========== ================================ The default configuration can be found in the Kconfig file diff --git a/boards/nxp/mr_canhubk3/mr_canhubk3-pinctrl.dtsi b/boards/nxp/mr_canhubk3/mr_canhubk3-pinctrl.dtsi index 49c4d164c817c4..9a9e7894a7d04b 100644 --- a/boards/nxp/mr_canhubk3/mr_canhubk3-pinctrl.dtsi +++ b/boards/nxp/mr_canhubk3/mr_canhubk3-pinctrl.dtsi @@ -300,6 +300,13 @@ }; }; + flexio0_pwm_default: flexio0_pwm_default { + group1 { + pinmux = , ; + output-enable; + }; + }; + qdec_s32: qdec_s32 { group1 { pinmux = , diff --git a/boards/nxp/mr_canhubk3/mr_canhubk3.dts b/boards/nxp/mr_canhubk3/mr_canhubk3.dts index ba74e255f625e2..66f7939340e3de 100644 --- a/boards/nxp/mr_canhubk3/mr_canhubk3.dts +++ b/boards/nxp/mr_canhubk3/mr_canhubk3.dts @@ -40,6 +40,7 @@ watchdog0 = &fs26_wdt; /* For pwm test suites */ pwm-0 = &emios0_pwm; + pwm-1 = &flexio0_pwm; red-pwm-led = &user_led1_red_pwm; green-pwm-led = &user_led1_green_pwm; blue-pwm-led = &user_led1_blue_pwm; @@ -616,6 +617,27 @@ }; }; +&flexio0 { + status = "okay"; + + flexio0_pwm: flexio0_pwm { + pinctrl-0 = <&flexio0_pwm_default>; + pinctrl-names = "default"; + status = "okay"; + + pwm_0 { + pin-id = <19>; + prescaler = <1>; + }; + + pwm_1 { + pin-id = <11>; + prescaler = <1>; + }; + }; + +}; + &lcu1 { status = "okay"; }; diff --git a/boards/nxp/rd_rw612_bga/Kconfig.defconfig b/boards/nxp/rd_rw612_bga/Kconfig.defconfig index 376f96da2b3328..e4c25b8924296c 100644 --- a/boards/nxp/rd_rw612_bga/Kconfig.defconfig +++ b/boards/nxp/rd_rw612_bga/Kconfig.defconfig @@ -5,6 +5,9 @@ if BOARD_RD_RW612_BGA +config FLASH_LOAD_SIZE + default 0x400000 if !BOOTLOADER_MCUBOOT && !NXP_MONOLITHIC_BT + if LVGL # Enable DMA for LCDIC @@ -34,4 +37,11 @@ endif # LVGL config INPUT_FT5336_INTERRUPT default y if INPUT +if DT_HAS_NXP_ENET_MAC_ENABLED && NETWORKING + +config NET_L2_ETHERNET + default y + +endif # DT_HAS_NXP_ENET_MAC_ENABLED && NETWORKING + endif # BOARD_RD_RW612_BGA diff --git a/boards/nxp/rd_rw612_bga/board.yml b/boards/nxp/rd_rw612_bga/board.yml index fe2573bfdbb4f6..3316d695614207 100644 --- a/boards/nxp/rd_rw612_bga/board.yml +++ b/boards/nxp/rd_rw612_bga/board.yml @@ -3,3 +3,5 @@ board: vendor: nxp socs: - name: rw612 + variants: + - name: ethernet diff --git a/boards/nxp/rd_rw612_bga/doc/index.rst b/boards/nxp/rd_rw612_bga/doc/index.rst index 42783abb9bbd8c..51547c9e354000 100644 --- a/boards/nxp/rd_rw612_bga/doc/index.rst +++ b/boards/nxp/rd_rw612_bga/doc/index.rst @@ -66,6 +66,8 @@ Supported Features | PM | on-chip | power management; uses SoC Power | | | | Modes 1 and 2 | +-----------+------------+-----------------------------------+ +| BLE | on-chip | Bluetooth | ++-----------+------------+-----------------------------------+ The default configuration can be found in the defconfig file: @@ -73,6 +75,16 @@ The default configuration can be found in the defconfig file: Other hardware features are not currently supported +Fetch Binary Blobs +****************** + +To support Bluetooth, rd_rw612_bga requires fetching binary blobs, which can be +achieved by running the following command: + +.. code-block:: console + + west blobs fetch hal_nxp + Programming and Debugging ************************* @@ -134,9 +146,57 @@ should see the following message in the terminal: ***** Booting Zephyr OS zephyr-v3.6.0 ***** Hello World! rd_rw612_bga +Bluetooth +********* + +BLE functionality requires to fetch binary blobs, so make sure to follow +the ``Fetch Binary Blobs`` section first. + +Those binary blobs can be used in two different ways, depending if :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` +is enabled or not: + +- :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` is enabled (default): + +The required binary blob will be linked with the application image directly, forming +one single monolithic image. +The user has nothing else to do other than flashing the application to the board. + +- :kconfig:option:`CONFIG_NXP_MONOLITHIC_BT` is disabled: + +In this case, the BLE blob won't be linked with the application, so the user needs to manually +flash the BLE binary blob to the board at the address ``0x18540000``. +The binary blob will be located here: ``/modules/hal/nxp/zephyr/blobs/rw61x/rw61x_sb_ble_a2.bin`` + +Board variants +************** + +Ethernet +======== + +To use ethernet on the RD_RW612_BGA board, you first need to make the following +modifications to the board hardware: + +Add resistors: +- R485 +- R486 +- R487 +- R488 +- R489 +- R491 +- R490 +Remove resistors: +- R522 +- R521 +- R520 +- R524 +- R523 +- R508 +- R505 + +Then, build for the board target `rd_rw612_bga//ethernet`. Resources -========= +********* .. _RW612 Website: https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radiobr1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612 diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga-pinctrl.dtsi b/boards/nxp/rd_rw612_bga/rd_rw612_bga-pinctrl.dtsi index 31a3303d5d6fe8..78193e6b5122ac 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga-pinctrl.dtsi +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga-pinctrl.dtsi @@ -94,4 +94,22 @@ bias-pull-down; }; }; + + pinmux_enet: pinmux_enet { + group0 { + pinmux = ; + slew-rate = "fast"; + }; + }; + + pinmux_mdio: pinmux_mdio { + group0 { + pinmux = ; + slew-rate = "fast"; + }; + }; }; diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dts b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dts index 4a3f958849422d..41552feecff65e 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dts +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dts @@ -6,10 +6,4 @@ /dts-v1/; -#include #include "rd_rw612_bga.dtsi" - -/ { - model = "nxp,rd_rw612_bga"; - compatible = "nxp,rd_rw612_bga"; -}; diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi index 1fa058bfb13133..7260dd4e2db3af 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi @@ -4,10 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "rd_rw612_bga-pinctrl.dtsi" #include / { + model = "nxp,rd_rw612_bga"; + compatible = "nxp,rd_rw612_bga"; aliases { usart-0 = &flexcomm3; diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.dts b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.dts new file mode 100644 index 00000000000000..2a793e6cdcab75 --- /dev/null +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.dts @@ -0,0 +1,47 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "rd_rw612_bga.dtsi" + +/* + * To use ethernet on RD_RW612_BGA board: + * + * Load R485, R486, R487, R488, R489, R491, R490, + * R522, R521, R520, R524, R523, R508, R505 + * Remove R518, R507, R506 + */ +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_mdio>; + pinctrl-names = "default"; + phy: phy@2 { + compatible = "microchip,ksz8081"; + reg = <2>; + status = "okay"; + reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; + int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; + +/* XTAL is disconnected */ +/* TODO: this should be uncommented once it is added */ +/* + * &rtc { + * status = "disabled"; + * }; + */ diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml new file mode 100644 index 00000000000000..19d26ea8162f07 --- /dev/null +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml @@ -0,0 +1,20 @@ +# +# Copyright 2023 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: rd_rw612_bga/rw612/ethernet +name: NXP RD_RW612_BGA ETHERNET +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 960 +flash: 65536 +supported: + - netif:eth +testing: + default: false diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet_defconfig b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet_defconfig new file mode 100644 index 00000000000000..b987fa24dc09b3 --- /dev/null +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet_defconfig @@ -0,0 +1,15 @@ +# +# Copyright 2022 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts b/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts index 8d2b01c44ba130..729219dd670e13 100644 --- a/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts +++ b/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts @@ -236,23 +236,23 @@ zephyr_udc0: &usbotg { boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x00010000>; + reg = <0x00000000 DT_SIZE_K(64)>; read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 0x000E9000>; + reg = <0x00010000 (DT_SIZE_K(928) + DT_SIZE_K(8))>; }; - slot1_partition: partition@F9000 { + slot1_partition: partition@FA000 { label = "image-1"; - reg = <0x000F9000 0x000E8000>; + reg = <0x000FA000 DT_SIZE_K(928)>; }; - storage_partition: partition@1e1000 { + storage_partition: partition@1E2000 { label = "storage"; - reg = <0x001e1000 0x0001f000>; + reg = <0x001E2000 DT_SIZE_K(120)>; }; }; }; diff --git a/boards/nxp/twr_ke18f/twr_ke18f.dts b/boards/nxp/twr_ke18f/twr_ke18f.dts index e0f3e1d242c0ea..18bbbe72769751 100644 --- a/boards/nxp/twr_ke18f/twr_ke18f.dts +++ b/boards/nxp/twr_ke18f/twr_ke18f.dts @@ -335,25 +335,25 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0xc000>; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ - slot0_partition: partition@c000 { + slot0_partition: partition@10000 { label = "image-0"; - reg = <0x0000c000 0x37000>; + reg = <0x00010000 (DT_SIZE_K(200) + DT_SIZE_K(8))>; }; - slot1_partition: partition@43000 { + slot1_partition: partition@44000 { label = "image-1"; - reg = <0x00043000 0x36000>; + reg = <0x00044000 DT_SIZE_K(200)>; }; - storage_partition: partition@79000 { + storage_partition: partition@76000 { label = "storage"; - reg = <0x00079000 0x00007000>; + reg = <0x00076000 DT_SIZE_K(40)>; }; }; }; diff --git a/boards/nxp/twr_kv58f220m/twr_kv58f220m.dts b/boards/nxp/twr_kv58f220m/twr_kv58f220m.dts index f79c840942c923..2a59adfd6ef3a0 100644 --- a/boards/nxp/twr_kv58f220m/twr_kv58f220m.dts +++ b/boards/nxp/twr_kv58f220m/twr_kv58f220m.dts @@ -113,25 +113,25 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x10000>; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; }; - /* Note slot 0 has one additional sector, - * this is intended for use with the swap move algorithm + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. */ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 0x68000>; + reg = <0x00010000 (DT_SIZE_K(416) + DT_SIZE_K(16))>; }; - slot1_partition: partition@78000 { + slot1_partition: partition@7C000 { label = "image-1"; - reg = <0x00078000 0x66000>; + reg = <0x0007C000 DT_SIZE_K(416)>; }; - storage_partition: partition@de000 { - label = "image-scratch"; - reg = <0x000de000 0x22000>; + storage_partition: partition@E4000 { + label = "storage"; + reg = <0x000E4000 DT_SIZE_K(112)>; }; }; }; diff --git a/boards/nxp/vmu_rt1170/Kconfig.defconfig b/boards/nxp/vmu_rt1170/Kconfig.defconfig index f0f7bffa888b06..4bf5b36250753b 100644 --- a/boards/nxp/vmu_rt1170/Kconfig.defconfig +++ b/boards/nxp/vmu_rt1170/Kconfig.defconfig @@ -26,9 +26,6 @@ if NETWORKING config NET_L2_ETHERNET default y if CPU_CORTEX_M7 # No cache memory support is required for driver -config ETH_MCUX_PHY_RESET - default n - config ETH_MCUX_RMII_EXT_CLK default y diff --git a/boards/nxp/vmu_rt1170/doc/index.rst b/boards/nxp/vmu_rt1170/doc/index.rst index a683fc8ad1ed49..89a2599aee2e1d 100644 --- a/boards/nxp/vmu_rt1170/doc/index.rst +++ b/boards/nxp/vmu_rt1170/doc/index.rst @@ -61,6 +61,10 @@ Hardware - CAN bus JST-GH connectors +- RC IN + + - RC input connector for SBUS compatible RC receivers + For more information about the MIMXRT1176 SoC and VMU RT1170 board, see these references: @@ -94,7 +98,7 @@ following hardware features: +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-----------+------------+-------------------------------------+ -| PWM | on-chip | pwm | +| PWM | on-chip | flexpwm, qtmr | +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ @@ -125,7 +129,7 @@ following hardware features: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/nxp/vmu_rt1170/vmu_rt1170_defconfig` +:zephyr_file:`boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7_defconfig` Other hardware features are not currently supported by the port. @@ -134,71 +138,337 @@ Connections and I/Os The MIMXRT1170 SoC has six pairs of pinmux/gpio controllers. -+---------------------------+----------------+------------------+ -| Name | Function | Usage | -+---------------------------+----------------+------------------+ -| WAKEUP | GPIO | SW7 | -+---------------------------+----------------+------------------+ -| GPIO_AD_04 | GPIO | LED | -+---------------------------+----------------+------------------+ -| GPIO_AD_24 | LPUART1_TX | UART Console | -+---------------------------+----------------+------------------+ -| GPIO_AD_25 | LPUART1_RX | UART Console | -+---------------------------+----------------+------------------+ -| GPIO_LPSR_00 | CAN3_TX | flexcan | -+---------------------------+----------------+------------------+ -| GPIO_LPSR_01 | CAN3_RX | flexcan | -+---------------------------+----------------+------------------+ -| GPIO_AD_29 | SPI1_CS0 | spi | -+---------------------------+----------------+------------------+ -| GPIO_AD_28 | SPI1_CLK | spi | -+---------------------------+----------------+------------------+ -| GPIO_AD_30 | SPI1_SDO | spi | -+---------------------------+----------------+------------------+ -| GPIO_AD_31 | SPI1_SDI | spi | -+---------------------------+----------------+------------------+ -| GPIO_AD_08 | LPI2C1_SCL | i2c | -+---------------------------+----------------+------------------+ -| GPIO_AD_09 | LPI2C1_SDA | i2c | -+---------------------------+----------------+------------------+ -| GPIO_LPSR_05 | LPI2C5_SCL | i2c | -+---------------------------+----------------+------------------+ -| GPIO_LPSR_04 | LPI2C5_SDA | i2c | -+---------------------------+----------------+------------------+ -| GPIO_AD_04 | FLEXPWM1_PWM2 | pwm | -+---------------------------+----------------+------------------+ -| GPIO_AD_32 | ENET_MDC | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_AD_33 | ENET_MDIO | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_02 | ENET_TX_DATA00 | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_03 | ENET_TX_DATA01 | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_04 | ENET_TX_EN | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_05 | ENET_REF_CLK | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_06 | ENET_RX_DATA00 | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_07 | ENET_RX_DATA01 | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_08 | ENET_RX_EN | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_DISP_B2_09 | ENET_RX_ER | Ethernet | -+---------------------------+----------------+------------------+ -| GPIO_AD_17_SAI1_MCLK | SAI_MCLK | SAI | -+---------------------------+----------------+------------------+ -| GPIO_AD_21_SAI1_TX_DATA00 | SAI1_TX_DATA | SAI | -+---------------------------+----------------+------------------+ -| GPIO_AD_22_SAI1_TX_BCLK | SAI1_TX_BCLK | SAI | -+---------------------------+----------------+------------------+ -| GPIO_AD_23_SAI1_TX_SYNC | SAI1_TX_SYNC | SAI | -+---------------------------+----------------+------------------+ -| GPIO_AD_17_SAI1_MCLK | SAI1_MCLK | SAI | -+---------------------------+----------------+------------------+ -| GPIO_AD_20_SAI1_RX_DATA00 | SAI1_RX_DATA00 | SAI | -+---------------------------+----------------+------------------+ ++-----------------+--------------------------------+----------------------------+ +| Name | Function | Usage | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_00 | FLEXCAN2_TX | CAN2_TX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_01 | FLEXCAN2_RX | CAN2_RX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_02 | LPUART8_TXD | UART8_TX_TELEM2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_03 | LPUART8_RXD | UART8_RX_TELEM2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_04 | LPUART8_CTS_B | UART8_CTS_TELEM2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_05 | LPUART8_RTS_B | UART8_RTS_TELEM2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_06 | FLEXCAN1_TX | CAN1_TX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_07 | FLEXCAN1_RX | CAN1_RX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_08 | LPI2C1_SCL | I2C1_SCL_GPS1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_09 | LPI2C1_SDA | I2C1_SDA_GPS1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_10 | LPADC1_CH2A | SCALED_VDD_3V3_SENSORS1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_11 | LPADC1_CH2B | SCALED_VDD_3V3_SENSORS2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_12 | LPADC1_CH3A | SCALED_VDD_3V3_SENSORS3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_13 | LPADC1_CH3B | SCALED_V5 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_14 | LPADC1_CH4A | ADC_6V6 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_15 | LPUART10_TXD | UART10_TX_TELEM3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_16 | LPADC1_CH5A | ADC_3V3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_17 | LPADC1_CHB | SCALED_VDD_3V3_SENSORS4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_18 | LPI2C2_SCL | I2C2_SCL_GPS2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_19 | LPI2C2_SDA | I2C2_SDA_GPS2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_20 | GPIO3_IO19 | SPI1_DRDY1_SENSOR1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_21 | GPIO3_IO20 | SPI3_DRDY1_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_22 | LPADC2_CH2A | HW_VER_SENSE | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_23 | LPADC2_CH2B | HW_REV_SENSE | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_24 | LPSPI2_SCK | SPI2_SCK_SENSOR2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_25 | LPSPI2_PCS0 | SPI2_nCS0_SENSOR2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_26 | LPSPI2_SOUT | SPI2_MOSI_SENSOR2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_27 | LPSPI2_SIN | SPI2_MISO_SENSOR2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_28 | LPUART5_TXD | UART5_TX_GPS2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_29 | LPUART5_RXD | UART5_RX_GPS2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_30 | LPUART3_TXD | UART3_TX_GPS1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_31 | LPUART3_RXD | UART3_RX_GPS1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_32 | USDHC1_CD_B | USDHC1_CD | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_33 | LPUART10_RXD | UART10_RX_TELEM3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_34 | LPUART10_CTS_B | UART10_CTS_TELEM3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_AD_35 | LPUART10_RTS_B | UART10_RTS_TELEM3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_00 | ENET_1G_RX_EN | ETH_CRS_DV | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_01 | ENET_1G_RX_ER | ETH_RX_ER | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_02 | LPUART1_TXD | UART1_TX_DEBUG | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_03 | LPUART1_RXD | UART1_RX_DEBUG | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_04 | LPUART4_RXD | UART4_RX_TELEM1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_05 | LPUART4_CTS_B | UART4_CTS_TELEM1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_06 | LPUART4_TXD | UART4_TX_TELEM1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_07 | LPUART4_RTS_B | UART4_RTS_TELEM1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_08 | ENET_1G_TDATA1 | ETH_TXD1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_09 | ENET_1G_TDATA0 | ETH_TXD0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_10 | ENET_1G_TX_EN | ETH_TX_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B1_11 | ENET_1G_REF_CLK | ETH_REF_CLK | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_00 | GPIO5_IO01 | nLED_RED | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_01 | GPIO5_IO02 | nLED_GREEN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_02 | ARM_TRACE0 | TRACED0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_03 | ARM_TRACE1 | TRACED1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_04 | ARM_TRACE2 | TRACED2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_05 | ARM_TRACE3 | TRACED3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_06 | ARM_TRACE_CLK | TRACECLK | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_07 | ARM_TRACE_SWO | TRACESWO | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_08 | GPIO5_IO09 | ETH_POWER_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_09 | GPIO5_IO10 | ETH_PHY_nINT | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_10 | LPI2C3_SCL | I2C3_SCL_FMU | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_11 | LPI2C3_SDA | I2C3_SDA_FMU | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_12 | LPSPI4_SCK | SPI4_SCK_SENSOR4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_13 | LPSPI4_SIN | SPI4_MISO_SENSOR4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_14 | LPSPI4_SOUT | SPI4_MOSI_SENSOR4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_DISP_B2_15 | LPSPI4_PCS0 | SPI4_nCS0_SENSOR4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_00 | FLEXPWM4_PWM0_A + FLEXIO1_IO00 | FMU_CH11 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_01 | GPIO1_IO01 | VDD_3V3_SD_CARD_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_02 | FLEXPWM4_PWM1_A + FLEXIO1_IO02 | FMU_CH12 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_03 | GPIO1_IO03 | FMU_nSAFETY_SWITCH_LED_OUT | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_04 | GPIO1_IO04 | NFC_GPIO | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_05 | GPIO1_IO05 | SPI6_DRDY1_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_06 | FLEXPWM2_PWM0_A + FLEXIO1_IO06 | FMU_CH4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_07 | GPIO1_IO07 | SPI6_DRDY2_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_08 | FLEXPWM2_PWM1_A + FLEXIO1_IO08 | FMU_CH5 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_09 | GPT5_CAPTURE1 | FMU_PPM_INPUT | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_10 | FLEXPWM2_PWM2_A + FLEXIO1_IO10 | FMU_CH6 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_11 | GPIO1_IO11 | SPI6_nRESET_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_12 | GPIO1_IO12 | VDD_5V_HIPOWER_nOC | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_13 | GPIO1_IO13 | nLED_BLUE | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_14 | GPIO1_IO14 | VDD_3V3_SENSORS3_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_15 | GPIO1_IO15 | VDD_5V_PERIPH_nOC | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_16 | GPIO1_IO16 | SPI4_DRDY1_SENSOR4 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_17 | GPIO1_IO17 | nARMED | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_18 | TMR2_TIMER0 | SPIX_SYNC | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_19 | FLEXPWM2_PWM3_A + FLEXIO1_IO19 | FMU_CH7 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_20 | TMR4_TIMER0 | FMU_CAP1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_21 | FLEXPWM3_PWM3_A + FLEXIO1_IO21 | FMU_CH10 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_22 | GPIO1_IO22 | VDD_3V3_SENSORS2_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_23 | FLEXPWM1_PWM0_A | FMU_CH1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_24 | GPIO1_IO24 | FMU_SAFETY_SWITCH_IN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_25 | FLEXPWM1_PWM1_A + FLEXIO1_IO25 | FMU_CH2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_26 | GPIO1_IO26 | HW_VER_REV_DRIVE | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_27 | FLEXPWM1_PWM2_A + FLEXIO1_IO27 | FMU_CH3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_28 | GPIO1_IO28 | nPOWER_IN_A | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_29 | FLEXPWM3_PWM0_A + FLEXIO1_IO29 | FMU_CH8 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_30 | GPIO1_IO30 | nPOWER_IN_B | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_31 | FLEXPWM3_PWM1_A + FLEXIO1_IO31 | FMU_CH9 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_32 | GPIO2_IO00 | nPOWER_IN_C | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_33 | GPIO2_IO01 | VDD_3V3_SENSORS1_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_34 | GPIO2_IO02 | VDD_5V_PERIPH_nEN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_35 | GPIO2_IO03 | I2C2_DRDY1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_36 | GPIO2_IO04 | VDD_3V3_SENSORS4_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_37 | GPIO2_IO05 | VDD_5V_HIPOWER_nEN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_38 | GPIO2_IO06 | VDD_3V3_SPEKTRUM_POWER_EN | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_39 | GPIO2_IO07 | SPI2_DRDY1_SENSOR2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_40 | LPUART6_TXD | UART6_TX_TO_IO__RC_INPUT | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B1_41 | LPUART6_RXD | UART6_RX_FROM_IO__NC | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_00 | LPSPI1_SCK | SPI1_SCK_SENSOR1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_01 | LPSPI1_PCS0 | SPI1_nCS0_SENSOR1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_02 | LPSPI1_SOUT | SPI1_MOSI_SENSOR1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_03 | LPSPI1_SIN | SPI1_MISO_SENSOR1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_04 | LPSPI3_SCK | SPI3_SCK_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_05 | LPSPI3_PCS0 | SPI3_nCS0_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_06 | LPSPI3_SOUT | SPI3_MOSI_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_07 | LPSPI3_SIN | SPI3_MISO_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_08 | LPSPI3_PCS1 | SPI3_nCS1_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_09 | TMR1_TIMER0 | BUZZER_1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_10 | FLEXSPI2_A_SCLK | FLEXSPI2_SCK_FRAM | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_11 | FLEXSPI2_A_SS0_B | FLEXSPI2_nCS0_FRAM | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_12 | GPIO2_IO22 | GPIO_EMC_B2_12 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_13 | FLEXSPI2_A_DATA0 | FLEXSPI2_DATA0_FRAM | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_14 | FLEXSPI2_A_DATA1 | FLEXSPI2_DATA1_FRAM | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_15 | ENET_1G_RDATA0 | ETH_RXD0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_16 | ENET_1G_RDATA1 | ETH_RXD1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_17 | TMR3_TIMER0 | HEATER | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_18 | GPIO2_IO28 | SPI3_DRDY2_SENSOR3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_19 | ENET_1G_MDC | ETH_MDC | ++-----------------+--------------------------------+----------------------------+ +| GPIO_EMC_B2_20 | ENET_1G_MDIO | ETH_MDIO | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_00 | FLEXCAN3_TX | CAN3_TX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_01 | FLEXCAN3_RX | CAN3_RX | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_02 | SRC_BOOT_MODE00 | BT_MODE0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_03 | SRC_BOOT_MODE01 | BT_MODE1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_04 | LPUART11_TXD | UART11_TX_EXTERNAL2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_05 | LPUART11_RXD | UART11_RX_EXTERNAL2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_06 | LPI2C6_SDA | I2C6_SDA_EXTERNAL2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_07 | LPI2C6_SCL | I2C6_SCL_EXTERNAL2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_08 | LPSPI6_PCS1 | SPI6_nCS1_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_09 | LPSPI6_PCS0 | SPI6_nCS0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_10 | LPSPI6_SCK | SPI6_SCK_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_11 | LPSPI6_SOUT | SPI6_MOSI_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_12 | LPSPI6_SIN | SPI6_MISO_EXTERNAL1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_13 | JTAG_MOD | NC_JTAG_MOD_PD | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_14 | SWD_CLK | FMU_SWCLK | ++-----------------+--------------------------------+----------------------------+ +| GPIO_LPSR_15 | SWD_DIO | FMU_SWDIO | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_00 | USDHC1_CMD | USDHC1_CMD | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_01 | USDHC1_CLK | USDHC1_CLK | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_02 | USDHC1_DATA0 | USDHC1_DATA0 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_03 | USDHC1_DATA1 | USDHC1_DATA1 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_04 | USDHC1_DATA2 | USDHC1_DATA2 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B1_05 | USDHC1_DATA3 | USDHC1_DATA3 | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_00 | FLEXSPI1_B_DATA3 | FLEXSPI1_DATA7_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_01 | FLEXSPI1_B_DATA2 | FLEXSPI1_DATA6_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_02 | FLEXSPI1_B_DATA1 | FLEXSPI1_DATA5_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_03 | FLEXSPI1_B_DATA0 | FLEXSPI1_DATA4_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_04 | FLEXSPI1_B_SCLK | FLEXSPI1_nSCK_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_05 | FLEXSPI1_A_DQS | FLEXSPI1_DQS_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_06 | FLEXSPI1_A_SS0_B | FLEXSPI1_nCS0_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_07 | FLEXSPI1_A_SCLK | FLEXSPI1_SCK_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_08 | FLEXSPI1_A_DATA0 | FLEXSPI1_DATA0_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_09 | FLEXSPI1_A_DATA0 | FLEXSPI1_DATA1_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_10 | FLEXSPI1_A_DATA2 | FLEXSPI1_DATA2_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| GPIO_SD_B2_11 | FLEXSPI1_A_DATA3 | FLEXSPI1_DATA3_HYPERFLASH | ++-----------------+--------------------------------+----------------------------+ +| USB1_DN | USB_OG1_DN | USB_D_N | ++-----------------+--------------------------------+----------------------------+ +| USB1_DP | USB_OTG1_DP | USB_D_P | ++-----------------+--------------------------------+----------------------------+ +| USB1_VBUS | USB_OTG1_VBUS | VBUS | ++-----------------+--------------------------------+----------------------------+ Serial Port =========== diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170-pinctrl.dtsi b/boards/nxp/vmu_rt1170/vmu_rt1170-pinctrl.dtsi index e7ab7ce896b556..e6d00911b1328c 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170-pinctrl.dtsi +++ b/boards/nxp/vmu_rt1170/vmu_rt1170-pinctrl.dtsi @@ -3,16 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 * * Note: File generated by gen_board_pinctrl.py - * from vmu_rt1170.mex + * from vmu_rt1170.mex, then updated manually */ #include &pinctrl { - pinmux_enet: pinmux_enet { + pinmux_enet1g: pinmux_enet1g { group0 { - pinmux = <&iomuxc_gpio_disp_b2_09_gpio_mux5_io10>, - <&iomuxc_gpio_disp_b1_00_enet_1g_rx_en>, + pinmux = <&iomuxc_gpio_disp_b1_00_enet_1g_rx_en>, <&iomuxc_gpio_disp_b1_01_enet_1g_rx_er>; drive-strength = "high"; bias-pull-down; @@ -27,9 +26,7 @@ input-enable; }; group2 { - pinmux = <&iomuxc_gpio_emc_b2_19_enet_1g_mdc>, - <&iomuxc_gpio_emc_b2_20_enet_1g_mdio>, - <&iomuxc_gpio_disp_b1_09_enet_1g_tdata00>, + pinmux = <&iomuxc_gpio_disp_b1_09_enet_1g_tdata00>, <&iomuxc_gpio_disp_b1_08_enet_1g_tdata01>, <&iomuxc_gpio_disp_b1_10_enet_1g_tx_en>; drive-strength = "high"; @@ -44,6 +41,24 @@ }; }; + pinmux_enet1g_mdio: pinmux_enet1g_mdio { + group0 { + pinmux = <&iomuxc_gpio_emc_b2_19_enet_1g_mdc>, + <&iomuxc_gpio_emc_b2_20_enet_1g_mdio>; + drive-strength = "high"; + slew-rate = "fast"; + }; + group1 { + pinmux = <&iomuxc_gpio_disp_b2_09_gpio_mux5_io10>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + }; + + pinmux_enet1g_ptp: pinmux_enet1g_ptp { + }; + pinmux_flexcan1: pinmux_flexcan1 { group0 { pinmux = <&iomuxc_gpio_ad_07_can1_rx>, @@ -156,6 +171,14 @@ }; }; + pinmux_qtmr_pwm_buzzer: pinmux_qtmr_pwm_buzzer { + group0 { + pinmux = <&iomuxc_gpio_emc_b2_09_qtimer1_timer0>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + pinmux_lpadc1: pinmux_lpadc1 { group0 { pinmux = <&iomuxc_gpio_ad_10_adc1_ch2a>; diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170.dtsi b/boards/nxp/vmu_rt1170/vmu_rt1170.dtsi index 075dc1860dc365..ac8e6a1869461a 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170.dtsi +++ b/boards/nxp/vmu_rt1170/vmu_rt1170.dtsi @@ -5,6 +5,7 @@ */ #include "vmu_rt1170-pinctrl.dtsi" +#include / { aliases { @@ -97,8 +98,26 @@ status = "okay"; }; -&enet1g { - pinctrl-0 = <&pinmux_enet>; +&enet1g_mac { + pinctrl-0 = <&pinmux_enet1g>; + pinctrl-names = "default"; + phy-handle = <&enet1g_phy>; + phy-connection-type = "rmii"; + zephyr,random-mac-address; +}; + +&enet1g_mdio { + pinctrl-0 = <&pinmux_enet1g_mdio>; + pinctrl-names = "default"; + enet1g_phy: phy@1 { + compatible = "nxp,tja1103"; + reg = <1>; + master-slave = "master"; + }; +}; + +&enet1g_ptp_clock { + pinctrl-0 = <&pinmux_enet1g_ptp>; pinctrl-names = "default"; }; @@ -177,7 +196,7 @@ ahb-prefetch; ahb-read-addr-opt; rx-clock-source = <1>; - reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(16)>; + reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(64)>; mx25um51345g: mx25um51345g@0 { compatible = "nxp,imx-flexspi-mx25um51345g"; /* MX25UM51245G is 64MB, 512MBit flash part */ @@ -193,22 +212,24 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(128)>; }; + /* The MCUBoot swap-move algorithm uses the last 14 sectors + * of the primary slot0 for swap status and move. + */ slot0_partition: partition@20000 { label = "image-0"; - reg = <0x00020000 DT_SIZE_K(3076)>; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(56))>; }; - slot1_partition: partition@321000 { + slot1_partition: partition@32E000 { label = "image-1"; - reg = <0x00321000 DT_SIZE_K(3072)>; + reg = <0x0032E000 DT_SIZE_M(3)>; }; - storage_partition: partition@621000 { + storage_partition: partition@62E000 { label = "storage"; - reg = <0x00621000 DT_SIZE_M(57)>; + reg = <0x0062E000 (DT_SIZE_M(58) - DT_SIZE_K(184))>; }; }; }; diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts index c2ea2f474967b6..d4e9788faca058 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts +++ b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts @@ -21,6 +21,7 @@ watchdog0 = &wdog1; sdhc0 = &usdhc1; sw0 = &arming_button; + pwm-led0 = &buzzer0; }; chosen { @@ -121,6 +122,13 @@ regulator-always-on; status = "okay"; }; + + pwm_shell: pwm_shell { + compatible = "pwm-leds"; + buzzer0: buzzer0 { + pwms = <&qtmr1 0 PWM_HZ(50) PWM_POLARITY_NORMAL>; + }; + }; }; @@ -170,6 +178,41 @@ current-speed = <115200>; }; +&lpuart6 { + status = "okay"; + single-wire; + rx-invert; + + sbus { + compatible = "futaba,sbus"; + right_stick_x { + channel = <1>; + type = ; + zephyr,code = ; + }; + right_stick_y { + channel = <2>; + type = ; + zephyr,code = ; + }; + left_stick_y { + channel = <3>; + type = ; + zephyr,code = ; + }; + left_stick_x { + channel = <4>; + type = ; + zephyr,code = ; + }; + kill_switch { + channel = <5>; + type = ; + zephyr,code = ; + }; + }; +}; + &flexcan1 { status = "okay"; @@ -392,6 +435,15 @@ capture-channel = <1>; }; +&qtmr1 { + compatible = "nxp,qtmr-pwm"; + pinctrl-0 = <&pinmux_qtmr_pwm_buzzer>; + pinctrl-names = "default"; + #pwm-cells = <3>; + prescaler = <128>; + status = "okay"; +}; + &usdhc1 { status = "okay"; no-1-8-v; @@ -429,7 +481,18 @@ &enet1g { status = "okay"; - int-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>; +}; + +&enet1g_mac { + status = "okay"; +}; + +&enet1g_mdio { + status = "okay"; + enet1g_phy: phy@1 { + status = "okay"; + int-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>; + }; }; zephyr_udc0: &usb1 { diff --git a/boards/olimex/olimex_esp32_evb/Kconfig.defconfig b/boards/olimex/olimex_esp32_evb/Kconfig.defconfig index c15264f5538df7..e3269639038322 100644 --- a/boards/olimex/olimex_esp32_evb/Kconfig.defconfig +++ b/boards/olimex/olimex_esp32_evb/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_OLIMEX_ESP32_EVB_ESP32_PROCPU if BOARD_OLIMEX_ESP32_EVB_ESP32_APPCPU diff --git a/boards/olimex/olimex_esp32_evb/doc/index.rst b/boards/olimex/olimex_esp32_evb/doc/index.rst index bcfc8a3c346431..c5457d5612c7a9 100644 --- a/boards/olimex/olimex_esp32_evb/doc/index.rst +++ b/boards/olimex/olimex_esp32_evb/doc/index.rst @@ -84,9 +84,9 @@ features: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/olimex/olimex_esp32_evb/olimex_esp32_evb_esp32_appcpu_defconfig` +:zephyr_file:`boards/olimex/olimex_esp32_evb/olimex_esp32_evb_appcpu_defconfig` and -:zephyr_file:`boards/olimex/olimex_esp32_evb/olimex_esp32_evb_esp32_procpu_defconfig` +:zephyr_file:`boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu_defconfig` Other hardware features are not currently supported by the port. diff --git a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts index e092f9766b594a..c239263ea537bf 100644 --- a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts +++ b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts @@ -20,6 +20,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -164,3 +165,7 @@ uext_spi: &spi2 {}; }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts b/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts index b21e9b960ec1a3..ceba94b4794aeb 100644 --- a/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts +++ b/boards/openisa/rv32m1_vega/rv32m1_vega_openisa_rv32m1_ri5cy.dts @@ -19,11 +19,12 @@ zephyr,shell-uart = &lpuart0; zephyr,uart-pipe = &lpuart0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_controller; }; +}; - aliases { - spi-flash0 = &mx25r32; - }; +&bt_hci_controller { + status = "okay"; }; &m4_flash { diff --git a/boards/others/black_f407ve/black_f407ve.dts b/boards/others/black_f407ve/black_f407ve.dts index 539f9838fbf4bc..2411e0e5a945cd 100644 --- a/boards/others/black_f407ve/black_f407ve.dts +++ b/boards/others/black_f407ve/black_f407ve.dts @@ -57,7 +57,6 @@ led0 = &green_led_1; led1 = &green_led_2; sw0 = &user_button_UP; - spi-flash0 = &w25q16cv; }; }; diff --git a/boards/others/icev_wireless/Kconfig.defconfig b/boards/others/icev_wireless/Kconfig.defconfig index 96ed16249d4aeb..b7c82093375ffe 100644 --- a/boards/others/icev_wireless/Kconfig.defconfig +++ b/boards/others/icev_wireless/Kconfig.defconfig @@ -7,7 +7,3 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 51200 if WIFI default 40960 if BT default 4096 - -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice diff --git a/boards/others/icev_wireless/icev_wireless.dts b/boards/others/icev_wireless/icev_wireless.dts index 6015780833554b..6209aeac7c21e3 100644 --- a/boards/others/icev_wireless/icev_wireless.dts +++ b/boards/others/icev_wireless/icev_wireless.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -126,3 +127,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/others/serpente/doc/index.rst b/boards/others/serpente/doc/index.rst index 4b6bf5e7390c31..c624c5ad0626ea 100644 --- a/boards/others/serpente/doc/index.rst +++ b/boards/others/serpente/doc/index.rst @@ -56,7 +56,7 @@ following hardware features: Other hardware features are not currently supported by Zephyr. The default configuration can be found in the Kconfig file -:zephyr_file:`boards/arturo182/serpente/serpente_defconfig`. +:zephyr_file:`boards/others/serpente/serpente_defconfig`. Connections and IOs =================== diff --git a/boards/panasonic/pan1783/Kconfig.defconfig b/boards/panasonic/pan1783/Kconfig.defconfig index ec08e860bbde52..6c70d441e91503 100644 --- a/boards/panasonic/pan1783/Kconfig.defconfig +++ b/boards/panasonic/pan1783/Kconfig.defconfig @@ -8,9 +8,8 @@ config MBOX_NRFX_IPC if SOC_NRF5340_CPUAPP_QKAA -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/panasonic/pan1783/pan1783_nrf5340_cpuapp_common.dtsi b/boards/panasonic/pan1783/pan1783_nrf5340_cpuapp_common.dtsi index fae7f566fccfe5..c1d4c5739e2564 100644 --- a/boards/panasonic/pan1783/pan1783_nrf5340_cpuapp_common.dtsi +++ b/boards/panasonic/pan1783/pan1783_nrf5340_cpuapp_common.dtsi @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; @@ -156,7 +156,6 @@ mcuboot-button0 = &evb_sw1; mcuboot-led0 = &evb_led1; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/particle/argon/dts/mesh_feather.dtsi b/boards/particle/argon/dts/mesh_feather.dtsi index ee3c4340d5bbc9..889fc75f835171 100644 --- a/boards/particle/argon/dts/mesh_feather.dtsi +++ b/boards/particle/argon/dts/mesh_feather.dtsi @@ -20,7 +20,6 @@ led3 = &status_blue; sw0 = &mode_button; sw1 = &reset_button; - spi-flash0 = &mx25l32; }; chosen { diff --git a/boards/particle/boron/dts/mesh_feather.dtsi b/boards/particle/boron/dts/mesh_feather.dtsi index 0005ca547ff26c..13b7e238230db7 100644 --- a/boards/particle/boron/dts/mesh_feather.dtsi +++ b/boards/particle/boron/dts/mesh_feather.dtsi @@ -20,7 +20,6 @@ led3 = &status_blue; sw0 = &mode_button; sw1 = &reset_button; - spi-flash0 = &mx25l32; }; chosen { diff --git a/boards/particle/xenon/particle_xenon.dts b/boards/particle/xenon/particle_xenon.dts index 2d64ba119b2998..c297014ff363fb 100644 --- a/boards/particle/xenon/particle_xenon.dts +++ b/boards/particle/xenon/particle_xenon.dts @@ -29,7 +29,6 @@ aliases { watchdog0 = &wdt0; - spi-flash0 = &mx25l32; }; }; diff --git a/boards/pine64/pinetime_devkit0/pinetime_devkit0.dts b/boards/pine64/pinetime_devkit0/pinetime_devkit0.dts index 207c893488018d..7bdf52d79e4cf7 100644 --- a/boards/pine64/pinetime_devkit0/pinetime_devkit0.dts +++ b/boards/pine64/pinetime_devkit0/pinetime_devkit0.dts @@ -12,6 +12,7 @@ #include #include "pinetime_devkit0-pinctrl.dtsi" #include +#include / { model = "Pine64 PineTime DevKit0"; @@ -77,6 +78,42 @@ output-ohms = <1000000>; full-ohms = <(1000000 + 1000000)>; }; + + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi1>; + dc-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; /* DET */ + reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; /* RESX reset */ + write-only; + #address-cells = <1>; + #size-cells = <0>; + /* Sitronix ST7789V LCD */ + st7789v: st7789v@1 { + compatible = "sitronix,st7789v"; + reg = <1>; + mipi-max-frequency = <8000000>; /* 8MHz */ + width = <240>; + height = <240>; + x-offset = <0>; + y-offset = <0>; + vcom = <0x19>; + gctrl = <0x35>; + vrhs = <0x12>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x05>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 01]; + pwctrl1-param = [a4 a1]; + pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; + nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; + ram-param = [00 F0]; + rgb-param = [CD 08 14]; + mipi-mode = ; + }; + }; }; &adc { @@ -178,34 +215,6 @@ }; }; }; - - /* Sitronix ST7789V LCD */ - st7789v: st7789v@1 { - compatible = "sitronix,st7789v"; - reg = <1>; - spi-max-frequency = <8000000>; /* 8MHz */ - cmd-data-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; /* DET */ - reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; /* RESX reset */ - width = <240>; - height = <240>; - x-offset = <0>; - y-offset = <0>; - vcom = <0x19>; - gctrl = <0x35>; - vrhs = <0x12>; - vdvs = <0x20>; - mdac = <0x00>; - gamma = <0x01>; - colmod = <0x05>; - lcm = <0x2c>; - porch-param = [0c 0c 00 33 33]; - cmd2en-param = [5a 69 02 01]; - pwctrl1-param = [a4 a1]; - pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; - nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; - ram-param = [00 F0]; - rgb-param = [CD 08 14]; - }; }; &flash0 { diff --git a/boards/qemu/cortex_m3/qemu_cortex_m3.dts b/boards/qemu/cortex_m3/qemu_cortex_m3.dts index 2e0bd95755f275..b035736a9f7b79 100644 --- a/boards/qemu/cortex_m3/qemu_cortex_m3.dts +++ b/boards/qemu/cortex_m3/qemu_cortex_m3.dts @@ -20,7 +20,7 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart2; + zephyr,bt-hci = &bt_hci_uart; zephyr,uart-pipe = &uart1; zephyr,bt-mon-uart = &uart2; }; @@ -39,6 +39,11 @@ &uart2 { status = "okay"; current-speed = <115200>; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; ð { diff --git a/boards/qemu/x86/qemu_x86.dts b/boards/qemu/x86/qemu_x86.dts index 023c551eb47acf..907e8a1ec1cb7e 100644 --- a/boards/qemu/x86/qemu_x86.dts +++ b/boards/qemu/x86/qemu_x86.dts @@ -37,8 +37,8 @@ zephyr,sram = &dram0; zephyr,flash = &flash0; zephyr,console = &uart0; + zephyr,bt-hci = &bt_hci_uart; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; zephyr,uart-pipe = &uart1; zephyr,bt-mon-uart = &uart1; zephyr,code-partition = &slot0_partition; @@ -125,6 +125,11 @@ &uart1 { status = "okay"; current-speed = <115200>; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; &hpet { diff --git a/boards/qemu/x86/qemu_x86_tiny.ld b/boards/qemu/x86/qemu_x86_tiny.ld index 3b3ecde113cc34..c3188c6e891a80 100644 --- a/boards/qemu/x86/qemu_x86_tiny.ld +++ b/boards/qemu/x86/qemu_x86_tiny.ld @@ -25,7 +25,7 @@ * the same as its physical location, although an identity mapping for RAM * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS. */ -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL #define KERNEL_BASE_ADDR \ (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) @@ -55,7 +55,7 @@ MEMORY { -#if defined(Z_VM_KERNEL) +#if defined(K_MEM_IS_VM_KERNEL) ROM (rx) : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL #endif RAM (wx) : ORIGIN = KERNEL_BASE_ADDR, LENGTH = KERNEL_RAM_SIZE @@ -75,7 +75,7 @@ MEMORY IDT_LIST : ORIGIN = 0xFFFF1000, LENGTH = 2K } -#if defined(Z_VM_KERNEL) +#if defined(K_MEM_IS_VM_KERNEL) #define ROMABLE_REGION ROM #define RAMABLE_REGION RAM #else @@ -245,7 +245,7 @@ MEMORY *mpsc_pbuf.c.obj(.##lsect) \ *mpsc_pbuf.c.obj(.##lsect.*) -epoint = Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); +epoint = K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); ENTRY(epoint) /* SECTIONS definitions */ @@ -254,6 +254,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /DISCARD/ : { *(.plt) diff --git a/boards/rak/rak5010/board.cmake b/boards/rak/rak5010/board.cmake index 1bf111421e2b70..d91b58c847d8a9 100644 --- a/boards/rak/rak5010/board.cmake +++ b/boards/rak/rak5010/board.cmake @@ -7,3 +7,4 @@ include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/raytac/mdbt53_db_40/Kconfig.defconfig b/boards/raytac/mdbt53_db_40/Kconfig.defconfig index 7bb0e9da9484c9..bb53d3ae8f477e 100644 --- a/boards/raytac/mdbt53_db_40/Kconfig.defconfig +++ b/boards/raytac/mdbt53_db_40/Kconfig.defconfig @@ -53,9 +53,8 @@ config FLASH_LOAD_SIZE endif # BOARD_RAYTAC_MDBT53_DB_40_NRF5340_CPUAPP_NS -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts index 3af7de1f17edf3..62a49e520698ad 100644 --- a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts +++ b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_common.dts @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/raytac/mdbt53v_db_40/Kconfig.defconfig b/boards/raytac/mdbt53v_db_40/Kconfig.defconfig index 9cdb1683eed02f..9573720773d152 100644 --- a/boards/raytac/mdbt53v_db_40/Kconfig.defconfig +++ b/boards/raytac/mdbt53v_db_40/Kconfig.defconfig @@ -53,9 +53,8 @@ config FLASH_LOAD_SIZE endif # BOARD_RAYTAC_MDBT53V_DB_40_NRF5340_CPUAPP_NS -choice BT_HCI_BUS_TYPE - default BT_HCI_IPC if BT -endchoice +config BT_HCI_IPC + default y if BT config HEAP_MEM_POOL_ADD_SIZE_BOARD int diff --git a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts index c7d7521d08b05a..3c1b42307a6ec0 100644 --- a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts +++ b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dts @@ -14,7 +14,7 @@ zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; - zephyr,bt-hci-ipc = &ipc0; + zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; }; diff --git a/boards/renesas/da1469x_dk_pro/Kconfig.defconfig b/boards/renesas/da1469x_dk_pro/Kconfig.defconfig index d491f8c1ebd475..4ef15e108a4402 100644 --- a/boards/renesas/da1469x_dk_pro/Kconfig.defconfig +++ b/boards/renesas/da1469x_dk_pro/Kconfig.defconfig @@ -64,10 +64,6 @@ endif # PM || PM_DEVICE if BT -choice BT_HCI_BUS_TYPE - default BT_DA1469X -endchoice - config BT_WAIT_NOP default y diff --git a/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.dts b/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.dts index f84a97b2020bf5..f866df49a859a6 100644 --- a/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.dts +++ b/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.dts @@ -19,6 +19,7 @@ zephyr,console = &uart; zephyr,shell-uart = &uart; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_da1469x; }; lvgl_pointer { @@ -178,3 +179,7 @@ zephyr_udc0: &usbd { pinctrl-1 = <&spi2_sleep>; pinctrl-names = "default", "sleep"; }; + +&bt_hci_da1469x { + status = "okay"; +}; diff --git a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57-pinctrl.dtsi b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57-pinctrl.dtsi index 6dc65b033137e1..37c6c099176041 100644 --- a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57-pinctrl.dtsi +++ b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57-pinctrl.dtsi @@ -15,44 +15,126 @@ pin = ; }; + sd0_clk: sd0_clk { + pin = ; + power-source = ; + }; + + sd0_cmd: sd0_cmd { + pin = ; + power-source = ; + }; + + sd0_data0: sd0_data0 { + pin = ; + power-source = ; + }; + + sd0_data1: sd0_data1 { + pin = ; + power-source = ; + }; + + sd0_data2: sd0_data2 { + pin = ; + power-source = ; + }; + + sd0_data3: sd0_data3 { + pin = ; + power-source = ; + }; + + sd0_clk_uhs: sd0_clk_uhs { + pin = ; + power-source = ; + }; + + sd0_cmd_uhs: sd0_cmd_uhs { + pin = ; + power-source = ; + }; + + sd0_data0_uhs: sd0_data0_uhs { + pin = ; + power-source = ; + }; + + sd0_data1_uhs: sd0_data1_uhs { + pin = ; + power-source = ; + }; + + sd0_data2_uhs: sd0_data2_uhs { + pin = ; + power-source = ; + }; + + sd0_data3_uhs: sd0_data3_uhs { + pin = ; + power-source = ; + }; + + /* note: CD pin is fixed at 3.3V */ + sd0_cd: sd0_cd { + pin = ; + power-source = ; + }; + + /* note: WP pin is fixed at 3.3V */ + sd0_wp: sd0_wp { + pin = ; + power-source = ; + }; + emmc2_clk: emmc2_clk { pin = ; + power-source = ; }; emmc2_cmd: emmc2_cmd { pin = ; + power-source = ; }; emmc2_data0: emmc2_data0 { pin = ; + power-source = ; }; emmc2_data1: emmc2_data1 { pin = ; + power-source = ; }; emmc2_data2: emmc2_data2 { pin = ; + power-source = ; }; emmc2_data3: emmc2_data3 { pin = ; + power-source = ; }; emmc2_data4: emmc2_data4 { pin = ; + power-source = ; }; emmc2_data5: emmc2_data5 { pin = ; + power-source = ; }; emmc2_data6: emmc2_data6 { pin = ; + power-source = ; }; emmc2_data7: emmc2_data7 { pin = ; + power-source = ; }; emmc2_ds: emmc2_ds { diff --git a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts index 599a0f25314beb..117b6bb4e741bb 100644 --- a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts +++ b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts @@ -8,6 +8,7 @@ /dts-v1/; #include #include +#include #include "rcar_h3ulcb_r8a77951_a57-pinctrl.dtsi" / { @@ -28,6 +29,52 @@ aliases { sdhc0 = &emmc2; }; + + vcc_sd0: regulator-vcc-sd0 { + compatible = "regulator-fixed"; + + regulator-name = "SD0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + enable-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; + }; + + vccq_sd0: regulator-vccq-sd0 { + compatible = "regulator-gpio"; + + regulator-name = "SD0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + states = <3300000 1>, <1800000 0>; + + regulator-always-on; + }; +}; + +&gpio5 { + status = "okay"; +}; + +&sd0 { + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp + &sd0_data0 &sd0_data1 &sd0_data2 &sd0_data3>; + pinctrl-1 = <&sd0_clk_uhs &sd0_cmd_uhs &sd0_cd &sd0_wp + &sd0_data0_uhs &sd0_data1_uhs &sd0_data2_uhs &sd0_data3_uhs>; + pinctrl-names = "default", "uhs"; + disk { + compatible = "zephyr,sdmmc-disk"; + status = "okay"; + }; + + vmmc-supply = <&vcc_sd0>; + vqmmc-supply = <&vccq_sd0>; + + bus-width = <4>; + mmc-sdr104-support; + status = "okay"; }; &scif2 { diff --git a/boards/renesas/rcar_salvator_xs/rcar_salvator_xs-pinctrl.dtsi b/boards/renesas/rcar_salvator_xs/rcar_salvator_xs-pinctrl.dtsi index b563a720079f84..f23f4b3c1b1af8 100644 --- a/boards/renesas/rcar_salvator_xs/rcar_salvator_xs-pinctrl.dtsi +++ b/boards/renesas/rcar_salvator_xs/rcar_salvator_xs-pinctrl.dtsi @@ -17,42 +17,52 @@ emmc2_clk: emmc2_clk { pin = ; + power-source = ; }; emmc2_cmd: emmc2_cmd { pin = ; + power-source = ; }; emmc2_data0: emmc2_data0 { pin = ; + power-source = ; }; emmc2_data1: emmc2_data1 { pin = ; + power-source = ; }; emmc2_data2: emmc2_data2 { pin = ; + power-source = ; }; emmc2_data3: emmc2_data3 { pin = ; + power-source = ; }; emmc2_data4: emmc2_data4 { pin = ; + power-source = ; }; emmc2_data5: emmc2_data5 { pin = ; + power-source = ; }; emmc2_data6: emmc2_data6 { pin = ; + power-source = ; }; emmc2_data7: emmc2_data7 { pin = ; + power-source = ; }; emmc2_ds: emmc2_ds { diff --git a/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55-pinctrl.dtsi b/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55-pinctrl.dtsi index 50739a237bea12..9d99d8cb89ce82 100644 --- a/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55-pinctrl.dtsi +++ b/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55-pinctrl.dtsi @@ -14,4 +14,58 @@ hscif0_data_rx_default: hscif0_data_rx_default { pin = ; }; + + mmc_clk: mmc_clk { + pin = ; + power-source = ; + }; + + mmc_cmd: mmc_cmd { + pin = ; + power-source = ; + }; + + mmc_data0: mmc_data0 { + pin = ; + power-source = ; + }; + + mmc_data1: mmc_data1 { + pin = ; + power-source = ; + }; + + mmc_data2: mmc_data2 { + pin = ; + power-source = ; + }; + + mmc_data3: mmc_data3 { + pin = ; + power-source = ; + }; + + mmc_data4: mmc_data4 { + pin = ; + power-source = ; + }; + + mmc_data5: mmc_data5 { + pin = ; + power-source = ; + }; + + mmc_data6: mmc_data6 { + pin = ; + power-source = ; + }; + + mmc_data7: mmc_data7 { + pin = ; + power-source = ; + }; + + mmc_ds: mmc_ds { + pin = ; + }; }; diff --git a/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55.dts b/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55.dts index 2075b90495cb44..3a7b5c4eb829bb 100644 --- a/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55.dts +++ b/boards/renesas/rcar_spider_s4/rcar_spider_s4_r8a779f0_a55.dts @@ -30,3 +30,22 @@ current-speed = <1843200>; status = "okay"; }; + +&mmc0 { + pinctrl-0 = <&mmc_clk &mmc_cmd &mmc_ds + &mmc_data0 &mmc_data1 &mmc_data2 &mmc_data3 + &mmc_data4 &mmc_data5 &mmc_data6 &mmc_data7>; + pinctrl-1 = <&mmc_clk &mmc_cmd &mmc_ds + &mmc_data0 &mmc_data1 &mmc_data2 &mmc_data3 + &mmc_data4 &mmc_data5 &mmc_data6 &mmc_data7>; + pinctrl-names = "default", "uhs"; + disk { + compatible = "zephyr,mmc-disk"; + status = "okay"; + }; + bus-width = <8>; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + non-removable; + status = "okay"; +}; diff --git a/boards/seagate/legend/legend.dts b/boards/seagate/legend/legend.dts index 245d2c8de7da95..d230345dd0794d 100644 --- a/boards/seagate/legend/legend.dts +++ b/boards/seagate/legend/legend.dts @@ -21,7 +21,6 @@ aliases { watchdog0 = &iwdg; - spi-flash0 = &spi_nor; led-strip = &led_strip_spi; }; diff --git a/boards/seeed/xiao_ble/xiao_ble_common.dtsi b/boards/seeed/xiao_ble/xiao_ble_common.dtsi index d031ce4b5b3d40..8ce71198e176e4 100644 --- a/boards/seeed/xiao_ble/xiao_ble_common.dtsi +++ b/boards/seeed/xiao_ble/xiao_ble_common.dtsi @@ -54,7 +54,6 @@ bootloader-led0 = &led0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &p25q16h; }; }; diff --git a/boards/seeed/xiao_esp32c3/Kconfig.defconfig b/boards/seeed/xiao_esp32c3/Kconfig.defconfig index f70e724ed8e0ca..4171bb04bc2760 100644 --- a/boards/seeed/xiao_esp32c3/Kconfig.defconfig +++ b/boards/seeed/xiao_esp32c3/Kconfig.defconfig @@ -7,7 +7,3 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 51200 if WIFI default 40960 if BT default 4096 - -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice diff --git a/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts b/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts index 943cda08b7dbf3..68687958b8a2a1 100644 --- a/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts +++ b/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts @@ -21,6 +21,7 @@ zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,canbus = &twai; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -118,3 +119,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/seeed/xiao_esp32s3/Kconfig.defconfig b/boards/seeed/xiao_esp32s3/Kconfig.defconfig index 424820d78adc90..b9222985d8dd0c 100644 --- a/boards/seeed/xiao_esp32s3/Kconfig.defconfig +++ b/boards/seeed/xiao_esp32s3/Kconfig.defconfig @@ -10,10 +10,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_XIAO_ESP32S3_ESP32S3_PROCPU if BOARD_XIAO_ESP32S3_ESP32S3_APPCPU diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.dts b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.dts index 17c2ca3eeec43d..2c1349b735c4ce 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.dts +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; aliases { @@ -127,3 +128,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/seeed/xiao_rp2040/Kconfig.defconfig b/boards/seeed/xiao_rp2040/Kconfig.defconfig new file mode 100644 index 00000000000000..e2af832cdcaec8 --- /dev/null +++ b/boards/seeed/xiao_rp2040/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Seeed Studio inc. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XIAO_RP2040 + +config RP2_FLASH_W25Q080 + default y + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_XIAO_RP2040 diff --git a/boards/seeed/xiao_rp2040/Kconfig.xiao_rp2040 b/boards/seeed/xiao_rp2040/Kconfig.xiao_rp2040 new file mode 100644 index 00000000000000..8bd3d0d2d15540 --- /dev/null +++ b/boards/seeed/xiao_rp2040/Kconfig.xiao_rp2040 @@ -0,0 +1,7 @@ +# XIAO RP2040 board configuration + +# Copyright (c) 2023 Seeed Studio inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_XIAO_RP2040 + select SOC_RP2040 diff --git a/boards/seeed/xiao_rp2040/board.cmake b/boards/seeed/xiao_rp2040/board.cmake new file mode 100644 index 00000000000000..4103e36e63569d --- /dev/null +++ b/boards/seeed/xiao_rp2040/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(uf2 "--board-id=RPI-RP2") + +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/seeed/xiao_rp2040/board.yml b/boards/seeed/xiao_rp2040/board.yml new file mode 100644 index 00000000000000..7eaca9159728c1 --- /dev/null +++ b/boards/seeed/xiao_rp2040/board.yml @@ -0,0 +1,5 @@ +board: + name: xiao_rp2040 + vendor: seeed + socs: + - name: rp2040 diff --git a/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040.webp b/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040.webp new file mode 100644 index 00000000000000..5233046000ae6f Binary files /dev/null and b/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040.webp differ diff --git a/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040_pinout.webp b/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040_pinout.webp new file mode 100644 index 00000000000000..cb295b073d46b2 Binary files /dev/null and b/boards/seeed/xiao_rp2040/doc/img/xiao_rp2040_pinout.webp differ diff --git a/boards/seeed/xiao_rp2040/doc/index.rst b/boards/seeed/xiao_rp2040/doc/index.rst new file mode 100644 index 00000000000000..7206e9be07f585 --- /dev/null +++ b/boards/seeed/xiao_rp2040/doc/index.rst @@ -0,0 +1,138 @@ +.. _xiao_rp2040: + +XIAO RP2040 +########### + +Overview +******** + +The XIAO RP2040 is an IoT mini development board from Seeed Studio. +It is equipped with an RP2040 SoC, an on-board WS2812 addressable +LED, and USB connector. The USB bootloader allows it +to be flashed without any adapter, in a drag-and-drop manner. + +For more details see the `Seeed Studio XIAO RP2040`_ wiki page. + +.. figure:: img/xiao_rp2040.webp + :align: center + :alt: XIAO RP2040 + + XIAO RP2040 + +Hardware +******** + +The Seeed Studio XIAO RP2040 is a low-power microcontroller that +carries the powerful Dual-core RP2040 processor with a flexible +clock running up to 133 MHz. There is also 264KB of SRAM, and 2MB of +on-board Flash memory. + +There are 14 GPIO PINs on Seeed Studio XIAO RP2040, on which there +are 11 digital pins, 4 analog pins, 11 PWM Pins,1 I2C interface, +1 UART interface, 1 SPI interface, 1 SWD Bonding pad interface. + +Supported Features +================== + +The ``xiao_rp2040`` board target supports the following hardware +features: + +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - NVIC + - N/A + - :dtcompatible:`arm,v6m-nvic` + * - UART + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart` + * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`raspberrypi,pico-gpio` + * - ADC + - :kconfig:option:`CONFIG_ADC` + - :dtcompatible:`raspberrypi,pico-adc` + * - I2C + - :kconfig:option:`CONFIG_I2C` + - :dtcompatible:`snps,designware-i2c` + * - SPI + - :kconfig:option:`CONFIG_SPI` + - :dtcompatible:`raspberrypi,pico-spi` + * - USB Device + - :kconfig:option:`CONFIG_USB_DEVICE_STACK` + - :dtcompatible:`raspberrypi,pico-usbd` + * - HWINFO + - :kconfig:option:`CONFIG_HWINFO` + - N/A + * - Watchdog Timer (WDT) + - :kconfig:option:`CONFIG_WATCHDOG` + - :dtcompatible:`raspberrypi,pico-watchdog` + * - PWM + - :kconfig:option:`CONFIG_PWM` + - :dtcompatible:`raspberrypi,pico-pwm` + * - Flash + - :kconfig:option:`CONFIG_FLASH` + - :dtcompatible:`raspberrypi,pico-flash-controller` + * - Clock controller + - :kconfig:option:`CONFIG_CLOCK_CONTROL` + - :dtcompatible:`raspberrypi,pico-clock-controller` + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` + +Pin Mapping +=========== + +The peripherals of the RP2040 SoC can be routed to various pins on the board. +The configuration of these routes can be modified through DTS. Please refer to +the datasheet to see the possible routings for each peripheral. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +.. rst-class:: rst-columns + +- UART0_TX : P0 +- UART0_RX : P1 +- I2C1_SDA : P6 +- I2C1_SCL : P7 +- SPI0_RX : P4 +- SPI0_SCK : P2 +- SPI0_TX : P3 + +Connections and IOs +=================== + +The board uses a standard XIAO pinout, the default pin mapping is the following: + +.. figure:: img/xiao_rp2040_pinout.webp + :align: center + :alt: XIAO RP2040 Pinout + + XIAO RP2040 Pinout + +Programming and Debugging +************************* + +Flashing +======== + +Using UF2 +--------- + +You can flash the Xiao RP2040 with a UF2 file. +By default, building an app for this board will generate a +:file:`build/zephyr/zephyr.uf2` file. If the Xiao RP2040 is powered on with +the ``BOOTSEL`` button pressed, it will appear on the host as a mass storage +device. The UF2 file should be copied to the device, which will +flash the Xiao RP2040. + +References +********** + +.. target-notes:: + +.. _`Seeed Studio XIAO RP2040`: https://wiki.seeedstudio.com/XIAO-RP2040/ diff --git a/boards/seeed/xiao_rp2040/seeed_xiao_connector.dtsi b/boards/seeed/xiao_rp2040/seeed_xiao_connector.dtsi new file mode 100644 index 00000000000000..d0e9152cefd083 --- /dev/null +++ b/boards/seeed/xiao_rp2040/seeed_xiao_connector.dtsi @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Seeed Studio inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + xiao_d: connector { + compatible = "seeed,xiao-gpio"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <0 0 &gpio0 26 0> /* D0 */ + , <1 0 &gpio0 27 0> /* D1 */ + , <2 0 &gpio0 28 0> /* D2 */ + , <3 0 &gpio0 29 0> /* D3 */ + , <4 0 &gpio0 6 0> /* D4 */ + , <5 0 &gpio0 7 0> /* D5 */ + , <6 0 &gpio0 0 0> /* D6 */ + , <7 0 &gpio0 1 0> /* D7 */ + , <8 0 &gpio0 2 0> /* D8 */ + , <9 0 &gpio0 4 0> /* D9 */ + , <10 0 &gpio0 3 0> /* D10 */ + ; + }; +}; + +xiao_i2c: &i2c1 { +}; +xiao_spi: &spi0 { +}; +xiao_serial: &uart0 { +}; diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040-pinctrl.dtsi b/boards/seeed/xiao_rp2040/xiao_rp2040-pinctrl.dtsi new file mode 100644 index 00000000000000..0e235884bf22c5 --- /dev/null +++ b/boards/seeed/xiao_rp2040/xiao_rp2040-pinctrl.dtsi @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2023 Seeed Studio inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + pwm_ch4b_default: pwm_ch4b_default { + group1 { + pinmux = ; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + group3 { + pinmux = ; + }; + }; + + adc_default: adc_default { + group1 { + pinmux = , + , + , + ; + input-enable; + }; + }; + + clocks_default: clocks_default { + }; + + ws2812_pio0_default: ws2812_pio0_default { + ws2812 { + pinmux = ; + }; + }; +}; diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040.dts b/boards/seeed/xiao_rp2040/xiao_rp2040.dts new file mode 100644 index 00000000000000..0a52f47d672d4e --- /dev/null +++ b/boards/seeed/xiao_rp2040/xiao_rp2040.dts @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2023 Seeed Studio inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "xiao_rp2040-pinctrl.dtsi" +#include "seeed_xiao_connector.dtsi" +#include +#include +#include + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,code-partition = &code_partition; + }; + + aliases { + watchdog0 = &wdt0; + led-strip = &ws2812; + pwm-led0 = &pwm_led0; + led0 = &blue_led; + led1 = &green_led; + led2 = &red_led; + }; + + pwm_leds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm 9 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM_LED"; + }; + }; + + leds { + compatible = "gpio-leds"; + + blue_led: blue_led { + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + label = "BLUE_LED"; + }; + + green_led: green_led { + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + label = "GREEN_LED"; + }; + + red_led: red_led { + gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + label = "RED_LED"; + }; + }; +}; + +&pwm { + pinctrl-0 = <&pwm_ch4b_default>; + pinctrl-names = "default"; + divider-int-0 = <255>; +}; + +&flash0 { + /* + * 2MB of flash minus the 0x100 used for the second stage bootloader + */ + reg = <0x10000000 DT_SIZE_M(2)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + code_partition: partition@100 { + label = "code"; + reg = <0x100 (DT_SIZE_M(2) - 0x100)>; + read-only; + }; + }; +}; + +&clocks { + pinctrl-0 = <&clocks_default>; + pinctrl-names = "default"; +}; + +&timer { + status = "okay"; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&gpio0 { + status = "okay"; + + /* + * The neopixel on this board has its positive side hooked up to a GPIO pin + * rather than a positive voltage rail to save on power. This will enable + * the LED on board initialization. + */ + neopixel-power-enable { + gpio-hog; + gpios = <11 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&wdt0 { + status = "okay"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + +&pio0 { + status = "okay"; + + pio-ws2812 { + compatible = "worldsemi,ws2812-rpi_pico-pio"; + status = "okay"; + pinctrl-0 = <&ws2812_pio0_default>; + pinctrl-names = "default"; + bit-waveform = <3>, <3>, <4>; + + ws2812: ws2812 { + status = "okay"; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + chain-length = <1>; + color-mapping = ; + reset-delay = <280>; + frequency = <800000>; + }; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040.yaml b/boards/seeed/xiao_rp2040/xiao_rp2040.yaml new file mode 100644 index 00000000000000..b2852757aa3af4 --- /dev/null +++ b/boards/seeed/xiao_rp2040/xiao_rp2040.yaml @@ -0,0 +1,24 @@ +identifier: xiao_rp2040 +name: XIAO RP2040 +type: mcu +arch: arm +flash: 2048 +ram: 256 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - uart + - gpio + - adc + - i2c + - spi + - hwinfo + - watchdog + - pwm + - flash + - dma + - counter + - clock +vendor: seeed diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040_defconfig b/boards/seeed/xiao_rp2040/xiao_rp2040_defconfig new file mode 100644 index 00000000000000..ef4e863884ab57 --- /dev/null +++ b/boards/seeed/xiao_rp2040/xiao_rp2040_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=125000000 +CONFIG_RESET=y + +# Enable UART driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable clock control by default +CONFIG_CLOCK_CONTROL=y + +# Code partition needed to target the correct flash range +CONFIG_USE_DT_CODE_PARTITION=y + +# Output UF2 by default, native bootloader supports it. +CONFIG_BUILD_OUTPUT_UF2=y diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/boards/rd_rw612_bga.overlay b/boards/shields/adafruit_2_8_tft_touch_v2/boards/rd_rw612_bga.overlay index 59136c9b45bcae..8c44347e63f1da 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/boards/rd_rw612_bga.overlay +++ b/boards/shields/adafruit_2_8_tft_touch_v2/boards/rd_rw612_bga.overlay @@ -16,6 +16,7 @@ * directly and does not require the MIPI DBI SPI node */ /delete-node/ mipi_dbi; + /delete-node/ adafruit_2_8_tft_touch_v2_mipi_dbi; }; &lcdic { diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/dts/adafruit_2_8_tft_touch_v2.dtsi b/boards/shields/adafruit_2_8_tft_touch_v2/dts/adafruit_2_8_tft_touch_v2.dtsi index 9413a7834d981c..9a8d5069c37852 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/dts/adafruit_2_8_tft_touch_v2.dtsi +++ b/boards/shields/adafruit_2_8_tft_touch_v2/dts/adafruit_2_8_tft_touch_v2.dtsi @@ -19,7 +19,7 @@ invert-y; }; - adafruit_2_8_tft_touch_v2_mipi_dbi { + adafruit_2_8_tft_touch_v2_mipi_dbi: adafruit_2_8_tft_touch_v2_mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&arduino_spi>; dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ diff --git a/boards/shields/frdm_kw41z/frdm_kw41z.overlay b/boards/shields/frdm_kw41z/frdm_kw41z.overlay index 3807b2f6a2dabb..8e9f14fbfb433f 100644 --- a/boards/shields/frdm_kw41z/frdm_kw41z.overlay +++ b/boards/shields/frdm_kw41z/frdm_kw41z.overlay @@ -6,11 +6,16 @@ / { chosen { - zephyr,bt-uart = &arduino_serial; + zephyr,bt-hci = &bt_hci_uart; }; }; &arduino_serial { status = "okay"; current-speed = <115200>; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; diff --git a/boards/shields/lmp90100_evb/doc/index.rst b/boards/shields/lmp90100_evb/doc/index.rst index f3a1ff36ed3ed5..689257e251fb75 100644 --- a/boards/shields/lmp90100_evb/doc/index.rst +++ b/boards/shields/lmp90100_evb/doc/index.rst @@ -50,7 +50,7 @@ Set ``-DSHIELD=lmp90100_evb`` when you invoke ``west build``. For example: :goals: build .. _LMP90100 Sensor AFE Evaluation Board User's Guide: - http://www.ti.com/lit/pdf/snau028 + https://www.farnell.com/datasheets/1604987.pdf .. _LMP90100 Multi-Channel, Low Power 24-Bit Sensor AFE: http://www.ti.com/product/LMP90100 diff --git a/boards/shields/lmp90100_evb/lmp90100_evb.overlay b/boards/shields/lmp90100_evb/lmp90100_evb.overlay index 7271c9c7c3debb..e30840dd10bde9 100644 --- a/boards/shields/lmp90100_evb/lmp90100_evb.overlay +++ b/boards/shields/lmp90100_evb/lmp90100_evb.overlay @@ -32,7 +32,7 @@ status = "okay"; eeprom0_lmp90100_evb: eeprom@57 { - compatible = "atmel,at24"; + compatible = "atmel,at24c02", "atmel,at24"; reg = <0x57>; size = <256>; pagesize = <8>; diff --git a/boards/shields/nxp_btb44_ov5640/Kconfig.shield b/boards/shields/nxp_btb44_ov5640/Kconfig.shield new file mode 100644 index 00000000000000..608188a2c54b05 --- /dev/null +++ b/boards/shields/nxp_btb44_ov5640/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_NXP_BTB44_OV5640 + def_bool $(shields_list_contains,nxp_btb44_ov5640) diff --git a/boards/shields/nxp_btb44_ov5640/doc/index.rst b/boards/shields/nxp_btb44_ov5640/doc/index.rst new file mode 100644 index 00000000000000..299878dc2d119d --- /dev/null +++ b/boards/shields/nxp_btb44_ov5640/doc/index.rst @@ -0,0 +1,134 @@ +.. _nxp_btb44_ov5640: + +NXP BTB-44 OV5640 Camera Module +############################### + +Overview +******** + +This shield supports ov5640 camera modules which use a 44-pin board-to-board connector and +a MIPI CSI or DVP (parallel) interface. These camera modules are made specifically for and +provided together with NXP's i.MX RT1160 and RT1170 EVK boards. + +More information about this OV5640 camera module can be found at `Camera iMXRT`_. + +Pins assignment of the NXP board-to-board 44-pin OV5640 camera module +====================================================================== + ++----------------------+--------------------+ +| Camera Connector Pin | Function | ++======================+====================+ +| 1 | AGND | ++----------------------+--------------------+ +| 2 | AF_GND | ++----------------------+--------------------+ +| 3 | STROBE | ++----------------------+--------------------+ +| 4 | AF_VCC | ++----------------------+--------------------+ +| 5 | SDA | ++----------------------+--------------------+ +| 6 | VCMSINK | ++----------------------+--------------------+ +| 7 | SCL | ++----------------------+--------------------+ +| 8 | AVDD | ++----------------------+--------------------+ +| 9 | RESETB | ++----------------------+--------------------+ +| 10 | GPIO1 | ++----------------------+--------------------+ +| 11 | PCLK | ++----------------------+--------------------+ +| 12 | GPIO0 | ++----------------------+--------------------+ +| 13 | VSYNC | ++----------------------+--------------------+ +| 14 | FREX | ++----------------------+--------------------+ +| 15 | HREF | ++----------------------+--------------------+ +| 16 | MIPI_CSI_DP1 / D9 | ++----------------------+--------------------+ +| 17 | PWDN | ++----------------------+--------------------+ +| 18 | MIPI_CSI_DN1 / D8 | ++----------------------+--------------------+ +| 19 | MIPI_CSI_DP1 / D9 | ++----------------------+--------------------+ +| 20 | DGND | ++----------------------+--------------------+ +| 21 | MIPI_CSI_DN1 / D8 | ++----------------------+--------------------+ +| 22 | MIPI_CSI_CLKP / D7 | ++----------------------+--------------------+ +| 23 | MIPI_CSI_CLKP / D7 | ++----------------------+--------------------+ +| 24 | MIPI_CSI_CLKN / D6 | ++----------------------+--------------------+ +| 25 | MIPI_CSI_CLKN / D6 | ++----------------------+--------------------+ +| 26 | DGND | ++----------------------+--------------------+ +| 27 | MIPI_CSI_DP0 / D5 | ++----------------------+--------------------+ +| 28 | MIPI_CSI_DP0 / D5 | ++----------------------+--------------------+ +| 29 | MIPI_CSI_DN0 / D4 | ++----------------------+--------------------+ +| 30 | MIPI_CSI_DN0 / D4 | ++----------------------+--------------------+ +| 31 | D3 | ++----------------------+--------------------+ +| 32 | DGND | ++----------------------+--------------------+ +| 33 | D2 | ++----------------------+--------------------+ +| 34 | XCLK | ++----------------------+--------------------+ +| 35 | D1 | ++----------------------+--------------------+ +| 36 | DVDD | ++----------------------+--------------------+ +| 37 | D0 | ++----------------------+--------------------+ +| 38 | DOVDD | ++----------------------+--------------------+ +| 39 | DGND | ++----------------------+--------------------+ +| 40 | DGND | ++----------------------+--------------------+ +| 41 | GND | ++----------------------+--------------------+ +| 42 | GND | ++----------------------+--------------------+ +| 43 | GND | ++----------------------+--------------------+ +| 44 | AF_GND | ++----------------------+--------------------+ + +Requirements +************ + +This shield can only be used with a board which provides a 44-pin board-to-board +connector with MIPI CSI or DVP (parallel) interface where the pinouts are defined +as above, such as i.MX RT1160 and RT1170 EVK boards. + +Programming +*********** + +Set ``-DSHIELD=nxp_btb44_ov5640`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/video/capture + :board: mimxrt1170_evk/mimxrt1176/cm7 + :shield: nxp_btb44_ov5640 + :goals: build + +References +********** + +.. target-notes:: + +.. _Camera iMXRT: + https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Connecting-camera-and-LCD-to-i-MX-RT-EVKs/ta-p/1122183 diff --git a/boards/shields/nxp_btb44_ov5640/nxp_btb44_ov5640.overlay b/boards/shields/nxp_btb44_ov5640/nxp_btb44_ov5640.overlay new file mode 100644 index 00000000000000..7f9848fd7a29ea --- /dev/null +++ b/boards/shields/nxp_btb44_ov5640/nxp_btb44_ov5640.overlay @@ -0,0 +1,48 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/{ + chosen { + zephyr,camera = &nxp_csi; + }; +}; + +&nxp_cam_i2c { + status = "okay"; + + ov5640: ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + reset-gpios = <&nxp_cam_connector 9 GPIO_ACTIVE_LOW>; + powerdown-gpios = <&nxp_cam_connector 17 GPIO_ACTIVE_HIGH>; + + port { + ov5640_ep_out: endpoint { + remote-endpoint = <&mipi_csi2rx_ep_in>; + }; + }; + }; +}; + +&nxp_mipi_csi { + status = "okay"; + + sensor = <&ov5640>; + + ports { + port@1 { + reg = <1>; + + mipi_csi2rx_ep_in: endpoint { + remote-endpoint = <&ov5640_ep_out>; + }; + }; + }; +}; + +&nxp_csi { + status = "okay"; +}; diff --git a/boards/shields/rk043fn02h_ct/Kconfig.defconfig b/boards/shields/rk043fn02h_ct/Kconfig.defconfig new file mode 100644 index 00000000000000..f2b199d916968b --- /dev/null +++ b/boards/shields/rk043fn02h_ct/Kconfig.defconfig @@ -0,0 +1,47 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_RK043FN02H_CT + +if LVGL + +config INPUT + default y + +config INPUT_FT5336_INTERRUPT + default y + +# LVGL should allocate buffers equal to size of display +config LV_Z_VDB_SIZE + default 100 + +# Enable double buffering +config LV_Z_DOUBLE_VDB + default y + +# Force full refresh. This prevents memory copy associated with partial +# display refreshes, which is not necessary for the eLCDIF driver +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 16 + +config LV_DPI_DEF + default 128 + +# Use offloaded render thread +config LV_Z_FLUSH_THREAD + default y + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_16 +endchoice + +# Force display buffers to be aligned to cache line size (32 bytes) +config LV_Z_VDB_ALIGN + default 32 + +endif # LVGL + +endif # SHIELD_RK043FN02H_CT diff --git a/boards/shields/rk043fn02h_ct/Kconfig.shield b/boards/shields/rk043fn02h_ct/Kconfig.shield new file mode 100644 index 00000000000000..4cf0c812ae89e4 --- /dev/null +++ b/boards/shields/rk043fn02h_ct/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RK043FN02H_CT + def_bool $(shields_list_contains,rk043fn02h_ct) diff --git a/boards/shields/rk043fn02h_ct/doc/index.rst b/boards/shields/rk043fn02h_ct/doc/index.rst new file mode 100644 index 00000000000000..8fe083d61c5e59 --- /dev/null +++ b/boards/shields/rk043fn02h_ct/doc/index.rst @@ -0,0 +1,105 @@ +.. _rk043fn02h_ct: + +RK043FN02H-CT Parallel Display +############################## + +Overview +******** + +RK043FN02H-CT is a 4.3 inch TFT 480*272 pixels with LED backlight and +capacitive touch panel from Rocktech. This LCD panel can work with several i.MX +RT EVKs and LPC MCUs for evaluation of applications with display. + +More information about the shield can be found at the `RK043FN02H-CT product +page`_. + +This display uses a 40 pin parallel FPC interface plus 6 pin I2C interface, +available on many NXP EVKs. Note that this parallel FPC interface is not +compatible with the MIPI FPC interface present on other NXP EVKs. + +Pins Assignment of the Rocktech RK043FN02H-CT Parallel Display +============================================================== + ++-----------------------+------------------------+ +| Parallel FPC Pin | Function | ++=======================+========================+ +| 1 | LED backlight cathode | ++-----------------------+------------------------+ +| 2 | LED backlight anode | ++-----------------------+------------------------+ +| 3 | GND | ++-----------------------+------------------------+ +| 4 | VDD (3v3) | ++-----------------------+------------------------+ +| 5-7 | GND | ++-----------------------+------------------------+ +| 8-12 | LCD D11-D15 | ++-----------------------+------------------------+ +| 13-14 | GND | ++-----------------------+------------------------+ +| 15-20 | LCD D5-D10 | ++-----------------------+------------------------+ +| 21-23 | GND | ++-----------------------+------------------------+ +| 24-28 | LCD D0-D4 | ++-----------------------+------------------------+ +| 29 | GND | ++-----------------------+------------------------+ +| 30 | LCD CLK | ++-----------------------+------------------------+ +| 31 | LCD DISP | ++-----------------------+------------------------+ +| 32 | LCD HSYNC | ++-----------------------+------------------------+ +| 33 | LCD VSYNC | ++-----------------------+------------------------+ +| 34 | LCD DE | ++-----------------------+------------------------+ +| 35 | NC | ++-----------------------+------------------------+ +| 36 | GND | ++-----------------------+------------------------+ +| 37-40 | NC | ++-----------------------+------------------------+ + ++-----------------------+------------------------+ +| I2C Connector Pin | Function | ++=======================+========================+ +| 1 | VDD (3v3) | ++-----------------------+------------------------+ +| 2 | LCD Touch Reset | ++-----------------------+------------------------+ +| 3 | LCD Touch Interrupt | ++-----------------------+------------------------+ +| 4 | LCD I2C SCL | ++-----------------------+------------------------+ +| 5 | LCD I2C SDA | ++-----------------------+------------------------+ +| 6 | GND | ++-----------------------+------------------------+ + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for the 40+6 pin parallel/I2C FPC interface + +Programming +*********** + +Set ``-DSHIELD=rk043fn02h_ct`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/display + :board: mimxrt1060_evk + :shield: rk043fn02h_ct + :goals: build + +References +********** + +.. target-notes:: + +.. _RK043FN02H-CT product page: + https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/4-3-lcd-panel:RK043FN02H-CT diff --git a/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay b/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay new file mode 100644 index 00000000000000..ab0b10d70af2a9 --- /dev/null +++ b/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay @@ -0,0 +1,50 @@ +/* + * Copyright 2024, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/{ + chosen { + zephyr,display = &zephyr_lcdif; + }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <&ft5336_rk043fn02h_ct>; + }; +}; + +&nxp_touch_i2c { + status = "okay"; + ft5336_rk043fn02h_ct: ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + int-gpios = <&nxp_i2c_touch_fpc 2 GPIO_ACTIVE_LOW>; + }; +}; + +&zephyr_lcdif { + status = "okay"; + width = <480>; + height = <272>; + display-timings { + compatible = "zephyr,panel-timing"; + hsync-len = <41>; + hfront-porch = <4>; + hback-porch = <8>; + vsync-len = <10>; + vfront-porch = <4>; + vback-porch = <2>; + de-active= <1>; + pixelclk-active = <1>; + hsync-active = <0>; + vsync-active = <0>; + clock-frequency = <9210240>; + }; + pixel-format = ; + data-bus-width = "16-bit"; + backlight-gpios = <&nxp_parallel_lcd_connector 0 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/shields/rk043fn66hs_ctg/Kconfig.defconfig b/boards/shields/rk043fn66hs_ctg/Kconfig.defconfig new file mode 100644 index 00000000000000..58e4b93b08860f --- /dev/null +++ b/boards/shields/rk043fn66hs_ctg/Kconfig.defconfig @@ -0,0 +1,47 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_RK043FN66HS_CTG + +if LVGL + +config INPUT + default y + +config INPUT_GT911_INTERRUPT + default y + +# LVGL should allocate buffers equal to size of display +config LV_Z_VDB_SIZE + default 100 + +# Enable double buffering +config LV_Z_DOUBLE_VDB + default y + +# Force full refresh. This prevents memory copy associated with partial +# display refreshes, which is not necessary for the eLCDIF driver +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 16 + +config LV_DPI_DEF + default 128 + +# Use offloaded render thread +config LV_Z_FLUSH_THREAD + default y + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_16 +endchoice + +# Force display buffers to be aligned to cache line size (32 bytes) +config LV_Z_VDB_ALIGN + default 32 + +endif # LVGL + +endif # SHIELD_RK043FN66HS_CTG diff --git a/boards/shields/rk043fn66hs_ctg/Kconfig.shield b/boards/shields/rk043fn66hs_ctg/Kconfig.shield new file mode 100644 index 00000000000000..02a15503e4c7db --- /dev/null +++ b/boards/shields/rk043fn66hs_ctg/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RK043FN66HS_CTG + def_bool $(shields_list_contains,rk043fn66hs_ctg) diff --git a/boards/shields/rk043fn66hs_ctg/doc/index.rst b/boards/shields/rk043fn66hs_ctg/doc/index.rst new file mode 100644 index 00000000000000..29d031e8305e32 --- /dev/null +++ b/boards/shields/rk043fn66hs_ctg/doc/index.rst @@ -0,0 +1,105 @@ +.. _rk043fn66hs_ctg: + +RK043FN66HS-CTG Parallel Display +################################ + +Overview +******** + +RK043FN66HS-CTG is a 4.3 inch TFT 480*272 pixels with LED backlight and +capacitive touch panel from Rocktech. This LCD panel can work with several i.MX +RT EVKs and LPC MCUs for evaluation of applications with display. + +More information about the shield can be found at the `RK043FN66HS-CTG product +page`_. + +This display uses a 40 pin parallel FPC interface plus 6 pin I2C interface, +available on many NXP EVKs. Note that this parallel FPC interface is not +compatible with the MIPI FPC interface present on other NXP EVKs. + +Pins Assignment of the Rocktech RK043FN66HS-CTG Parallel Display +================================================================ + ++-----------------------+------------------------+ +| Parallel FPC Pin | Function | ++=======================+========================+ +| 1 | LED backlight cathode | ++-----------------------+------------------------+ +| 2 | LED backlight anode | ++-----------------------+------------------------+ +| 3 | GND | ++-----------------------+------------------------+ +| 4 | VDD (3v3) | ++-----------------------+------------------------+ +| 5-7 | GND | ++-----------------------+------------------------+ +| 8-12 | LCD D11-D15 | ++-----------------------+------------------------+ +| 13-14 | GND | ++-----------------------+------------------------+ +| 15-20 | LCD D5-D10 | ++-----------------------+------------------------+ +| 21-23 | GND | ++-----------------------+------------------------+ +| 24-28 | LCD D0-D4 | ++-----------------------+------------------------+ +| 29 | GND | ++-----------------------+------------------------+ +| 30 | LCD CLK | ++-----------------------+------------------------+ +| 31 | LCD DISP | ++-----------------------+------------------------+ +| 32 | LCD HSYNC | ++-----------------------+------------------------+ +| 33 | LCD VSYNC | ++-----------------------+------------------------+ +| 34 | LCD DE | ++-----------------------+------------------------+ +| 35 | NC | ++-----------------------+------------------------+ +| 36 | GND | ++-----------------------+------------------------+ +| 37-40 | NC | ++-----------------------+------------------------+ + ++-----------------------+------------------------+ +| I2C Connector Pin | Function | ++=======================+========================+ +| 1 | VDD (3v3) | ++-----------------------+------------------------+ +| 2 | LCD Touch Reset | ++-----------------------+------------------------+ +| 3 | LCD Touch Interrupt | ++-----------------------+------------------------+ +| 4 | LCD I2C SCL | ++-----------------------+------------------------+ +| 5 | LCD I2C SDA | ++-----------------------+------------------------+ +| 6 | GND | ++-----------------------+------------------------+ + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for the 40+6 pin parallel/I2C FPC interface + +Programming +*********** + +Set ``-DSHIELD=rk043fn66hs_ctg`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/display + :board: mimxrt1060_evk + :shield: rk043fn66hs_ctg + :goals: build + +References +********** + +.. target-notes:: + +.. _RK043FN66HS-CTG product page: + https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/4-3-lcd-panel:RK043FN66HS-CTG diff --git a/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay b/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay new file mode 100644 index 00000000000000..b992ec932b8197 --- /dev/null +++ b/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay @@ -0,0 +1,51 @@ +/* + * Copyright 2024, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/{ + chosen { + zephyr,display = &zephyr_lcdif; + }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <>911_rk043fn66hs_ctg>; + }; +}; + +&nxp_touch_i2c { + status = "okay"; + gt911_rk043fn66hs_ctg: gt911@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + irq-gpios = <&nxp_i2c_touch_fpc 2 GPIO_ACTIVE_HIGH>; + reset-gpios = <&nxp_i2c_touch_fpc 1 GPIO_ACTIVE_LOW>; + }; +}; + +&zephyr_lcdif { + status = "okay"; + width = <480>; + height = <272>; + display-timings { + compatible = "zephyr,panel-timing"; + hsync-len = <4>; + hfront-porch = <8>; + hback-porch = <43>; + vsync-len = <4>; + vfront-porch = <8>; + vback-porch = <12>; + de-active= <1>; + pixelclk-active = <1>; + hsync-active = <0>; + vsync-active = <0>; + clock-frequency = <9210240>; + }; + pixel-format = ; + data-bus-width = "16-bit"; + backlight-gpios = <&nxp_parallel_lcd_connector 0 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay b/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay index c12ee45515b9c6..46c863b5ac896f 100644 --- a/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay +++ b/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay @@ -3,41 +3,51 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include / { chosen { zephyr,display = &st7789v_st7789v_tl019fqv01; }; + + mipi_dbi_st7789v_tl019fqv01 { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&arduino_spi>; + dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + write-only; + #address-cells = <1>; + #size-cells = <0>; + + st7789v_st7789v_tl019fqv01: st7789v@0 { + compatible = "sitronix,st7789v"; + mipi-max-frequency = <20000000>; + reg = <0>; + width = <320>; + height = <170>; + x-offset = <0>; + y-offset = <35>; + vcom = <0x2b>; + gctrl = <0x35>; + vrhs = <0x0f>; + vdvs = <0x20>; + mdac = <0x60>; + gamma = <0x01>; + colmod = <0x55>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 01]; + pwctrl1-param = [52 a1]; + pvgam-param = [D0 00 02 07 0B 1A 31 54 40 29 12 12 12 17]; + nvgam-param = [D0 00 02 07 05 15 2D 44 44 1C 18 16 1C 1D]; + ram-param = [00 F8]; + rgb-param = [CD 08 14]; + mipi-mode = ; + }; + }; }; &arduino_spi { status = "okay"; cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ - - st7789v_st7789v_tl019fqv01: st7789v@0 { - compatible = "sitronix,st7789v"; - spi-max-frequency = <20000000>; - reg = <0>; - cmd-data-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ - reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ - width = <320>; - height = <170>; - x-offset = <0>; - y-offset = <35>; - vcom = <0x2b>; - gctrl = <0x35>; - vrhs = <0x0f>; - vdvs = <0x20>; - mdac = <0x60>; - gamma = <0x01>; - colmod = <0x55>; - lcm = <0x2c>; - porch-param = [0c 0c 00 33 33]; - cmd2en-param = [5a 69 02 01]; - pwctrl1-param = [52 a1]; - pvgam-param = [D0 00 02 07 0B 1A 31 54 40 29 12 12 12 17]; - nvgam-param = [D0 00 02 07 05 15 2D 44 44 1C 18 16 1C 1D]; - ram-param = [00 F8]; - rgb-param = [CD 08 14]; - }; }; diff --git a/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay b/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay index 3c7205ce28700e..0a92937a982fe0 100644 --- a/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay +++ b/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay @@ -5,40 +5,51 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { zephyr,display = &st7789v_st7789v_waveshare_240x240; }; + + mipi_dbi_st7789v_waveshare_240x240 { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&arduino_spi>; + dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + write-only; + #address-cells = <1>; + #size-cells = <0>; + + st7789v_st7789v_waveshare_240x240: st7789v@0 { + compatible = "sitronix,st7789v"; + mipi-max-frequency = <20000000>; + reg = <0>; + width = <240>; + height = <240>; + x-offset = <0>; + y-offset = <0>; + vcom = <0x19>; + gctrl = <0x35>; + vrhs = <0x12>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x05>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 01]; + pwctrl1-param = [a4 a1]; + pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; + nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; + ram-param = [00 F0]; + rgb-param = [CD 08 14]; + mipi-mode = ; + }; + }; }; &arduino_spi { status = "okay"; cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ - - st7789v_st7789v_waveshare_240x240: st7789v@0 { - compatible = "sitronix,st7789v"; - spi-max-frequency = <20000000>; - reg = <0>; - cmd-data-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ - reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ - width = <240>; - height = <240>; - x-offset = <0>; - y-offset = <0>; - vcom = <0x19>; - gctrl = <0x35>; - vrhs = <0x12>; - vdvs = <0x20>; - mdac = <0x00>; - gamma = <0x01>; - colmod = <0x05>; - lcm = <0x2c>; - porch-param = [0c 0c 00 33 33]; - cmd2en-param = [5a 69 02 01]; - pwctrl1-param = [a4 a1]; - pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; - nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; - ram-param = [00 F0]; - rgb-param = [CD 08 14]; - }; }; diff --git a/boards/shields/waveshare_epaper/Kconfig.defconfig b/boards/shields/waveshare_epaper/Kconfig.defconfig index 5f7f13a0b16e43..6087880f4f378a 100644 --- a/boards/shields/waveshare_epaper/Kconfig.defconfig +++ b/boards/shields/waveshare_epaper/Kconfig.defconfig @@ -5,8 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 # -if SHIELD_WAVESHARE_EPAPER_GDEH029A1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B72 || SHIELD_WAVESHARE_EPAPER_GDEW075T7 || SHIELD_WAVESHARE_EPAPER_GDEH0154A07 || SHIELD_WAVESHARE_EPAPER_GDEW042T2 || SHIELD_WAVESHARE_EPAPER_GDEW042T2_P - +if SHIELD_WAVESHARE_EPAPER_GDEH029A1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B72 || SHIELD_WAVESHARE_EPAPER_GDEW075T7 || SHIELD_WAVESHARE_EPAPER_GDEH0154A07 || SHIELD_WAVESHARE_EPAPER_GDEW042T2 || SHIELD_WAVESHARE_EPAPER_GDEW042T2_P || SHIELD_WAVESHARE_EPAPER_GDEY0213B74 if DISPLAY diff --git a/boards/shields/waveshare_epaper/Kconfig.shield b/boards/shields/waveshare_epaper/Kconfig.shield index 863059e57843cc..b3fe949cb3ae33 100644 --- a/boards/shields/waveshare_epaper/Kconfig.shield +++ b/boards/shields/waveshare_epaper/Kconfig.shield @@ -21,3 +21,6 @@ config SHIELD_WAVESHARE_EPAPER_GDEW042T2 config SHIELD_WAVESHARE_EPAPER_GDEW042T2_P def_bool $(shields_list_contains,waveshare_epaper_gdew042t2-p) + +config SHIELD_WAVESHARE_EPAPER_GDEY0213B74 + def_bool $(shields_list_contains,waveshare_epaper_gdey0213b74) diff --git a/boards/shields/waveshare_epaper/doc/index.rst b/boards/shields/waveshare_epaper/doc/index.rst index 876ba1d107e8cd..25c4ecd955e400 100644 --- a/boards/shields/waveshare_epaper/doc/index.rst +++ b/boards/shields/waveshare_epaper/doc/index.rst @@ -65,6 +65,9 @@ Current supported displays | Good Display | WFT0420CZ15 | UC8176 / | waveshare_epaper_gdew042t2 | | GDEW042T2 | | gd7965 | waveshare_epaper_gdew042t2-p | +--------------+-----------------+--------------+------------------------------+ +| Good Display | FPC-A002 | SSD1680 / | waveshare_epaper_gdey0213b74 | +| GDEY0213B74 | | ssd16xx | | ++--------------+-----------------+--------------+------------------------------+ Requirements diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdey0213b74.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdey0213b74.overlay new file mode 100644 index 00000000000000..bd77a1ede516ab --- /dev/null +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdey0213b74.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, Kelly Helmut Lord + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "waveshare_epaper_common.dtsi" + +/ { + chosen { + zephyr,display = &ssd16xx_waveshare_epaper_gdey0213b74; + }; +}; + +&arduino_spi { + ssd16xx_waveshare_epaper_gdey0213b74: ssd16xxfb@0 { + compatible = "gooddisplay,gdey0213b74", "solomon,ssd1680"; + spi-max-frequency = <4000000>; + reg = <0>; + width = <250>; + height = <122>; + dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + busy-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; /* D7 */ + + tssv = <0x80>; + + full { + border-waveform = <0x05>; + }; + + partial { + border-waveform = <0x3c>; + }; + }; +}; diff --git a/boards/shields/x_nucleo_bnrg2a1/Kconfig.defconfig b/boards/shields/x_nucleo_bnrg2a1/Kconfig.defconfig index 88f16f95dc56e6..94ace9e3849893 100644 --- a/boards/shields/x_nucleo_bnrg2a1/Kconfig.defconfig +++ b/boards/shields/x_nucleo_bnrg2a1/Kconfig.defconfig @@ -8,9 +8,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/shields/x_nucleo_bnrg2a1/x_nucleo_bnrg2a1.overlay b/boards/shields/x_nucleo_bnrg2a1/x_nucleo_bnrg2a1.overlay index 177ac9eb9484d3..535373ea307d7e 100644 --- a/boards/shields/x_nucleo_bnrg2a1/x_nucleo_bnrg2a1.overlay +++ b/boards/shields/x_nucleo_bnrg2a1/x_nucleo_bnrg2a1.overlay @@ -4,10 +4,16 @@ * SPDX-License-Identifier: Apache-2.0 */ + / { + chosen { + zephyr,bt-hci = &hci_spi; + }; + }; + &arduino_spi { cs-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>; /* A1 */ - bluenrg-2@0 { + hci_spi: bluenrg-2@0 { compatible = "st,hci-spi-v2"; reg = <0>; reset-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */ diff --git a/boards/shields/x_nucleo_eeprma2/x_nucleo_eeprma2.overlay b/boards/shields/x_nucleo_eeprma2/x_nucleo_eeprma2.overlay index a1c7c6813dc34f..84f1cda1a3cfa1 100644 --- a/boards/shields/x_nucleo_eeprma2/x_nucleo_eeprma2.overlay +++ b/boards/shields/x_nucleo_eeprma2/x_nucleo_eeprma2.overlay @@ -20,7 +20,7 @@ eeprom0_x_nucleo_eeprma2: eeprom@54 { /* M24C02-FMC6TG aka U1 (2 kbit eeprom in DFN8 package) */ - compatible = "st,m24xxx", "atmel,at24"; + compatible = "st,m24c02", "st,m24xxx", "atmel,at24"; reg = <0x54>; size = <256>; pagesize = <16>; @@ -33,7 +33,7 @@ eeprom1_x_nucleo_eeprma2: eeprom@55 { /* M24256-DFDW6TP aka U2 (256 kbit eeprom in TSSOP package) */ - compatible = "st,m24xxx", "atmel,at24"; + compatible = "st,m24256", "st,m24xxx", "atmel,at24"; reg = <0x55>; size = ; pagesize = <64>; @@ -46,7 +46,7 @@ eeprom2_x_nucleo_eeprma2: eeprom@56 { /* M24M01-DFMN6TP aka U3 (1 Mbit eeprom in SO8N package) */ - compatible = "st,m24xxx", "atmel,at24"; + compatible = "st,m24m01", "st,m24xxx", "atmel,at24"; reg = <0x56>; size = ; pagesize = <256>; @@ -82,7 +82,7 @@ eeprom4_x_nucleo_eeprma2: eeprom_m95040@0 { /* M95040-RMC6TG aka U5 (4 kbit eeprom in DFN8 package) */ - compatible = "st,m95xxx", "atmel,at25"; + compatible = "st,m95040", "st,m95xxx", "atmel,at25"; reg = <0x00>; size = <512>; pagesize = <16>; @@ -96,7 +96,7 @@ eeprom5_x_nucleo_eeprma2: eeprom_m95256@1 { /* M95256-DFDW6TP aka U6 (256 kbit eeprom in TSSOP package) */ - compatible = "st,m95xxx", "atmel,at25"; + compatible = "st,m95256", "st,m95xxx", "atmel,at25"; reg = <0x01>; size = ; pagesize = <64>; @@ -110,7 +110,7 @@ eeprom6_x_nucleo_eeprma2: eeprom_m95m04@2 { /* M95M04-DRMN6TP aka U7 (4 Mbit eeprom in SON8 package) */ - compatible = "st,m95xxx", "atmel,at25"; + compatible = "st,m95m04", "st,m95xxx", "atmel,at25"; reg = <0x02>; size = ; pagesize = <512>; diff --git a/boards/shields/x_nucleo_idb05a1/Kconfig.defconfig b/boards/shields/x_nucleo_idb05a1/Kconfig.defconfig index a5fe2515b50341..276ee66467992f 100644 --- a/boards/shields/x_nucleo_idb05a1/Kconfig.defconfig +++ b/boards/shields/x_nucleo_idb05a1/Kconfig.defconfig @@ -8,9 +8,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay b/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay index e6dff3c9c9f331..f508f0b26a0b43 100644 --- a/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay +++ b/boards/shields/x_nucleo_idb05a1/x_nucleo_idb05a1.overlay @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ + / { + chosen { + zephyr,bt-hci = &spbtle_rf_x_nucleo_idb05a1; + }; + }; + &arduino_spi { cs-gpios = <&arduino_header 1 GPIO_ACTIVE_LOW>; /* A1 */ diff --git a/boards/silabs/dev_kits/index.rst b/boards/silabs/dev_kits/index.rst new file mode 100644 index 00000000000000..4a0cf90ce33205 --- /dev/null +++ b/boards/silabs/dev_kits/index.rst @@ -0,0 +1,10 @@ +.. _dev_kits: + +Dev Kits and Thunderboards +########################## + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/silabs/efr32mg_sltb004a/CMakeLists.txt b/boards/silabs/dev_kits/sltb004a/CMakeLists.txt similarity index 100% rename from boards/silabs/efr32mg_sltb004a/CMakeLists.txt rename to boards/silabs/dev_kits/sltb004a/CMakeLists.txt diff --git a/boards/silabs/efr32mg_sltb004a/Kconfig.defconfig b/boards/silabs/dev_kits/sltb004a/Kconfig.defconfig similarity index 75% rename from boards/silabs/efr32mg_sltb004a/Kconfig.defconfig rename to boards/silabs/dev_kits/sltb004a/Kconfig.defconfig index 5dd6c6417a7410..3a9256b44e1ee1 100644 --- a/boards/silabs/efr32mg_sltb004a/Kconfig.defconfig +++ b/boards/silabs/dev_kits/sltb004a/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2018, Diego Sueiro # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFR32MG_SLTB004A +if BOARD_SLTB004A config CMU_HFXO_FREQ default 40000000 @@ -11,4 +11,4 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -endif # BOARD_EFR32MG_SLTB004A +endif # BOARD_SLTB004A diff --git a/boards/silabs/efr32mg_sltb004a/Kconfig.efr32mg_sltb004a b/boards/silabs/dev_kits/sltb004a/Kconfig.sltb004a similarity index 83% rename from boards/silabs/efr32mg_sltb004a/Kconfig.efr32mg_sltb004a rename to boards/silabs/dev_kits/sltb004a/Kconfig.sltb004a index 3f2245d372e3c5..58f4485dd4ea77 100644 --- a/boards/silabs/efr32mg_sltb004a/Kconfig.efr32mg_sltb004a +++ b/boards/silabs/dev_kits/sltb004a/Kconfig.sltb004a @@ -3,5 +3,5 @@ # Copyright (c) 2018, Diego Sueiro # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFR32MG_SLTB004A +config BOARD_SLTB004A select SOC_PART_NUMBER_EFR32MG12P332F1024GL125 diff --git a/boards/silabs/efr32mg_sltb004a/board.c b/boards/silabs/dev_kits/sltb004a/board.c similarity index 100% rename from boards/silabs/efr32mg_sltb004a/board.c rename to boards/silabs/dev_kits/sltb004a/board.c diff --git a/boards/silabs/efr32mg_sltb004a/board.cmake b/boards/silabs/dev_kits/sltb004a/board.cmake similarity index 100% rename from boards/silabs/efr32mg_sltb004a/board.cmake rename to boards/silabs/dev_kits/sltb004a/board.cmake diff --git a/boards/silabs/efr32mg_sltb004a/board.yml b/boards/silabs/dev_kits/sltb004a/board.yml similarity index 72% rename from boards/silabs/efr32mg_sltb004a/board.yml rename to boards/silabs/dev_kits/sltb004a/board.yml index cef6207cf03c50..2141aa3817df93 100644 --- a/boards/silabs/efr32mg_sltb004a/board.yml +++ b/boards/silabs/dev_kits/sltb004a/board.yml @@ -1,5 +1,5 @@ board: - name: efr32mg_sltb004a + name: sltb004a vendor: silabs socs: - name: efr32mg12p332f1024gl125 diff --git a/boards/silabs/efr32mg_sltb004a/doc/index.rst b/boards/silabs/dev_kits/sltb004a/doc/index.rst similarity index 81% rename from boards/silabs/efr32mg_sltb004a/doc/index.rst rename to boards/silabs/dev_kits/sltb004a/doc/index.rst index ae06df99fc54a8..8ee2b64604d06a 100644 --- a/boards/silabs/efr32mg_sltb004a/doc/index.rst +++ b/boards/silabs/dev_kits/sltb004a/doc/index.rst @@ -1,18 +1,18 @@ -.. _efr32mg_sltb004a: +.. _sltb004a: -EFR32MG-SLTB004A -################ +EFR32MG12 Thunderboard (SLTB004A) +################################# Overview ******** -The EFR32™ Mighty Gecko Starter Kit EFR32MG-SLTB004A (a.k.a Thunderboard -Sense 2) contains a MCU from the EFR32MG family built on ARM® Cortex®-M4F -processor with low power capabilities. +The EFR32MG12 Thunderboard (a.k.a Thunderboard Sense 2) contains an MCU +from the EFR32MG12 family built on ARM® Cortex®-M4F processor with low +power capabilities. -.. image:: efr32mg_sltb004a.jpg +.. image:: sltb004a.jpg :align: center - :alt: EFR32MG-SLTB004A + :alt: EFR32MG12 SLTB004A Hardware ******** @@ -40,20 +40,17 @@ Hardware - Automatic switch-over between USB and battery power - CR2032 coin cell holder and external battery connector -For more information about the EFR32MG SoC and Thunderboard Sense 2 -(EFR32MG-SLTB004A) board: +For more information about the EFR32MG12 SoC and Thunderboard Sense 2 board: -- `EFR32MG Website`_ -- `EFR32MG Datasheet`_ -- `EFR32MG Reference Manual`_ -- `EFR32MG-SLTB004A Website`_ -- `EFR32MG-SLTB004A User Guide`_ -- `EFR32MG-SLTB004A Schematics`_ +- `EFR32MG12 Datasheet`_ +- `EFR32MG12 Reference Manual`_ +- `SLTB004A User Guide`_ +- `SLTB004A Schematics`_ Supported Features ================== -The efr32mg_sltb004a board configuration supports the following hardware features: +The sltb004a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | @@ -83,14 +80,14 @@ The efr32mg_sltb004a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a_defconfig` +:zephyr_file:`boards/silabs/dev_kits/sltb004a/sltb004a_defconfig` Other hardware features are currently not supported by the port. Connections and IOs =================== -The EFR32MG SoC has eight gpio controllers (PORTA, PORTB, PORTC, PORTD, +The EFR32MG12 SoC has eight gpio controllers (PORTA, PORTB, PORTC, PORTD, PORTF, PORTI, PORTJ and PORTK). In the following table, the column Name contains Pin names. For example, PE2 @@ -136,13 +133,13 @@ in the board's and microcontroller's datasheets and manuals. System Clock ============ -The EFR32MG SoC is configured to use the 38.4 MHz external oscillator on the +The EFR32MG12 SoC is configured to use the 38.4 MHz external oscillator on the board. Serial Port =========== -The EFR32MG SoC has four USARTs and one Low Energy UARTs (LEUART with 9600 +The EFR32MG12 SoC has four USARTs and one Low Energy UARTs (LEUART with 9600 maximum baudrate). USART0 is configured as the Zephyr console and is connected to the On-Board J-Link Debugger that presents a virtual COM port for general purpose application serial data transfer with this interface. @@ -157,7 +154,7 @@ Programming and Debugging Flashing ======== -The EFR32MG-SLTB004A includes an `J-Link`_ serial and debug adaptor built into the +The SLTB004A includes an `J-Link`_ serial and debug adaptor built into the board. The adaptor provides: - A USB connection to the host computer, which exposes a Mass Storage and a @@ -165,18 +162,18 @@ board. The adaptor provides: - A Serial Flash device, which implements the USB flash disk file storage. - A physical UART connection which is relayed over interface USB Serial port. -Flashing an application to EFR32-SLTB004A ------------------------------------------ +Flashing an application to SLTB004A +----------------------------------- The sample application :ref:`hello_world` is used for this example. Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32mg_sltb004a + :board: sltb004a :goals: build -Connect the EFR32MG-SLTB004A to your host computer using the USB port and you +Connect the SLTB004A to your host computer using the USB port and you should see a USB connection which exposes a Mass Storage (TB004) and a USB Serial Port. Copy the generated zephyr.bin in the SLTB004A drive. @@ -192,25 +189,19 @@ the following message: .. code-block:: console - Hello World! arm + Hello World! sltb004a -.. _EFR32MG-SLTB004A Website: - https://www.silabs.com/products/development-tools/thunderboard/thunderboard-sense-two-kit - -.. _EFR32MG-SLTB004A User Guide: +.. _SLTB004A User Guide: https://www.silabs.com/documents/public/user-guides/ug309-sltb004a-user-guide.pdf -.. _EFR32MG-SLTB004A Schematics: +.. _SLTB004A Schematics: https://www.silabs.com/documents/public/schematic-files/BRD4166A-D00-schematic.pdf -.. _EFR32MG Website: - https://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc - -.. _EFR32MG Datasheet: +.. _EFR32MG12 Datasheet: https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf -.. _EFR32MG Reference Manual: +.. _EFR32MG12 Reference Manual: https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf .. _J-Link: diff --git a/boards/silabs/efr32mg_sltb004a/doc/efr32mg_sltb004a.jpg b/boards/silabs/dev_kits/sltb004a/doc/sltb004a.jpg similarity index 100% rename from boards/silabs/efr32mg_sltb004a/doc/efr32mg_sltb004a.jpg rename to boards/silabs/dev_kits/sltb004a/doc/sltb004a.jpg diff --git a/boards/silabs/efr32_radio/pre_dt_board.cmake b/boards/silabs/dev_kits/sltb004a/pre_dt_board.cmake similarity index 100% rename from boards/silabs/efr32_radio/pre_dt_board.cmake rename to boards/silabs/dev_kits/sltb004a/pre_dt_board.cmake diff --git a/boards/silabs/dev_kits/sltb004a/sltb004a-pinctrl.dtsi b/boards/silabs/dev_kits/sltb004a/sltb004a-pinctrl.dtsi new file mode 100644 index 00000000000000..e500e3b18bdd97 --- /dev/null +++ b/boards/silabs/dev_kits/sltb004a/sltb004a-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for uart0 device, default state */ + usart0_default: usart0_default { + group1 { + /* configure PA.1 as UART_RX */ + psels = , + ; + }; + group2 { + /* configure PA.0 as UART_TX */ + psels = , + ; + }; + }; +}; diff --git a/boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.dts b/boards/silabs/dev_kits/sltb004a/sltb004a.dts similarity index 95% rename from boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.dts rename to boards/silabs/dev_kits/sltb004a/sltb004a.dts index 3819bd6ca94cf4..033984be007709 100644 --- a/boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.dts +++ b/boards/silabs/dev_kits/sltb004a/sltb004a.dts @@ -6,12 +6,12 @@ /dts-v1/; #include -#include +#include "sltb004a-pinctrl.dtsi" #include / { - model = "Silabs EFR32MG SLTB004A board (aka Thunderboard Sense 2)"; - compatible = "silabs,efr32mg_sltb004a", "silabs,efr32mg"; + model = "Silabs EFR32MG12 SLTB004A board (aka Thunderboard Sense 2)"; + compatible = "silabs,sltb004a", "silabs,efr32mg"; /* These aliases are provided for compatibility with samples */ aliases { @@ -22,7 +22,6 @@ sw1 = &button1; watchdog0 = &wdog0; watchdog1 = &wdog1; - spi-flash0 = &mx25r80; }; chosen { diff --git a/boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.yaml b/boards/silabs/dev_kits/sltb004a/sltb004a.yaml similarity index 75% rename from boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.yaml rename to boards/silabs/dev_kits/sltb004a/sltb004a.yaml index 3c8cbd773d01c1..a610e85fdee1f9 100644 --- a/boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a.yaml +++ b/boards/silabs/dev_kits/sltb004a/sltb004a.yaml @@ -1,5 +1,5 @@ -identifier: efr32mg_sltb004a -name: EFR32MG-SLTB004A +identifier: sltb004a +name: Thunderboard Sense 2 (SLTB004A, BRD4166A) type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48_defconfig b/boards/silabs/dev_kits/sltb004a/sltb004a_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48_defconfig rename to boards/silabs/dev_kits/sltb004a/sltb004a_defconfig diff --git a/boards/silabs/efm32gg_sltb009a/Kconfig.defconfig b/boards/silabs/dev_kits/sltb009a/Kconfig.defconfig similarity index 85% rename from boards/silabs/efm32gg_sltb009a/Kconfig.defconfig rename to boards/silabs/dev_kits/sltb009a/Kconfig.defconfig index a24eda68abd036..6c21d423607ab2 100644 --- a/boards/silabs/efm32gg_sltb009a/Kconfig.defconfig +++ b/boards/silabs/dev_kits/sltb009a/Kconfig.defconfig @@ -2,7 +2,7 @@ # Copyright (c) 2023 Antmicro # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32GG_SLTB009A +if BOARD_SLTB009A config CMU_HFXO_FREQ default 50000000 @@ -17,4 +17,4 @@ config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO -endif # BOARD_EFM32GG_SLTB009A +endif # BOARD_SLTB009A diff --git a/boards/silabs/efm32gg_sltb009a/Kconfig.efm32gg_sltb009a b/boards/silabs/dev_kits/sltb009a/Kconfig.sltb009a similarity index 85% rename from boards/silabs/efm32gg_sltb009a/Kconfig.efm32gg_sltb009a rename to boards/silabs/dev_kits/sltb009a/Kconfig.sltb009a index e1f93ff9da9049..d486de8476985f 100644 --- a/boards/silabs/efm32gg_sltb009a/Kconfig.efm32gg_sltb009a +++ b/boards/silabs/dev_kits/sltb009a/Kconfig.sltb009a @@ -2,5 +2,5 @@ # Copyright (c) 2023 Antmicro # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFM32GG_SLTB009A +config BOARD_SLTB009A select SOC_PART_NUMBER_EFM32GG12B810F1024GM64 diff --git a/boards/silabs/efm32gg_sltb009a/board.cmake b/boards/silabs/dev_kits/sltb009a/board.cmake similarity index 100% rename from boards/silabs/efm32gg_sltb009a/board.cmake rename to boards/silabs/dev_kits/sltb009a/board.cmake diff --git a/boards/silabs/efm32gg_sltb009a/board.yml b/boards/silabs/dev_kits/sltb009a/board.yml similarity index 72% rename from boards/silabs/efm32gg_sltb009a/board.yml rename to boards/silabs/dev_kits/sltb009a/board.yml index 388301f55e1f28..af69758728d320 100644 --- a/boards/silabs/efm32gg_sltb009a/board.yml +++ b/boards/silabs/dev_kits/sltb009a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32gg_sltb009a + name: sltb009a vendor: silabs socs: - name: efm32gg12b810f1024gm64 diff --git a/boards/silabs/efm32gg_sltb009a/doc/index.rst b/boards/silabs/dev_kits/sltb009a/doc/index.rst similarity index 93% rename from boards/silabs/efm32gg_sltb009a/doc/index.rst rename to boards/silabs/dev_kits/sltb009a/doc/index.rst index e27fcc34ba0f05..2ec7a83f325744 100644 --- a/boards/silabs/efm32gg_sltb009a/doc/index.rst +++ b/boards/silabs/dev_kits/sltb009a/doc/index.rst @@ -1,15 +1,16 @@ .. _efm32gg_sltb009a: -EFM32GG12 Thunderboard Kit -########################## +EFM32GG12 Thunderboard (SLTB009A) +################################# Overview ******** -The EFM32GG12 Thunderboard Kit (SLTB009A) is an evaluation platform for the EFM32GG12 GiantGecko Microcontroller, -featuring an ARM Cortex-M4 with FPU, 1024kB flash, and 192kB RAM. +The EFM32GG12 Thunderboard Kit (SLTB009A) is an evaluation platform for the +EFM32GG12 Giant Gecko Microcontroller, featuring an ARM Cortex-M4 with FPU, +1024kB flash, and 192kB RAM. -.. figure:: efm32gg12-thunderboard-kit.jpg +.. figure:: sltb009a.jpg :align: center :alt: SLTB009A @@ -57,7 +58,7 @@ features: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a_defconfig` +:zephyr_file:`boards/silabs/dev_kits/sltb009a/sltb009a_defconfig` Connections and IOs =================== @@ -121,7 +122,7 @@ board. The adaptor provides: - A physical UART connection which is relayed over interface USB serial port. Flashing an application to SLTB009A --------------------------------------- +----------------------------------- Connect the SLTB009A to your host computer using the USB port. @@ -129,7 +130,7 @@ Here is an example to build and flash the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32gg_stb009a + :board: sltb009a :goals: flash Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -144,7 +145,7 @@ terminal session: .. code-block:: console - Hello World! efm32gg_sltb009a + Hello World! sltb009a .. _SLTB009A Website: https://www.silabs.com/development-tools/thunderboard/thunderboard-gg12-kit diff --git a/boards/silabs/efm32gg_sltb009a/doc/efm32gg12-thunderboard-kit.jpg b/boards/silabs/dev_kits/sltb009a/doc/sltb009a.jpg similarity index 100% rename from boards/silabs/efm32gg_sltb009a/doc/efm32gg12-thunderboard-kit.jpg rename to boards/silabs/dev_kits/sltb009a/doc/sltb009a.jpg diff --git a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a-pinctrl.dtsi b/boards/silabs/dev_kits/sltb009a/sltb009a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a-pinctrl.dtsi rename to boards/silabs/dev_kits/sltb009a/sltb009a-pinctrl.dtsi diff --git a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.dts b/boards/silabs/dev_kits/sltb009a/sltb009a.dts similarity index 95% rename from boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.dts rename to boards/silabs/dev_kits/sltb009a/sltb009a.dts index eac47f561235a8..1c36fb59f21fa7 100644 --- a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.dts +++ b/boards/silabs/dev_kits/sltb009a/sltb009a.dts @@ -7,11 +7,11 @@ /dts-v1/; #include #include -#include "efm32gg_sltb009a-pinctrl.dtsi" +#include "sltb009a-pinctrl.dtsi" / { - model = "Silicon Labs EFM32GG SLTB009A board"; - compatible = "silabs,efm32gg_sltb009a"; + model = "Silicon Labs EFM32GG12 SLTB009A board"; + compatible = "silabs,sltb009a"; chosen { zephyr,console = &usart0; diff --git a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.yaml b/boards/silabs/dev_kits/sltb009a/sltb009a.yaml similarity index 68% rename from boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.yaml rename to boards/silabs/dev_kits/sltb009a/sltb009a.yaml index ddea24692faf5a..468b6b48d56f55 100644 --- a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a.yaml +++ b/boards/silabs/dev_kits/sltb009a/sltb009a.yaml @@ -1,5 +1,5 @@ -identifier: efm32gg_sltb009a -name: EFM32GG-SLTB009A +identifier: sltb009a +name: Thunderboard EFM32GG12 (SLTB009A, BRD2207A) type: mcu arch: arm ram: 192 diff --git a/boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a_defconfig b/boards/silabs/dev_kits/sltb009a/sltb009a_defconfig similarity index 100% rename from boards/silabs/efm32gg_sltb009a/efm32gg_sltb009a_defconfig rename to boards/silabs/dev_kits/sltb009a/sltb009a_defconfig diff --git a/boards/silabs/efr32_thunderboard/CMakeLists.txt b/boards/silabs/dev_kits/sltb010a/CMakeLists.txt similarity index 100% rename from boards/silabs/efr32_thunderboard/CMakeLists.txt rename to boards/silabs/dev_kits/sltb010a/CMakeLists.txt diff --git a/boards/silabs/efr32_thunderboard/Kconfig b/boards/silabs/dev_kits/sltb010a/Kconfig similarity index 87% rename from boards/silabs/efr32_thunderboard/Kconfig rename to boards/silabs/dev_kits/sltb010a/Kconfig index f9cfc8b4499a21..6fdb24720ae401 100644 --- a/boards/silabs/efr32_thunderboard/Kconfig +++ b/boards/silabs/dev_kits/sltb010a/Kconfig @@ -3,6 +3,6 @@ # Copyright (c) 2022, Silicon Labs # SPDX-License-Identifier: Apache-2.0 -module = BOARD_THUNDERBOARD +module = BOARD_SLTB010A module-str = Board Control source "subsys/logging/Kconfig.template.log_config" diff --git a/boards/silabs/efr32_thunderboard/Kconfig.defconfig b/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig similarity index 88% rename from boards/silabs/efr32_thunderboard/Kconfig.defconfig rename to boards/silabs/dev_kits/sltb010a/Kconfig.defconfig index 9c116263518955..9b45efccc9001d 100644 --- a/boards/silabs/efr32_thunderboard/Kconfig.defconfig +++ b/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig @@ -28,10 +28,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -choice BT_HCI_BUS_TYPE - default BT_SILABS_HCI -endchoice - endif # BT config REGULATOR diff --git a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184b b/boards/silabs/dev_kits/sltb010a/Kconfig.sltb010a similarity index 82% rename from boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184b rename to boards/silabs/dev_kits/sltb010a/Kconfig.sltb010a index 48a8915cf5ae44..43710c2540871e 100644 --- a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184b +++ b/boards/silabs/dev_kits/sltb010a/Kconfig.sltb010a @@ -3,5 +3,5 @@ # Copyright (c) 2021, Sateesh Kotapati # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFR32BG22_BRD4184B +config BOARD_SLTB010A select SOC_PART_NUMBER_EFR32BG22C224F512IM40 diff --git a/boards/silabs/efr32_thunderboard/board.c b/boards/silabs/dev_kits/sltb010a/board.c similarity index 95% rename from boards/silabs/efr32_thunderboard/board.c rename to boards/silabs/dev_kits/sltb010a/board.c index 508d0ee68370e3..e4dc2c3f62a790 100644 --- a/boards/silabs/efr32_thunderboard/board.c +++ b/boards/silabs/dev_kits/sltb010a/board.c @@ -13,7 +13,7 @@ #endif -LOG_MODULE_REGISTER(thunderboard, CONFIG_BOARD_THUNDERBOARD_LOG_LEVEL); +LOG_MODULE_REGISTER(thunderboard, CONFIG_BOARD_SLTB010A_LOG_LEVEL); static int thunderboard_init_clocks(void); diff --git a/boards/silabs/dev_kits/sltb010a/board.cmake b/boards/silabs/dev_kits/sltb010a/board.cmake new file mode 100644 index 00000000000000..fdaebc0c84443a --- /dev/null +++ b/boards/silabs/dev_kits/sltb010a/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/dev_kits/sltb010a/board.yml b/boards/silabs/dev_kits/sltb010a/board.yml new file mode 100644 index 00000000000000..4586a51ef722b9 --- /dev/null +++ b/boards/silabs/dev_kits/sltb010a/board.yml @@ -0,0 +1,11 @@ +boards: + - name: sltb010a + vendor: silabs + socs: + - name: efr32bg22c224f512im40 + revision: + format: number + default: "2" + revisions: + - name: "0" + - name: "2" diff --git a/boards/silabs/efr32_thunderboard/doc/brd4184.rst b/boards/silabs/dev_kits/sltb010a/doc/index.rst similarity index 84% rename from boards/silabs/efr32_thunderboard/doc/brd4184.rst rename to boards/silabs/dev_kits/sltb010a/doc/index.rst index a6f1c281d3c8e8..1299bef0bc2cd8 100644 --- a/boards/silabs/efr32_thunderboard/doc/brd4184.rst +++ b/boards/silabs/dev_kits/sltb010a/doc/index.rst @@ -1,15 +1,15 @@ -.. _efr32bg22_brd4184: +.. _sltb010a: -SiLabs EFR32BG22-BRD4184(A/B) (Thunderboard EFR32BG22) -###################################################### +EFR32BG22 Thunderboard (SLTB010A) +################################# -BRD4184 is a board based on EFR32BG22 SoC and is one of -:ref:`efr32_thunderboard`. It comes in two revisions, which differ from each -other slightly: BRD4184A and BRD4184B. +SLTB010A is a development kit based on the EFR32BG22 SoC. Early revisions of +the kit (A00 and A01) use a slightly different PCB (BRD4184A) from later +revisions (BRD4184B). -.. image:: ./efr32bg_sltb010a.jpg +.. image:: ./sltb010a.jpg :align: center - :alt: EFR32BG-SLTB010A + :alt: SLTB010A board Hardware ******** @@ -49,7 +49,7 @@ For more information about the EFR32BG SoC and Thunderboard EFR32BG22 board: Supported Features ================== -The efr32bg22_brd4184a/b board configuration supports the following hardware features: +The sltb010a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | @@ -80,27 +80,20 @@ The efr32bg22_brd4184a/b board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_thunderboard/efr32bg22_brd4184a_defconfig` -and -:zephyr_file:`boards/silabs/efr32_thunderboard/efr32bg22_brd4184b_defconfig` +:zephyr_file:`boards/silabs/dev_kits/sltb010a/sltb010a_defconfig`. Connections and IOs =================== -The EFR32BG SoC has six gpio controllers (PORTA, PORTB, PORTC, PORTD, -PORTE and PORTF). - -In the following tables, the column Name contains Pin names. For example, PE2 -means Pin number 2 on PORTE and #27 represents the location bitfield, as used -in the board's and microcontroller's datasheets and manuals. +The EFR32BG22 SoC has four gpio controllers (PORTA, PORTB, PORTC and PORTD). There are two variants of this board, "A" and "B". Please take a look at your PCB, to determine which one you have, as the GPIO pin bindings vary between those two. -BRD4184A: +BRD4184A (SLTB010A revision A00 and A01): +------+-------------+-----------------------------------+ -| Name | Function | Usage | +| Pin | Function | Usage | +======+=============+===================================+ | PB0 | GPIO | LED0 (YELLOW) | +------+-------------+-----------------------------------+ @@ -111,10 +104,10 @@ BRD4184A: | PA6 | UART_RX | UART RX Console VCOM_RX US1_RX #1 | +------+-------------+-----------------------------------+ -BRD4184B: +BRD4184B (SLTB010A revision A02 and newer): +------+-------------+-----------------------------------+ -| Name | Function | Usage | +| Pin | Function | Usage | +======+=============+===================================+ | PA4 | GPIO | LED0 (YELLOW) | +------+-------------+-----------------------------------+ @@ -128,7 +121,7 @@ BRD4184B: System Clock ============ -The EFR32BG SoC is configured to use the 38.4 MHz external oscillator on the +The EFR32BG22 SoC is configured to use the 38.4 MHz external oscillator on the board. Programming and Debugging @@ -145,14 +138,14 @@ BRD4184A: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32bg22_brd4184a + :board: sltb010a@0 :goals: flash BRD4184B: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32bg22_brd4184b + :board: sltb010a@2 :goals: flash .. note:: @@ -171,7 +164,7 @@ the following message: .. code-block:: console - Hello World! efr32bg22_brd4184 + Hello World! sltb010a Bluetooth ========= @@ -181,7 +174,7 @@ blobs from the SiLabs HAL repository. .. code-block:: console - west blobs fetch silabs + west blobs fetch hal_silabs Then build the Zephyr kernel and a Bluetooth sample with the following command. The :ref:`bluetooth-observer-sample` sample application is used in @@ -191,14 +184,14 @@ BRD4184A: .. zephyr-app-commands:: :zephyr-app: samples/bluetooth/observer - :board: efr32bg22_brd4184a + :board: sltb010a@0 :goals: build BRD4184B: .. zephyr-app-commands:: :zephyr-app: samples/bluetooth/observer - :board: efr32bg22_brd4184b + :board: sltb010a@2 :goals: build diff --git a/boards/silabs/efr32_thunderboard/doc/efr32bg_sltb010a.jpg b/boards/silabs/dev_kits/sltb010a/doc/sltb010a.jpg similarity index 100% rename from boards/silabs/efr32_thunderboard/doc/efr32bg_sltb010a.jpg rename to boards/silabs/dev_kits/sltb010a/doc/sltb010a.jpg diff --git a/boards/silabs/efr32_thunderboard/dts/bindings/silabs,gecko-wake-up-triggers.yaml b/boards/silabs/dev_kits/sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml similarity index 100% rename from boards/silabs/efr32_thunderboard/dts/bindings/silabs,gecko-wake-up-triggers.yaml rename to boards/silabs/dev_kits/sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml diff --git a/boards/silabs/efr32_thunderboard/pre_dt_board.cmake b/boards/silabs/dev_kits/sltb010a/pre_dt_board.cmake similarity index 100% rename from boards/silabs/efr32_thunderboard/pre_dt_board.cmake rename to boards/silabs/dev_kits/sltb010a/pre_dt_board.cmake diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184.dtsi b/boards/silabs/dev_kits/sltb010a/sltb010a.dts similarity index 88% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184.dtsi rename to boards/silabs/dev_kits/sltb010a/sltb010a.dts index 7badab451585f2..3f352ea6008f1f 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184.dtsi +++ b/boards/silabs/dev_kits/sltb010a/sltb010a.dts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +/dts-v1/; +#include +#include #include "thunderboard.dtsi" / { @@ -11,7 +14,6 @@ aliases { led0 = &led0; sw0 = &button0; - spi-flash0 = &mx25r80; spi0 = &usart0; watchdog0 = &wdog0; /* If enabled, MCUboot uses this for recovery mode entrance */ @@ -21,6 +23,7 @@ chosen { zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; }; }; @@ -56,3 +59,7 @@ &sw_imu_enable { enable-gpios = <&gpiob GECKO_PIN(4) GPIO_ACTIVE_HIGH>; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.dts b/boards/silabs/dev_kits/sltb010a/sltb010a_0.overlay similarity index 51% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.dts rename to boards/silabs/dev_kits/sltb010a/sltb010a_0.overlay index 48a59978911922..c108c8e67db4ce 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.dts +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_0.overlay @@ -4,14 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -/dts-v1/; -#include -#include -#include "efr32bg22_brd4184.dtsi" - / { - model = "Silicon Labs EFR32BG BRD4184A (aka Thunderboard BG22)"; - compatible = "silabs,efr32bg22c224f512im40", "silabs,efr32bg_brd4184a", + model = "Silicon Labs EFR32BG22 Thunderboard (SLTB010A) using BRD4184A"; + compatible = "silabs,efr32bg22c224f512im40", "silabs,sltb010a", "silabs,efr32bg22"; }; diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml similarity index 74% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.yaml rename to boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml index 40c6377a277fab..ff50de0ccb6810 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml @@ -1,5 +1,5 @@ -identifier: efr32bg22_brd4184b -name: EFR32BG22-BRD4184B +identifier: sltb010a@0 +name: Thunderboard EFR32BG22 (SLTB010A, BRD4184A) type: mcu arch: arm ram: 32 diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.dts b/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay similarity index 62% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.dts rename to boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay index 9dded5746bd670..224722da280c3a 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184b.dts +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay @@ -5,14 +5,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -/dts-v1/; -#include -#include -#include "efr32bg22_brd4184.dtsi" - / { - model = "Silicon Labs EFR32BG BRD4184B (aka Thunderboard BG22)"; - compatible = "silabs,efr32bg22c224f512im40", "silabs,efr32bg_brd4184b", + model = "Silicon Labs EFR32BG22 Thunderboard (SLTB010A) using BRD4184B"; + compatible = "silabs,efr32bg22c224f512im40", "silabs,sltb010a", "silabs,efr32bg22"; }; diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml similarity index 74% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.yaml rename to boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml index 37bc5bed239348..24e1dfb580d5e3 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184a.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml @@ -1,5 +1,5 @@ -identifier: efr32bg22_brd4184a -name: EFR32BG22-BRD4184A +identifier: sltb010a@2 +name: Thunderboard EFR32BG22 (SLTB010A, BRD4184B) type: mcu arch: arm ram: 32 diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184a_defconfig b/boards/silabs/dev_kits/sltb010a/sltb010a_defconfig similarity index 100% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184a_defconfig rename to boards/silabs/dev_kits/sltb010a/sltb010a_defconfig diff --git a/boards/silabs/efr32_thunderboard/thunderboard.dtsi b/boards/silabs/dev_kits/sltb010a/thunderboard.dtsi similarity index 100% rename from boards/silabs/efr32_thunderboard/thunderboard.dtsi rename to boards/silabs/dev_kits/sltb010a/thunderboard.dtsi diff --git a/boards/silabs/efr32xg24_dk2601b/Kconfig b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig similarity index 77% rename from boards/silabs/efr32xg24_dk2601b/Kconfig rename to boards/silabs/dev_kits/xg24_dk2601b/Kconfig index c695033c2ff53d..f346dac95afe34 100644 --- a/boards/silabs/efr32xg24_dk2601b/Kconfig +++ b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig @@ -3,10 +3,10 @@ # Copyright (c) 2022, Silicon Labs # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFR32XG24_DK2601B +if BOARD_XG24_DK2601B module = BOARD_EFR32MG24 module-str = Board Control source "subsys/logging/Kconfig.template.log_config" -endif # BOARD_EFR32XG24_DK2601B +endif # BOARD_XG24_DK2601B diff --git a/boards/silabs/efr32xg24_dk2601b/Kconfig.defconfig b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig similarity index 81% rename from boards/silabs/efr32xg24_dk2601b/Kconfig.defconfig rename to boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig index dbd2884e28ab72..a6a2953d6e5141 100644 --- a/boards/silabs/efr32xg24_dk2601b/Kconfig.defconfig +++ b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2021, Sateesh Kotapati # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFR32XG24_DK2601B +if BOARD_XG24_DK2601B config CMU_HFXO_FREQ default 40000000 @@ -33,10 +33,6 @@ config MINIMAL_LIBC_MALLOC_ARENA_SIZE config MAIN_STACK_SIZE default 2304 -choice BT_HCI_BUS_TYPE - default BT_SILABS_HCI -endchoice - if SHELL config SHELL_STACK_SIZE @@ -46,4 +42,4 @@ endif # SHELL endif # BT -endif # BOARD_EFR32XG24_DK2601B +endif # BOARD_XG24_DK2601B diff --git a/boards/silabs/efr32xg24_dk2601b/Kconfig.efr32xg24_dk2601b b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.xg24_dk2601b similarity index 83% rename from boards/silabs/efr32xg24_dk2601b/Kconfig.efr32xg24_dk2601b rename to boards/silabs/dev_kits/xg24_dk2601b/Kconfig.xg24_dk2601b index 3826dc11b2a725..bf4ac3677f1f4c 100644 --- a/boards/silabs/efr32xg24_dk2601b/Kconfig.efr32xg24_dk2601b +++ b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.xg24_dk2601b @@ -3,5 +3,5 @@ # Copyright (c) 2021, Sateesh Kotapati # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFR32XG24_DK2601B +config BOARD_XG24_DK2601B select SOC_PART_NUMBER_EFR32MG24B310F1536IM48 diff --git a/boards/silabs/efr32xg24_dk2601b/board.c b/boards/silabs/dev_kits/xg24_dk2601b/board.c similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/board.c rename to boards/silabs/dev_kits/xg24_dk2601b/board.c diff --git a/boards/silabs/efr32xg24_dk2601b/board.cmake b/boards/silabs/dev_kits/xg24_dk2601b/board.cmake similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/board.cmake rename to boards/silabs/dev_kits/xg24_dk2601b/board.cmake diff --git a/boards/silabs/efr32xg24_dk2601b/board.yml b/boards/silabs/dev_kits/xg24_dk2601b/board.yml similarity index 71% rename from boards/silabs/efr32xg24_dk2601b/board.yml rename to boards/silabs/dev_kits/xg24_dk2601b/board.yml index d4efb7ba178927..f946744d228e6a 100644 --- a/boards/silabs/efr32xg24_dk2601b/board.yml +++ b/boards/silabs/dev_kits/xg24_dk2601b/board.yml @@ -1,5 +1,5 @@ board: - name: efr32xg24_dk2601b + name: xg24_dk2601b vendor: silabs socs: - name: efr32mg24b310f1536im48 diff --git a/boards/silabs/efr32xg24_dk2601b/doc/img/efr32xg24_dk2601b.jpg b/boards/silabs/dev_kits/xg24_dk2601b/doc/img/xg24_dk2601b.jpg similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/doc/img/efr32xg24_dk2601b.jpg rename to boards/silabs/dev_kits/xg24_dk2601b/doc/img/xg24_dk2601b.jpg diff --git a/boards/silabs/efr32xg24_dk2601b/doc/index.rst b/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst similarity index 91% rename from boards/silabs/efr32xg24_dk2601b/doc/index.rst rename to boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst index f6be0f828897d6..551d08765de881 100644 --- a/boards/silabs/efr32xg24_dk2601b/doc/index.rst +++ b/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst @@ -1,7 +1,7 @@ .. _efr32mg24_dk2601b: -xG24-DK2601B -########################### +EFR32xG24 Dev Kit (xG24-DK2601B) +################################ Overview ******** @@ -10,10 +10,10 @@ The EFR32MG24 Mighty Gecko Board dev kit contains a Wireless System-On-Chip from the EFR32MG24 family built on an ARM Cortex®-M33F processor with excellent low power capabilities. -.. figure:: ./img/efr32xg24_dk2601b.jpg +.. figure:: ./img/xg24_dk2601b.jpg :height: 260px :align: center - :alt: SLWRB4180A Mighty Gecko Radio Board + :alt: xG24-DK2601B Dev Kit board xG24-DK2601B (image courtesy of Silicon Labs) @@ -94,13 +94,13 @@ means Pin number 2 on PORTA, as used in the board's datasheets and manuals. +-------+-------------+-------------------------------------+ | PB3 | GPIO | Push Button 1 | +-------+-------------+-------------------------------------+ -| PA5 | USART0_TX | UART Console EFM_BC_TX US0_TX | +| PA5 | USART0_TX | UART Console VCOM_TX US0_TX | +-------+-------------+-------------------------------------+ -| PA6 | USART0_RX | UART Console EFM_BC_RX US0_RX | +| PA6 | USART0_RX | UART Console VCOM_RX US0_RX | +-------+-------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b_defconfig` +:zephyr_file:`boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig` System Clock ============ @@ -129,10 +129,10 @@ Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32xg24_dk2601b + :board: xg24_dk2601b :goals: build -Connect the efr32xg24_dk2601b to your host computer using the USB port and you +Connect the xg24_dk2601b to your host computer using the USB port and you should see a USB connection. Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -147,7 +147,7 @@ terminal session: .. code-block:: console - Hello World! efr32xg24_dk2601b + Hello World! xg24_dk2601b Bluetooth ========= @@ -157,7 +157,7 @@ blobs from the SiLabs HAL repository. .. code-block:: console - west blobs fetch silabs + west blobs fetch hal_silabs Then build the Zephyr kernel and a Bluetooth sample with the following command. The :ref:`bluetooth-observer-sample` sample application is used in @@ -165,7 +165,7 @@ this example. .. zephyr-app-commands:: :zephyr-app: samples/bluetooth/observer - :board: efr32xg24_dk2601b + :board: xg24_dk2601b :goals: build .. _EFR32MG24 Website: diff --git a/boards/silabs/efr32xg24_dk2601b/dts/bindings/silabs,gecko-wake-up-trigger.yaml b/boards/silabs/dev_kits/xg24_dk2601b/dts/bindings/silabs,gecko-wake-up-trigger.yaml similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/dts/bindings/silabs,gecko-wake-up-trigger.yaml rename to boards/silabs/dev_kits/xg24_dk2601b/dts/bindings/silabs,gecko-wake-up-trigger.yaml diff --git a/boards/silabs/efr32mg_sltb004a/pre_dt_board.cmake b/boards/silabs/dev_kits/xg24_dk2601b/pre_dt_board.cmake similarity index 100% rename from boards/silabs/efr32mg_sltb004a/pre_dt_board.cmake rename to boards/silabs/dev_kits/xg24_dk2601b/pre_dt_board.cmake diff --git a/boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.dts b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts similarity index 94% rename from boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.dts rename to boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts index ffa883da6f9e60..ac03b32ff37e5b 100644 --- a/boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.dts +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts @@ -10,8 +10,8 @@ #include / { - model = "Silicon Labs BRD2601B (Mighty Gecko Radio Board)"; - compatible = "silabs,efr32mg24_brd2601b", "silabs,efr32mg24"; + model = "Silicon Labs BRD2601B (xG24 Dev Kit)"; + compatible = "silabs,xg24_brd2601b", "silabs,efr32mg24"; chosen { zephyr,console = &usart0; @@ -19,6 +19,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; }; aliases { @@ -146,25 +147,25 @@ /* Reserve 464 kB for the application in slot 0 */ slot0_partition: partition@c000 { - label = "storage"; + label = "image-0"; reg = <0x0000c000 0x00074000>; }; /* Reserve 464 kB for the application in slot 1 */ slot1_partition: partition@80000 { - label = "image-0"; + label = "image-1"; reg = <0x00080000 0x00074000>; }; /* Reserve 32 kB for the scratch partition */ scratch_partition: partition@f4000 { - label = "image-1"; + label = "image-scratch"; reg = <0x000f4000 0x00008000>; }; /* Set 528Kb of storage at the end of the 1024Kb of flash */ storage_partition: partition@fc000 { - label = "image-scratch"; + label = "storage"; reg = <0x000fc000 0x00084000>; }; }; @@ -177,3 +178,7 @@ &stimer0 { status = "okay"; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml similarity index 75% rename from boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml rename to boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml index 522d945ce5afcb..fece6ecddf557c 100644 --- a/boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b.yaml +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml @@ -1,5 +1,5 @@ -identifier: efr32xg24_dk2601b -name: BRD4601B +identifier: xg24_dk2601b +name: xG24 Dev Kit (xG24-DK2601B, BRD2601B) type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b_defconfig b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/efr32xg24_dk2601b_defconfig rename to boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig diff --git a/boards/silabs/dev_kits/xg27_dk2602a/CMakeLists.txt b/boards/silabs/dev_kits/xg27_dk2602a/CMakeLists.txt new file mode 100644 index 00000000000000..ca93e65ac913ab --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_UART_GECKO) + zephyr_library() + zephyr_library_sources(board.c) +endif() diff --git a/boards/silabs/dev_kits/xg27_dk2602a/Kconfig b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig new file mode 100644 index 00000000000000..965bfde207a38a --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig @@ -0,0 +1,8 @@ +# EFR32 Thunderboard-style boards + +# Copyright (c) 2022, Silicon Labs +# SPDX-License-Identifier: Apache-2.0 + +module = BOARD_XG27_DK2602A +module-str = Board Control +source "subsys/logging/Kconfig.template.log_config" diff --git a/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig new file mode 100644 index 00000000000000..850f2cd8538bb0 --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig @@ -0,0 +1,32 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config COMMON_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +config REGULATOR + default y if SI7210 diff --git a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg27_brd2602a b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.xg27_dk2602a similarity index 82% rename from boards/silabs/efr32_thunderboard/Kconfig.efr32bg27_brd2602a rename to boards/silabs/dev_kits/xg27_dk2602a/Kconfig.xg27_dk2602a index 7bf2e70d45533d..d5f2945cdfdfe7 100644 --- a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg27_brd2602a +++ b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.xg27_dk2602a @@ -3,5 +3,5 @@ # Copyright (c) 2021, Sateesh Kotapati # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFR32BG27_BRD2602A +config BOARD_XG27_DK2602A select SOC_PART_NUMBER_EFR32BG27C140F768IM40 diff --git a/boards/silabs/dev_kits/xg27_dk2602a/board.c b/boards/silabs/dev_kits/xg27_dk2602a/board.c new file mode 100644 index 00000000000000..fcdcab0f1b29af --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/board.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifdef CONFIG_SOC_GECKO_DEV_INIT +#include "em_cmu.h" +#endif + + +LOG_MODULE_REGISTER(dev_kit, CONFIG_BOARD_XG27_DK2602A_LOG_LEVEL); + +static int dev_kit_init_clocks(void); + +static int dev_kit_init(void) +{ + int ret; + +#ifdef CONFIG_SOC_GECKO_DEV_INIT + dev_kit_init_clocks(); +#endif + static struct gpio_dt_spec wake_up_gpio_dev = + GPIO_DT_SPEC_GET(DT_NODELABEL(wake_up_trigger), gpios); + + + if (!gpio_is_ready_dt(&wake_up_gpio_dev)) { + LOG_ERR("Wake-up GPIO device was not found!\n"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&wake_up_gpio_dev, GPIO_OUTPUT_ACTIVE); + if (ret < 0) + return ret; + + return 0; +} + +#ifdef CONFIG_SOC_GECKO_DEV_INIT +static int dev_kit_init_clocks(void) +{ + CMU_ClockSelectSet(cmuClock_SYSCLK, cmuSelect_HFRCODPLL); +#if defined(_CMU_EM01GRPACLKCTRL_MASK) + CMU_ClockSelectSet(cmuClock_EM01GRPACLK, cmuSelect_HFRCODPLL); +#endif +#if defined(_CMU_EM01GRPBCLKCTRL_MASK) + CMU_ClockSelectSet(cmuClock_EM01GRPBCLK, cmuSelect_HFRCODPLL); +#endif + CMU_ClockSelectSet(cmuClock_EM23GRPACLK, cmuSelect_LFRCO); +#if defined(RTCC_PRESENT) + CMU_ClockSelectSet(cmuClock_RTCC, cmuSelect_LFRCO); +#endif + CMU_ClockSelectSet(cmuClock_WDOG0, cmuSelect_LFRCO); + + return 0; +} +#endif + +/* needs to be done after GPIO driver init */ +SYS_INIT(dev_kit_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/silabs/dev_kits/xg27_dk2602a/board.cmake b/boards/silabs/dev_kits/xg27_dk2602a/board.cmake new file mode 100644 index 00000000000000..a5086fdebd91fb --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32BG27CxxxF768" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +board_runner_args(silabs_commander "--device=EFR32BG27C140F768IM40") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/silabs/dev_kits/xg27_dk2602a/board.yml b/boards/silabs/dev_kits/xg27_dk2602a/board.yml new file mode 100644 index 00000000000000..83a3037a1a7852 --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/board.yml @@ -0,0 +1,5 @@ +boards: + - name: xg27_dk2602a + vendor: silabs + socs: + - name: efr32bg27c140f768im40 diff --git a/boards/silabs/efr32_thunderboard/doc/brd2602.rst b/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst similarity index 84% rename from boards/silabs/efr32_thunderboard/doc/brd2602.rst rename to boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst index a9569d66518d3a..8bf44f5edbd8c4 100644 --- a/boards/silabs/efr32_thunderboard/doc/brd2602.rst +++ b/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst @@ -1,10 +1,17 @@ -.. _efr32BG27_brd2602: +.. _xg27_dk2602a: -SiLabs EFR32BG27-BRD2602(A) (EFR32BG27 +8 dBm Dev Kit Board) -############################################################ +EFR32xG27 Dev Kit (xG27-DK2602A) +################################ -BRD2602 is a board based on EFR32BG27 SoC and is one of -:ref:`efr32_thunderboard`. +Silicon Labs xG27-DK2602A is a Dev Kit using the EFR32BG27 SoC. The kit +consists of the EFR32BG27 +8 dBm Dev Kit Board (BRD2602A). + +.. figure:: ./xg27_dk2602a.png + :height: 260px + :align: center + :alt: xG27-DK2602A + + xG27-DK2602A (image courtesy of Silicon Labs) Hardware ******** @@ -28,10 +35,14 @@ Hardware - Reset button - CR2032 coin cell holder and external battery connector +For more information, refer to these documents: + +- `xG27 Dev Kit User's Guide`_ + Supported Features ================== -The efr32bg27_brd2602 board configuration supports the following hardware features: +The xg27_dk2602a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | @@ -50,7 +61,7 @@ The efr32bg27_brd2602 board configuration supports the following hardware featur Flashing ======== -The EFR32BG27-BRD2602A includes an embedded `J-Link`_ adapter built around +The xG27 Dev Kit includes an embedded `J-Link`_ adapter built around EFM32GG12 microcontroller (not user-programmable). The adapter provides: @@ -99,7 +110,7 @@ Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32bg27_brd2602a + :board: xg27_dk2602a :goals: build Connect your device to your host computer using the USB port and you @@ -117,7 +128,7 @@ the following message: .. code-block:: console - Hello World! efr32bg27_brd2602a + Hello World! xg27_dk2602a .. _picocom: https://github.com/npat-efault/picocom @@ -127,3 +138,6 @@ the following message: .. _Simplicity Commander: https://www.silabs.com/developers/mcu-programming-options + +.. _xG27 Dev Kit User's Guide: + https://www.silabs.com/documents/public/user-guides/ug554-brd2602a-user-guide.pdf diff --git a/boards/silabs/dev_kits/xg27_dk2602a/doc/xg27_dk2602a.png b/boards/silabs/dev_kits/xg27_dk2602a/doc/xg27_dk2602a.png new file mode 100644 index 00000000000000..0bb9399b11baa5 Binary files /dev/null and b/boards/silabs/dev_kits/xg27_dk2602a/doc/xg27_dk2602a.png differ diff --git a/boards/silabs/dev_kits/xg27_dk2602a/dts/bindings/silabs,gecko-wake-up-triggers.yaml b/boards/silabs/dev_kits/xg27_dk2602a/dts/bindings/silabs,gecko-wake-up-triggers.yaml new file mode 100644 index 00000000000000..fd49c3732cad56 --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/dts/bindings/silabs,gecko-wake-up-triggers.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2022, Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO Wake Up Trigger for EFR32BG22/EFR32BG27 + +compatible: "silabs,gecko-wake-up-trigger" + +include: base.yaml + +properties: + gpios: + type: phandle-array + required: true + description: | + GPIO used as wake up trigger from EM4 sleep diff --git a/boards/silabs/efr32xg24_dk2601b/pre_dt_board.cmake b/boards/silabs/dev_kits/xg27_dk2602a/pre_dt_board.cmake similarity index 100% rename from boards/silabs/efr32xg24_dk2601b/pre_dt_board.cmake rename to boards/silabs/dev_kits/xg27_dk2602a/pre_dt_board.cmake diff --git a/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi b/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi new file mode 100644 index 00000000000000..71979837476708 --- /dev/null +++ b/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + zephyr,bt-c2h-uart = &usart1; + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpiob GECKO_PIN(0) GPIO_ACTIVE_HIGH>; + label = "LED 0"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpiob GECKO_PIN(1) GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + zephyr,code = ; + }; + }; + + wake_up_trigger: gpio-wake-up { + compatible = "silabs,gecko-wake-up-trigger"; + gpios = <&gpioa GECKO_PIN(5) GPIO_ACTIVE_LOW>; + }; + + /* GPIOs that power up different sensors */ + sw_sensor_enable: gpio_switch_0 { + compatible = "regulator-fixed"; + status = "okay"; + regulator-name = "sw_sensor_enable"; + startup-delay-us = <100000>; + /* Always on since sensor drivers won't enable it automatically */ + regulator-always-on; + }; + + sw_mic_enable: gpio_switch_1 { + compatible = "regulator-fixed"; + status = "okay"; + regulator-name = "sw_mic_enable"; + startup-delay-us = <100000>; + }; + + sw_imu_enable: gpio_switch_2 { + compatible = "regulator-fixed"; + status = "okay"; + regulator-name = "sw_imu_enable"; + startup-delay-us = <100000>; + }; + +}; + +&cpu0 { + clock-frequency = <76800000>; +}; + +&pstate_em3 { + status = "disabled"; +}; + +&usart0 { + status = "okay"; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + + cs-gpios = <&gpioc 3 GPIO_ACTIVE_LOW>; + + mx25r80: mx25r8035f@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <80000000>; + size = <0x800000>; + jedec-id = [c2 28 14]; + sfdp-bfp = [ + e5 20 f1 ff ff ff 7f 00 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 b7 44 83 38 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + }; +}; + +&usart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; +}; + +&wdog0 { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&gpio { + location-swo = <0>; + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&burtc0 { + status = "okay"; +}; + +&stimer0 { + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&pinctrl { + i2c0_default: i2c0_default { + group1 { + psels = , + , + , + ; + }; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; + + si7210@30 { + compatible = "silabs,si7210"; + status = "okay"; + reg = <0x30>; + }; +}; + +&adc0 { + status = "okay"; +}; diff --git a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.dts b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts similarity index 89% rename from boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.dts rename to boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts index b267cd8356bad3..6dba2bfa6485df 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.dts +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts @@ -10,15 +10,14 @@ #include "thunderboard.dtsi" / { - model = "Silicon Labs EFR32BG27C140F768IM40 Thunderboard-style board"; - compatible = "silabs,efr32bg27c140f768im40", "silabs,efr32bg27_brd2602a", + model = "Silicon Labs xG27-DK2602A Dev Kit"; + compatible = "silabs,efr32bg27c140f768im40", "silabs,xg27_dk2602a", "silabs,efr32bg27"; /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; sw0 = &button0; - spi-flash0 = &mx25r80; spi0 = &usart0; watchdog0 = &wdog0; /* If enabled, MCUboot uses this for recovery mode entrance */ @@ -28,6 +27,7 @@ chosen { zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; }; }; @@ -81,3 +81,7 @@ &button0 { gpios = <&gpiob GECKO_PIN(3) GPIO_ACTIVE_LOW>; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.yaml b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml similarity index 73% rename from boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.yaml rename to boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml index 844a48854d55ec..b965fa25afeb66 100644 --- a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a.yaml +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml @@ -1,5 +1,5 @@ -identifier: efr32bg27_brd2602a -name: EFR32BG27_BRD2602A +identifier: xg27_dk2602a +name: xG27 Dev Kit (xG27-DK2602A, BRD2602A) type: mcu arch: arm ram: 64 diff --git a/boards/silabs/efr32_thunderboard/efr32bg22_brd4184b_defconfig b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig similarity index 100% rename from boards/silabs/efr32_thunderboard/efr32bg22_brd4184b_defconfig rename to boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a_defconfig diff --git a/boards/silabs/efm32pg_stk3402a/Kconfig.efm32pg_stk3402a b/boards/silabs/efm32pg_stk3402a/Kconfig.efm32pg_stk3402a deleted file mode 100644 index 7f4bea414753e4..00000000000000 --- a/boards/silabs/efm32pg_stk3402a/Kconfig.efm32pg_stk3402a +++ /dev/null @@ -1,9 +0,0 @@ -# EFM32PG STK3402A board - -# Copyright (c) 2018, Christian Taedcke -# Copyright (c) 2019 Lemonbeat GmbH -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_EFM32PG_STK3402A - select SOC_PART_NUMBER_EFM32PG12B500F1024GL125 if BOARD_EFM32PG_STK3402A_EFM32PG12B500F1024GL125 - select SOC_PART_NUMBER_EFM32JG12B500F1024GL125 if BOARD_EFM32PG_STK3402A_EFM32JG12B500F1024GL125 diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.dts b/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.dts deleted file mode 100644 index 090b217e49a676..00000000000000 --- a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.dts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2019 Lemonbeat GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; -#include -#include "efm32pg_stk3402a_common.dtsi" - -/ { - model = "Silicon Labs EFM32PG STK3402A board (JG)"; - compatible = "silabs,efm32pg_stk3402a_jg", "silabs,efm32jg12b"; - -}; diff --git a/boards/silabs/efr32_radio/Kconfig.efr32_radio b/boards/silabs/efr32_radio/Kconfig.efr32_radio deleted file mode 100644 index 1ebc6a94455fa3..00000000000000 --- a/boards/silabs/efr32_radio/Kconfig.efr32_radio +++ /dev/null @@ -1,15 +0,0 @@ -# EFR32BG13 BRD4104A / EFR32MG21 BRD4180A / -# EFR32FG1P BRD4250B / EFR32FG13P BRD4255A board - -# Copyright (c) 2020 Piotr Mienkowski -# Copyright (c) 2020 TriaGnoSys GmbH -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_EFR32_RADIO - select SOC_PART_NUMBER_EFR32BG13P632F512GM48 if BOARD_EFR32_RADIO_EFR32BG13P632F512GM48 - select SOC_PART_NUMBER_EFR32MG12P433F1024GM68 if BOARD_EFR32_RADIO_EFR32MG12P433F1024GM68 - select SOC_PART_NUMBER_EFR32MG12P432F1024GL125 if BOARD_EFR32_RADIO_EFR32MG12P432F1024GL125 - select SOC_PART_NUMBER_EFR32FG1P133F256GM48 if BOARD_EFR32_RADIO_EFR32FG1P133F256GM48 - select SOC_PART_NUMBER_EFR32MG21A020F1024IM32 if BOARD_EFR32_RADIO_EFR32MG21A020F1024IM32 - select SOC_PART_NUMBER_EFR32MG24B220F1536IM48 if BOARD_EFR32_RADIO_EFR32MG24B220F1536IM48 - select SOC_PART_NUMBER_EFR32FG13P233F512GM48 if BOARD_EFR32_RADIO_EFR32FG13P233F512GM48 diff --git a/boards/silabs/efr32_radio/board.cmake b/boards/silabs/efr32_radio/board.cmake deleted file mode 100644 index 142165be8c7949..00000000000000 --- a/boards/silabs/efr32_radio/board.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -board_runner_args(openocd) - -if(CONFIG_BOARD_EFR32_RADIO_EFR32BG13P632F512GM48) - board_runner_args(jlink "--device=EFR32BG13PxxxF512") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32FG1P133F256GM48) - board_runner_args(jlink "--device=EFR32FG1PxxxF256") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32MG12P433F1024GM68) - board_runner_args(jlink "--device=EFR32MG12PxxxF1024") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32MG12P432F1024GL125) - board_runner_args(jlink "--device=EFR32MG12PxxxF1024") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32MG21A020F1024IM32) - board_runner_args(jlink "--device=EFR32MG21AxxxF1024") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32MG24B220F1536IM48) - board_runner_args(jlink "--device=EFR32MG24BxxxF1536") -elseif(CONFIG_BOARD_EFR32_RADIO_EFR32FG13P233F512GM48) - board_runner_args(jlink "--device=EFR32FG13PxxxF512") -endif() - -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/efr32_radio/board.yml b/boards/silabs/efr32_radio/board.yml deleted file mode 100644 index 5e68cef3826b40..00000000000000 --- a/boards/silabs/efr32_radio/board.yml +++ /dev/null @@ -1,10 +0,0 @@ -boards: - - name: efr32_radio - socs: - - name: efr32bg13p632f512gm48 - - name: efr32mg12p433f1024gm68 - - name: efr32mg12p432f1024gl125 - - name: efr32fg1p133f256gm48 - - name: efr32mg21a020f1024im32 - - name: efr32mg24b220f1536im48 - - name: efr32fg13p233f512gm48 diff --git a/boards/silabs/efr32_radio/doc/brd4104a.rst b/boards/silabs/efr32_radio/doc/brd4104a.rst deleted file mode 100644 index 7fa1336345c550..00000000000000 --- a/boards/silabs/efr32_radio/doc/brd4104a.rst +++ /dev/null @@ -1,122 +0,0 @@ -.. _efr32_radio_brd4104a: - -EFR32 BRD4104A (SLWRB4104A) -########################### - -Overview -******** - -The EFR32BG13 Blue Gecko Bluetooth® Low Energy Radio Board is one of the two -radio boards delivered with `SLWSTK6020B Bluetooth SoC Starter Kit`_. It -contains a Wireless System-On-Chip from the EFR32BG13 family built on an -ARM Cortex®-M4F processor with excellent low power capabilities. - -.. figure:: efr32bg13-slwrb4104a.jpg - :align: center - :alt: SLWRB4104A Blue Gecko Bluetooth® Low Energy Radio Board - - SLWRB4104A (image courtesy of Silicon Labs) - -The BRD4104A a.k.a. SLWRB4104A radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. - -Hardware -******** - -- EFR32BG13P632F512GM48 Blue Gecko SoC -- CPU core: ARM Cortex®-M4 with FPU -- Flash memory: 512 kB -- RAM: 64 kB -- Transmit power: up to +10 dBm -- Operation frequency: 2.4 GHz -- 8Mbit SPI NOR Flash -- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). - -For more information about the EFR32BG13 SoC and BRD4104A board, refer to these -documents: - -- `EFR32BG13 Website`_ -- `EFR32BG13 Datasheet`_ -- `EFR32xG13 Reference Manual`_ -- `SLWSTK6020B Bluetooth SoC Starter Kit`_ -- `BRD4104A User Guide`_ -- `BRD4104A Reference Manual`_ -- `EFR32BG13-BRD4104A Schematics`_ - -Supported Features -================== - -Please refer to -:ref:`EFR32 Radio Board Supported Features ` -for details of the configuration and common features supported by the -``efr32_radio/efr32bg13p632f512gm48`` board. - -The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48_defconfig` - -System Clock -============ - -The EFR32BG13P SoC is configured to use the 38.4 MHz external oscillator on the -board. - -Serial Port -=========== - -The EFR32BG13P SoC has three USARTs and one Low Energy UARTs (LEUART). -USART0 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - -Flashing -======== - -Connect the BRD4001A board with a mounted BRD4104A radio module to your host -computer using the USB port. - -Here is an example for the :ref:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: efr32_radio/efr32bg13p632f512gm48 - :goals: flash - -Open a serial terminal (minicom, putty, etc.) with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and you should see the following message in the terminal: - -.. code-block:: console - - Hello World! efr32_radio - - -.. _EFR32BG13 Website: - https://www.silabs.com/wireless/bluetooth/efr32bg13-series-1-socs - -.. _EFR32BG13 Datasheet: - https://www.silabs.com/documents/public/data-sheets/efr32bg13-datasheet.pdf - -.. _EFR32xG13 Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdf - -.. _SLWSTK6020B Bluetooth SoC Starter Kit: - https://www.silabs.com/products/development-tools/wireless/bluetooth/blue-gecko-bluetooth-low-energy-soc-starter-kit - -.. _BRD4104A User Guide: - https://www.silabs.com/documents/public/user-guides/ug279-brd4104a-user-guide.pdf - -.. _BRD4104A Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/brd4104a-rm.pdf - -.. _EFR32BG13-BRD4104A Schematics: - https://www.silabs.com/documents/public/schematic-files/BRD4104A-A00-schematic.pdf diff --git a/boards/silabs/efr32_radio/doc/brd4161a.rst b/boards/silabs/efr32_radio/doc/brd4161a.rst deleted file mode 100644 index 992d5f7a4acd36..00000000000000 --- a/boards/silabs/efr32_radio/doc/brd4161a.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. _efr32_radio_brd4161a: - -EFR32 BRD4161A (SLWRB4161A) -########################### - -Overview -******** - -The EFR32MG12 Mighty Gecko Radio Board contains a Wireless System-On-Chip -from the EFR32MG12 family built on an ARM Cortex®-M4F processor with excellent -low power capabilities. - -.. figure:: efr32mg12-slwrb4161a.jpeg - :align: center - :alt: SLWRB4161A Mighty Gecko Radio Board - - SLWRB4161A (image courtesy of Silicon Labs) - -The BRD4161A a.k.a. SLWRB4161A radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. - -Hardware -******** - -- EFR32MG12P432F1024GL125 Mighty Gecko SoC -- CPU core: ARM Cortex®-M4 with FPU -- Flash memory: 1024 kB -- RAM: 256 kB -- Transmit power: up to +19 dBm -- Operation frequency: 2.4 GHz and Sub-Ghz -- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). - -For more information about the EFR32MG12 SoC and BRD4170A board, refer to these -documents: - -- `EFR32MG12 Website`_ -- `EFR32MG12 Datasheet`_ -- `EFR32xG12 Reference Manual`_ -- `BRD4161A User Guide`_ - -Supported Features -================== - -Please refer to -:ref:`EFR32 Radio Board Supported Features ` -for details of the configuration and common features supported by the -``efr32_radio/efr32mg12p432f1024gl125`` board. - -The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125_defconfig` - -System Clock -============ - -The EFR32MG12P SoC is configured to use the 38.4 MHz external oscillator on the -board. - -Serial Port -=========== - -The EFR32MG12P SoC has four USARTs and one Low Energy UARTs (LEUART). -USART0 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - -Flashing -======== - -Connect the BRD4001A board with a mounted BRD4170A radio module to your host -computer using the USB port. - -Here is an example for the :ref:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: efr32_radio/efr32mg12p432f1024gl125 - :goals: flash - -Open a serial terminal (minicom, putty, etc.) with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and you should see the following message in the terminal: - -.. code-block:: console - - Hello World! efr32_radio - - -.. _EFR32MG12 Website: - https://www.silabs.com/wireless/zigbee/efr32mg12-series-1-socs - -.. _EFR32MG12 Datasheet: - https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf - -.. _EFR32xG12 Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf - -.. _BRD4161A User Guide: - https://www.silabs.com/documents/public/user-guides/ug260-brd4161a-user-guide.pdf diff --git a/boards/silabs/efr32_radio/doc/brd4170a.rst b/boards/silabs/efr32_radio/doc/brd4170a.rst deleted file mode 100644 index a1751424f37c8c..00000000000000 --- a/boards/silabs/efr32_radio/doc/brd4170a.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. _efr32_radio_brd4170a: - -EFR32 BRD4170A (SLWRB4170A) -########################### - -Overview -******** - -The EFR32MG12 Mighty Gecko Radio Board contains a Wireless System-On-Chip -from the EFR32MG12 family built on an ARM Cortex®-M4F processor with excellent -low power capabilities. - -.. figure:: efr32mg12-slwrb4170a.jpg - :align: center - :alt: SLWRB4170A Mighty Gecko Radio Board - - SLWRB4170A (image courtesy of Silicon Labs) - -The BRD4170A a.k.a. SLWRB4170A radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. - -Hardware -******** - -- EFR32MG12P433F1024GM68 Mighty Gecko SoC -- CPU core: ARM Cortex®-M4 with FPU -- Flash memory: 1024 kB -- RAM: 256 kB -- Transmit power: up to +19 dBm -- Operation frequency: 2.4 GHz and Sub-Ghz -- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). - -For more information about the EFR32MG12 SoC and BRD4170A board, refer to these -documents: - -- `EFR32MG12 Website`_ -- `EFR32MG12 Datasheet`_ -- `EFR32xG12 Reference Manual`_ -- `BRD4170A User Guide`_ - -Supported Features -================== - -Please refer to -:ref:`EFR32 Radio Board Supported Features ` -for details of the configuration and common features supported by the -``efr32_radio/efr32mg12p433f1024gm68`` board. - -The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68_defconfig` - -System Clock -============ - -The EFR32MG12P SoC is configured to use the 38.4 MHz external oscillator on the -board. - -Serial Port -=========== - -The EFR32MG12P SoC has four USARTs and one Low Energy UARTs (LEUART). -USART0 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - -Flashing -======== - -Connect the BRD4001A board with a mounted BRD4170A radio module to your host -computer using the USB port. - -Here is an example for the :ref:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: efr32_radio/efr32mg12p433f1024gm68 - :goals: flash - -Open a serial terminal (minicom, putty, etc.) with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and you should see the following message in the terminal: - -.. code-block:: console - - Hello World! efr32_radio - - -.. _EFR32MG12 Website: - https://www.silabs.com/wireless/zigbee/efr32mg12-series-1-socs - -.. _EFR32MG12 Datasheet: - https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf - -.. _EFR32xG12 Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf - -.. _BRD4170A User Guide: - https://www.silabs.com/documents/public/user-guides/ug342-brd4170a-user-guide.pdf diff --git a/boards/silabs/efr32_radio/doc/brd4250b.rst b/boards/silabs/efr32_radio/doc/brd4250b.rst deleted file mode 100644 index 6ccb4ca22caa0f..00000000000000 --- a/boards/silabs/efr32_radio/doc/brd4250b.rst +++ /dev/null @@ -1,121 +0,0 @@ -.. _efr32_radio_brd4250b: - -EFR32 BRD4250B (SLWRB4250B) -########################### - -Overview -******** - -The EFR32FG1 Flex Gecko 2.4 GHz and 868 MHz Radio Board is delivered as part of -`SLWSTK6061B Proprietary Wireless Starter Kit`_. It contains a EFR32FG1 Wireless -SoC built on an ARM Cortex®-M4F processor with excellent low power capabilities. - -.. figure:: efr32fg1-slwrb4250b.jpg - :align: center - :alt: SLWRB4250B Flex Gecko 2.4 GHz and 868 MHz Radio Board - - SLWRB4250B (image courtesy of Silicon Labs) - -The BRD4250B a.k.a. SLWRB4250B radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. - -Hardware -******** - -- EFR32FG1P133F256GM48 Flex Gecko SoC -- CPU core: ARM Cortex®-M4 with FPU -- Flash memory: 256 kB -- RAM: 32 kB -- Transmit power: up to +13 dBm -- Operation frequency: 2.4 GHz, 868 MHz -- 8Mbit SPI NOR Flash -- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). - -For more information about the EFR32FG1 SoC and BRD4250B board, refer to these -documents: - -- `EFR32FG1 Website`_ -- `EFR32FG1 Datasheet`_ -- `EFR32xG1 Reference Manual`_ -- `SLWSTK6061B Proprietary Wireless Starter Kit`_ -- `BRD4250B User Guide`_ -- `BRD4250B Reference Manual`_ -- `EFR32FG1-BRD4250B Schematics`_ - -Supported Features -================== - -Please refer to -:ref:`EFR32 Radio Board Supported Features ` -for details of the configuration and common features supported by the -``efr32_radio/efr32fg1p133f256gm48`` board. - -The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48_defconfig` - -System Clock -============ - -The EFR32FG1P SoC is configured to use the 38.4 MHz external oscillator on the -board. - -Serial Port -=========== - -The EFR32FG1P SoC has two USARTs and one Low Energy UARTs (LEUART). -USART0 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - -Flashing -======== - -Connect the BRD4001A board with a mounted BRD4250B radio module to your host -computer using the USB port. - -Here is an example for the :ref:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: efr32_radio/efr32fg1p133f256gm48 - :goals: flash - -Open a serial terminal (minicom, putty, etc.) with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and you should see the following message in the terminal: - -.. code-block:: console - - Hello World! efr32_radio - - -.. _EFR32FG1 Website: - https://www.silabs.com/wireless/proprietary/efr32fg1-series-1-sub-ghz-2-4-ghz-socs - -.. _EFR32FG1 Datasheet: - https://www.silabs.com/documents/public/data-sheets/efr32fg1-datasheet.pdf - -.. _EFR32xG1 Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/efr32xg1-rm.pdf - -.. _SLWSTK6061B Proprietary Wireless Starter Kit: - https://www.silabs.com/products/development-tools/wireless/proprietary/slwstk6061b-efr32-flex-gecko-868-mhz-2-4-ghz-and-sub-ghz-starter-kit - -.. _BRD4250B User Guide: - https://www.silabs.com/documents/public/user-guides/ug182-brd4250b-user-guide.pdf - -.. _BRD4250B Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/brd4250b-rm.pdf - -.. _EFR32FG1-BRD4250B Schematics: - https://www.silabs.com/documents/public/schematic-files/BRD4250B-B02-schematic.pdf diff --git a/boards/silabs/efr32_radio/doc/brd4255a.rst b/boards/silabs/efr32_radio/doc/brd4255a.rst deleted file mode 100644 index 60138f08610c0c..00000000000000 --- a/boards/silabs/efr32_radio/doc/brd4255a.rst +++ /dev/null @@ -1,111 +0,0 @@ -.. _efr32_radio_brd4255a: - -EFR32 BRD4255A (SLWRB4255A) -########################### - -Overview -******** - -The EFR32FG13P Flex Gecko 2.4 GHz and 915 MHz Radio Board is delivered as a -`standalone Proprietary Wireless radio board`_. It contains a EFR32FG13P Wireless -SoC built on an ARM Cortex®-M4F processor with excellent low power capabilities. - -.. figure:: efr32fg13-slwrb4255a.jpg - :align: center - :alt: SLWRB4255A Flex Gecko 2.4 GHz and 915 MHz Radio Board - - SLWRB4255A (image courtesy of Silicon Labs) - -The BRD4255A a.k.a. SLWRB4255A radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. - -Hardware -******** - -- EFR32FG13P233F512GM48 Flex Gecko SoC -- CPU core: ARM Cortex®-M4 with FPU -- Flash memory: 512 kB -- RAM: 64 kB -- Transmit power: up to 19 dBm -- Operation frequency: 2.4 GHz, 915 MHz -- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). - -For more information about the EFR32FG13 SoC and BRD4255A board, refer to these -documents: - -- `EFR32FG13 Website`_ -- `EFR32FG13 Datasheet`_ -- `EFR32xG13 Reference Manual`_ -- `BRD4255A Reference Manual`_ - -Supported Features -================== - -Please refer to -:ref:`EFR32 Radio Board Supported Features ` -for details of the configuration and common features supported by the -``efr32_radio/efr32fg13p233f512gm48`` board. - -The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48_defconfig` - -System Clock -============ - -The EFR32FG13P SoC is configured to use the 38.4 MHz external oscillator on the -board. - -Serial Port -=========== - -The EFR32FG13P SoC has three USARTs and one Low Energy UARTs (LEUART). -USART0 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - -Flashing -======== - -Connect the BRD4001A board with a mounted BRD4255A radio module to your host -computer using the USB port. - -Here is an example for the :ref:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: efr32_radio/efr32fg13p233f512gm48 - :goals: flash - -Open a serial terminal (minicom, putty, etc.) with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and you should see the following message in the terminal: - -.. code-block:: console - - Hello World! efr32_radio - - -.. _EFR32FG13 Website: - https://www.silabs.com/wireless/proprietary/efr32fg13-series-1-sub-ghz-2-4-ghz-socs - -.. _EFR32FG13 Datasheet: - https://www.silabs.com/documents/public/data-sheets/efr32fg13-datasheet.pdf - -.. _EFR32xG13 Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdf - -.. _standalone Proprietary Wireless radio board: - https://www.silabs.com/development-tools/wireless/proprietary/slwrb4255a-efr32fg13-915-mhz-radio-board - -.. _BRD4255A Reference Manual: - https://www.silabs.com/documents/public/reference-manuals/brd4255a-rm.pdf diff --git a/boards/silabs/efr32_radio/doc/efr32_slwstk6020b.jpg b/boards/silabs/efr32_radio/doc/efr32_slwstk6020b.jpg deleted file mode 100644 index 5a93d75ff94843..00000000000000 Binary files a/boards/silabs/efr32_radio/doc/efr32_slwstk6020b.jpg and /dev/null differ diff --git a/boards/silabs/efr32_radio/efr32_radio-pinctrl.dtsi b/boards/silabs/efr32_radio/efr32_radio-pinctrl.dtsi deleted file mode 100644 index ade31fddfd824b..00000000000000 --- a/boards/silabs/efr32_radio/efr32_radio-pinctrl.dtsi +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -&pinctrl { - /* configuration for usart0 device, default state - operating as UART */ - usart0_default: usart0_default { - group1 { - psels = , - , - , - ; - }; - }; -}; diff --git a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184a b/boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184a deleted file mode 100644 index 2cbcd4397614fb..00000000000000 --- a/boards/silabs/efr32_thunderboard/Kconfig.efr32bg22_brd4184a +++ /dev/null @@ -1,7 +0,0 @@ -# EFR32BG SLTB010A board - -# Copyright (c) 2021, Sateesh Kotapati -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_EFR32BG22_BRD4184A - select SOC_PART_NUMBER_EFR32BG22C224F512IM40 diff --git a/boards/silabs/efr32_thunderboard/board.cmake b/boards/silabs/efr32_thunderboard/board.cmake deleted file mode 100644 index d27a7983eb1dbe..00000000000000 --- a/boards/silabs/efr32_thunderboard/board.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_BOARD_EFR32BG22_BRD4184A OR CONFIG_BOARD_EFR32BG22_BRD4184B) - board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") - include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) -elseif(CONFIG_BOARD_EFR32BG27_BRD2602A) - board_runner_args(silabs_commander "--device=EFR32BG27C140F768IM40") - include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) -endif() diff --git a/boards/silabs/efr32_thunderboard/board.yml b/boards/silabs/efr32_thunderboard/board.yml deleted file mode 100644 index ebfe25a104c0ce..00000000000000 --- a/boards/silabs/efr32_thunderboard/board.yml +++ /dev/null @@ -1,13 +0,0 @@ -boards: - - name: efr32bg22_brd4184a - vendor: silabs - socs: - - name: efr32bg22c224f512im40 - - name: efr32bg22_brd4184b - vendor: silabs - socs: - - name: efr32bg22c224f512im40 - - name: efr32bg27_brd2602a - vendor: silabs - socs: - - name: efr32bg27c140f768im40 diff --git a/boards/silabs/efr32_thunderboard/doc/index.rst b/boards/silabs/efr32_thunderboard/doc/index.rst deleted file mode 100644 index ca9bbcf99bd29c..00000000000000 --- a/boards/silabs/efr32_thunderboard/doc/index.rst +++ /dev/null @@ -1,68 +0,0 @@ -.. _efr32_thunderboard: - -EFR32 Thunderboard-style boards -############################### - -Overview -******** - -There are a couple of very similar boards, which we categorize as -"Thunderboard-style boards". The name can be seen on some of Silicon Labs products -that use boards of this style, such as EFR32™ Blue Gecko Starter Kit, -a.k.a Thunderboard EFR32BG22. - -Those boards contains an MCU from the EFR32BG family built on ARM® Cortex®-M33F -processor with low power capabilities. - -For an example of such board, refer to the following site: - -- `Thunderboard EFR32BG22 Website`_ - -Currently the following devices are considered "Thunderboard-style": - -.. toctree:: - :maxdepth: 1 - - brd4184.rst - brd2602.rst - -Serial Port -=========== - -The SoCs used on these boards have two USARTs. -USART1 is connected to the board controller and is used for the console. - -Programming and Debugging -************************* - -.. note:: - Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ - -Flashing -======== - -The Thunderboard boards include `J-Link`_ serial and debug adapters built into the -board. The adapter provides: - -- A USB connection to a host computer running `J-Link software`_ or `Silicon Labs - Simplicity Commander`_. -- A physical UART connection which is relayed over a USB Serial port interface. - -For detailed instructions regarding flashing, refer to documentation of a specific -device. - -.. _Thunderboard EFR32BG22 Website: - https://www.silabs.com/development-tools/thunderboard/thunderboard-bg22-kit - -.. _J-Link: - https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink - -.. _J-Link software: - https://www.segger.com/downloads/jlink - -.. _Silicon Labs Simplicity Commander: - https://www.silabs.com/developers/mcu-programming-options diff --git a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a_defconfig b/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a_defconfig deleted file mode 100644 index 50a14221ec99e9..00000000000000 --- a/boards/silabs/efr32_thunderboard/efr32bg27_brd2602a_defconfig +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_ARM_MPU=y -CONFIG_CONSOLE=y -CONFIG_UART_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_GPIO=y -CONFIG_SOC_GECKO_EMU_DCDC=y -CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y -CONFIG_HW_STACK_PROTECTION=y -CONFIG_PINCTRL=y - -# Used if SysTick is enabled, ignored for BURTC -# (BURTC uses TIMER_READS_ITS_FREQUENCY_AT_RUNTIME) -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=76800000 - -# Use BURTC as system clock source -CONFIG_GECKO_BURTC_TIMER=y -CONFIG_CMU_BURTCCLK_LFXO=y -CONFIG_SYS_CLOCK_TICKS_PER_SEC=1024 diff --git a/boards/silabs/index.rst b/boards/silabs/index.rst index 20a5d34136fc03..d4597d226ce174 100644 --- a/boards/silabs/index.rst +++ b/boards/silabs/index.rst @@ -4,7 +4,26 @@ Silicon Labs ############ .. toctree:: - :maxdepth: 1 + :maxdepth: 2 + :titlesonly: :glob: - **/* + */* + +Silicon Labs development hardware is represented in Zephyr by mapping +Silicon Labs *kits* to Zephyr *boards*. The name used is the orderable product +number (OPN) of the kit, as found on the packaging and on the Silicon Labs +website. The board name in Zephyr is created by normalizing the OPN to lowercase +and replacing dashes with underscores. + +You may find multiple other number and letter sequences silk-screened or lasered +onto Silicon Labs boards, including a PCB* number and a BRD* number. In most +cases, the digits of these sequences correspond to the numerical part of the kit +OPN. For instance, the kit ``xg24_dk2601b``, which is a Dev Kit for the +EFR32xG24 SoC, uses board BRD2601B, which again uses PCB2601A. It is possible to +use the ``west boards`` command to search for board names if you have a PCB and +you don't know what board name to use: + + .. code-block:: console + + west boards -n 2601 diff --git a/boards/silabs/radio_boards/common/efr32-series1-common-pinctrl.dtsi b/boards/silabs/radio_boards/common/efr32-series1-common-pinctrl.dtsi new file mode 100644 index 00000000000000..bb8f7802e6adca --- /dev/null +++ b/boards/silabs/radio_boards/common/efr32-series1-common-pinctrl.dtsi @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for usart0 device, default state - operating as UART */ + usart0_default: usart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + usart1_default: usart1_default { + group1 { + psels = , + , + , + , + , + ; + }; + }; + + usart2_default: usart2_default { + group1 { + psels = , + , + , + , + , + ; + }; + }; +}; diff --git a/boards/silabs/efr32_radio/efr32_radio.dtsi b/boards/silabs/radio_boards/common/efr32-series1-common.dtsi similarity index 88% rename from boards/silabs/efr32_radio/efr32_radio.dtsi rename to boards/silabs/radio_boards/common/efr32-series1-common.dtsi index 361b66b72df389..8ff361eccaaec0 100644 --- a/boards/silabs/efr32_radio/efr32_radio.dtsi +++ b/boards/silabs/radio_boards/common/efr32-series1-common.dtsi @@ -5,7 +5,7 @@ */ #include -#include "efr32_radio-pinctrl.dtsi" +#include "efr32-series1-common-pinctrl.dtsi" / { chosen { @@ -23,7 +23,6 @@ sw0 = &button0; sw1 = &button1; watchdog0 = &wdog0; - spi-flash0 = &mx25r80; }; leds { @@ -69,9 +68,8 @@ #address-cells = <1>; #size-cells = <0>; - location-rx = ; - location-tx = ; - location-clk = ; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; diff --git a/boards/silabs/radio_boards/index.rst b/boards/silabs/radio_boards/index.rst new file mode 100644 index 00000000000000..a4928294fada8d --- /dev/null +++ b/boards/silabs/radio_boards/index.rst @@ -0,0 +1,60 @@ +.. _silabs_radio_boards: + +Radio Boards +############ + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :glob: + + **/* + +Overview +******** + +Radio Boards are used together with a Wireless Mainboard, which is a +development platform for application development and debugging of wireless +products. + +There are two main variants of the Mainboard: + +- Wireless Starter Kit Mainboard (board BRD4001A, available standalone as SLWMB4001A) +- Wireless Pro Kit Mainboard (board BRD4002A, available standalone as Si-MB4002A) + +The Wireless Pro Kit Mainboard is a strict superset of the Wireless Starter Kit, +the two boards are pin compatible for all shared functionality. + +Wireless Starter Kits and Wireless Pro Kits are kits that bundle one or more +Radio Boards with one or more Mainboards. + +In Zephyr, Radio Boards are used as board targets, irrespective of whether the +board was acquired standalone or as part of a Starter Kit or Pro Kit. The kit +name of the standalone Radio Board is used as the board target. + +Hardware +******** + +Wireless Starter Kit Mainboard: + +- Advanced Energy Monitor providing real-time information about energy consumption at up to 10 ksps +- Packet Trace Interface +- Virtual COM port +- On-board Segger J-Link debugger with USB and Ethernet interfaces +- Ultra-low power 128x128 pixel memory LCD +- 2 user buttons and 2 LEDs +- 20 pin 2.54mm expansion header +- Si7021 Relative Humidity and Temperature Sensor +- Breakout pads for Wireless SoC I/O + +Wireless Pro Kit Mainboard: + +- Advanced Energy Monitor providing real-time information about energy consumption at up to 100 ksps +- Packet Trace Interface +- Virtual COM port +- On-board Segger J-Link debugger with USB and Ethernet interfaces +- Ultra-low power 128x128 pixel memory LCD +- 2 user buttons, joystick and 2 LEDs +- 20 pin 2.54mm expansion header +- Si7021 Relative Humidity and Temperature Sensor +- Breakout pads for Wireless SoC I/O diff --git a/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig new file mode 100644 index 00000000000000..0a5a0795b5965f --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SLWRB4104A + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x0 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default n + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_SLWRB4104A diff --git a/boards/silabs/radio_boards/slwrb4104a/Kconfig.slwrb4104a b/boards/silabs/radio_boards/slwrb4104a/Kconfig.slwrb4104a new file mode 100644 index 00000000000000..179b7f02c0a3cf --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4104a/Kconfig.slwrb4104a @@ -0,0 +1,8 @@ +# EFR32BG13 BRD4104A + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4104A + select SOC_PART_NUMBER_EFR32BG13P632F512GM48 diff --git a/boards/silabs/radio_boards/slwrb4104a/board.cmake b/boards/silabs/radio_boards/slwrb4104a/board.cmake new file mode 100644 index 00000000000000..cf1d8ee0e7505b --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4104a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32BG13PxxxF512") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4104a/board.yml b/boards/silabs/radio_boards/slwrb4104a/board.yml new file mode 100644 index 00000000000000..5ca377b2c8fbd6 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4104a/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4104a + socs: + - name: efr32bg13p632f512gm48 diff --git a/boards/silabs/efr32_radio/doc/efr32bg13-slwrb4104a.jpg b/boards/silabs/radio_boards/slwrb4104a/doc/efr32bg13-slwrb4104a.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32bg13-slwrb4104a.jpg rename to boards/silabs/radio_boards/slwrb4104a/doc/efr32bg13-slwrb4104a.jpg diff --git a/boards/silabs/efr32_radio/doc/index.rst b/boards/silabs/radio_boards/slwrb4104a/doc/index.rst similarity index 52% rename from boards/silabs/efr32_radio/doc/index.rst rename to boards/silabs/radio_boards/slwrb4104a/doc/index.rst index 31f79df34e0b53..6522489e79ac6c 100644 --- a/boards/silabs/efr32_radio/doc/index.rst +++ b/boards/silabs/radio_boards/slwrb4104a/doc/index.rst @@ -1,54 +1,47 @@ -.. _efr32_radio: +.. _slwrb4104a: -EFR32 Radio Boards -################## - -.. toctree:: - :maxdepth: 1 - - brd4104a.rst - brd4170a.rst - brd4250b.rst - brd4180a.rst - brd4255a.rst - brd4187c.rst +EFR32BG13 2.4 GHz 10 dBm (SLWRB4104A) +##################################### Overview ******** -Support for EFR32 Radio boards is provided by one of the starter kits - -- `SLWSTK6020B Bluetooth SoC Starter Kit`_ -- `SLWSTK6000B Mighty Gecko Wireless Starter Kit`_ -- `SLWSTK6061B Proprietary Wireless Starter Kit`_ -- `SLWSTK6006A Mighty Gecko Wireless Starter Kit`_ +The EFR32BG13 Blue Gecko Bluetooth® Low Energy Radio Board is one of the two +radio boards delivered with `SLWSTK6020B Bluetooth SoC Starter Kit`_. It +contains a Wireless System-On-Chip from the EFR32BG13 family built on an +ARM Cortex®-M4F processor with excellent low power capabilities. -.. figure:: efr32_slwstk6020b.jpg +.. figure:: efr32bg13-slwrb4104a.jpg :align: center - :alt: SLWSTK6020B Bluetooth SoC Starter Kit + :alt: SLWRB4104A Blue Gecko Bluetooth® Low Energy Radio Board + + SLWRB4104A (image courtesy of Silicon Labs) - SLWSTK6020B (image courtesy of Silicon Labs) +The BRD4104A a.k.a. SLWRB4104A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. Hardware ******** -Wireless Starter Kit Mainboard: - -- Advanced Energy Monitoring provides real-time information about the energy - consumption of an application or prototype design. -- Ultra-low power 128x128 pixel memory LCD -- 2 user buttons and 2 LEDs -- 20 pin expansion header -- Si7021 Humidity and Temperature Sensor -- On-board Segger J-Link USB and Ethernet debugger - -For more information about the BRD4001A board, refer to these documents: - -- `EFR32BG13 Blue Gecko Bluetooth Starter Kit User's Guide`_ -- `EFR32MG21 Mighty Gecko Wireless Starter Kit User's Guide`_ -- `WSTK Main Board BRD4001A Schematics`_ - -.. _efr32_radio_supported_features: +- EFR32BG13P632F512GM48 Blue Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 512 kB +- RAM: 64 kB +- Transmit power: up to +10 dBm +- Operation frequency: 2.4 GHz +- 8Mbit SPI NOR Flash +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32BG13 SoC and BRD4104A board, refer to these +documents: + +- `EFR32BG13 Website`_ +- `EFR32BG13 Datasheet`_ +- `EFR32xG13 Reference Manual`_ +- `SLWSTK6020B Bluetooth SoC Starter Kit`_ +- `BRD4104A User Guide`_ +- `BRD4104A Reference Manual`_ +- `EFR32BG13-BRD4104A Schematics`_ Supported Features ================== @@ -78,16 +71,17 @@ The board configuration supports the following hardware features: | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ -Other hardware features are currently not supported by the port. +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/slwrb4104a/slwrb4104a_defconfig` Connections and IOs =================== -In the following table, the column **Name** contains Pin names. For example, PA2 +In the following table, the column **Pin** contains Pin names. For example, PA2 means Pin number 2 on PORTA, as used in the board's datasheets and manuals. +-------+-------------+-------------------------------------+ -| Name | Function | Usage | +| Pin | Function | Usage | +=======+=============+=====================================+ | PF4 | GPIO | LED0 | +-------+-------------+-------------------------------------+ @@ -98,11 +92,11 @@ means Pin number 2 on PORTA, as used in the board's datasheets and manuals. | PF7 | GPIO | Push Button PB1 | +-------+-------------+-------------------------------------+ | PA5 | GPIO | Board Controller Enable | -| | | EFM_BC_EN | +| | | VCOM_ENABLE | +-------+-------------+-------------------------------------+ -| PA0 | USART0_TX | UART Console EFM_BC_TX US0_TX #0 | +| PA0 | USART0_TX | UART Console VCOM_TX US0_TX #0 | +-------+-------------+-------------------------------------+ -| PA1 | USART0_RX | UART Console EFM_BC_RX US0_RX #0 | +| PA1 | USART0_RX | UART Console VCOM_RX US0_RX #0 | +-------+-------------+-------------------------------------+ | PC6 | SPI_MOSI | Flash MOSI US1_TX #11 | +-------+-------------+-------------------------------------+ @@ -113,39 +107,32 @@ means Pin number 2 on PORTA, as used in the board's datasheets and manuals. | PA4 | SPI_CS | Flash Chip Select (GPIO) | +-------+-------------+-------------------------------------+ -.. _efr32_radio_programming: - -Programming and Debugging -************************* - -The BRD4001A includes an `J-Link`_ serial and debug adaptor built into the -board. The adaptor provides: +System Clock +============ -- A USB connection to the host computer, which exposes a debug interface and a - USB Serial Port. -- A physical UART connection which is relayed over interface USB Serial port. -- An Ethernet connection to support remote debugging. +The EFR32BG13P SoC is configured to use the 38.4 MHz external oscillator on the +board. -It is compatible with the following host debug tools: +Serial Port +=========== -- :ref:`openocd-debug-host-tools` -- :ref:`jlink-debug-host-tools` +The EFR32BG13P SoC has three USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. -OpenOCD is included in the Zephyr SDK. Refer to the links above for information -on how to install required host debug tools if you are not using the Zephyr SDK. +Programming and Debugging +************************* Flashing ======== -Connect the BRD4001A main board with the mounted radio module to your host +Connect the BRD4001A board with a mounted BRD4104A radio module to your host computer using the USB port. -Following example shows how to build the :ref:`hello_world` application for -BRD4104A radio module. +Here is an example for the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32_radio_brd4104a + :board: slwrb4104a :goals: flash Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -159,32 +146,26 @@ Reset the board and you should see the following message in the terminal: .. code-block:: console - Hello World! efr32_radio_brd4104a + Hello World! slwrb4161a -.. _SLWSTK6020B Bluetooth SoC Starter Kit: - https://www.silabs.com/products/development-tools/wireless/bluetooth/blue-gecko-bluetooth-low-energy-soc-starter-kit +.. _EFR32BG13 Website: + https://www.silabs.com/wireless/bluetooth/efr32bg13-series-1-socs -.. _SLWSTK6000B Mighty Gecko Wireless Starter Kit: - https://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit +.. _EFR32BG13 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32bg13-datasheet.pdf -.. _SLWSTK6061B Proprietary Wireless Starter Kit: - https://www.silabs.com/products/development-tools/wireless/proprietary/slwstk6061b-efr32-flex-gecko-868-mhz-2-4-ghz-and-sub-ghz-starter-kit +.. _EFR32xG13 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdf -.. _SLWSTK6006A Mighty Gecko Wireless Starter Kit: - https://www.silabs.com/products/development-tools/wireless/efr32xg21-wireless-starter-kit +.. _SLWSTK6020B Bluetooth SoC Starter Kit: + https://www.silabs.com/products/development-tools/wireless/bluetooth/blue-gecko-bluetooth-low-energy-soc-starter-kit -.. _EFR32BG13 Blue Gecko Bluetooth Starter Kit User's Guide: +.. _BRD4104A User Guide: https://www.silabs.com/documents/public/user-guides/ug279-brd4104a-user-guide.pdf -.. _EFR32MG21 Mighty Gecko Wireless Starter Kit User's Guide: - https://www.silabs.com/documents/public/user-guides/ug385-brd4180a-user-guide.pdf - -.. _EFR32MG24 Mighty Gecko Wireless Starter Kit User's Guide: - https://www.silabs.com/documents/public/user-guides/ug526-brd4187c-user-guide.pdf - -.. _WSTK Main Board BRD4001A Schematics: - https://www.silabs.com/documents/public/schematic-files/BRD4001A-A01-schematic.pdf +.. _BRD4104A Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/brd4104a-rm.pdf -.. _J-Link: - https://www.segger.com/jlink-debug-probes.html +.. _EFR32BG13-BRD4104A Schematics: + https://www.silabs.com/documents/public/schematic-files/BRD4104A-A00-schematic.pdf diff --git a/boards/silabs/radio_boards/slwrb4104a/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4104a/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4104a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.dts b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.dts similarity index 81% rename from boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.dts rename to boards/silabs/radio_boards/slwrb4104a/slwrb4104a.dts index 9ded71ef5598aa..a2a6b76df675d3 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.dts +++ b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.dts @@ -6,14 +6,14 @@ /dts-v1/; #include -#include "efr32_radio.dtsi" +#include "../common/efr32-series1-common.dtsi" / { - model = "Silicon Labs BRD4104A (Blue Gecko Radio Board)"; - compatible = "silabs,efr32_radio_brd4104a", "silabs,efr32bg13p"; + model = "Silicon Labs BRD4104A (Blue Gecko 13 Radio Board)"; + compatible = "silabs,slwrb4104a", "silabs,efr32bg13p"; - aliases { - spi-flash0 = &mx25r80; + chosen { + zephyr,bt-hci = &bt_hci_silabs; }; }; @@ -60,3 +60,7 @@ }; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.yaml b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml similarity index 73% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.yaml rename to boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml index af096e1af9e281..926a55f3150446 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.yaml +++ b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32fg13p233f512gm48 -name: BRD4255A +identifier: slwrb4104a +name: EFR32BG13 2.4 GHz 10 dBm Radio Board (SLWRB4104A) type: mcu arch: arm ram: 64 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48_defconfig b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48_defconfig rename to boards/silabs/radio_boards/slwrb4104a/slwrb4104a_defconfig diff --git a/boards/silabs/efr32_radio/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4104a/support/openocd.cfg similarity index 100% rename from boards/silabs/efr32_radio/support/openocd.cfg rename to boards/silabs/radio_boards/slwrb4104a/support/openocd.cfg diff --git a/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig new file mode 100644 index 00000000000000..1027e26c75c97a --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SLWRB4161A + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x0 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default n + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_SLWRB4161A diff --git a/boards/silabs/radio_boards/slwrb4161a/Kconfig.slwrb4161a b/boards/silabs/radio_boards/slwrb4161a/Kconfig.slwrb4161a new file mode 100644 index 00000000000000..67291857e9f90c --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/Kconfig.slwrb4161a @@ -0,0 +1,8 @@ +# EFR32MG12 BRD4161A + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4161A + select SOC_PART_NUMBER_EFR32MG12P432F1024GL125 diff --git a/boards/silabs/radio_boards/slwrb4161a/board.cmake b/boards/silabs/radio_boards/slwrb4161a/board.cmake new file mode 100644 index 00000000000000..be43109892de56 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32MG12PxxxF1024") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4161a/board.yml b/boards/silabs/radio_boards/slwrb4161a/board.yml new file mode 100644 index 00000000000000..a05542a40d819d --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4161a + socs: + - name: efr32mg12p432f1024gl125 diff --git a/boards/silabs/efr32_radio/doc/efr32mg12-slwrb4161a.jpeg b/boards/silabs/radio_boards/slwrb4161a/doc/efr32mg12-slwrb4161a.jpeg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32mg12-slwrb4161a.jpeg rename to boards/silabs/radio_boards/slwrb4161a/doc/efr32mg12-slwrb4161a.jpeg diff --git a/boards/silabs/radio_boards/slwrb4161a/doc/index.rst b/boards/silabs/radio_boards/slwrb4161a/doc/index.rst new file mode 100644 index 00000000000000..1f09e7d551c77c --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/doc/index.rst @@ -0,0 +1,156 @@ +.. _slwrb4161a: + +EFR32MG12 2.4 GHz 19 dBm (SLWRB4161A) +##################################### + +Overview +******** + +The EFR32MG12 Mighty Gecko Radio Board contains a Wireless System-On-Chip +from the EFR32MG12 family built on an ARM Cortex®-M4F processor with excellent +low power capabilities. + +.. figure:: efr32mg12-slwrb4161a.jpeg + :align: center + :alt: SLWRB4161A Mighty Gecko Radio Board + + SLWRB4161A (image courtesy of Silicon Labs) + +The BRD4161A a.k.a. SLWRB4161A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. + +Hardware +******** + +- EFR32MG12P432F1024GL125 Mighty Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 1024 kB +- RAM: 256 kB +- Transmit power: up to +19 dBm +- Operation frequency: 2.4 GHz and Sub-Ghz +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32MG12 SoC and BRD4170A board, refer to these +documents: + +- `EFR32MG12 Website`_ +- `EFR32MG12 Datasheet`_ +- `EFR32xG12 Reference Manual`_ +- `BRD4161A User Guide`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| SPI(M) | on-chip | spi port-polling | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/slwrb4161a/slwrb4161a_defconfig` + +Connections and IOs +=================== + +In the following table, the column **Pin** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Pin | Function | Usage | ++=======+=============+=====================================+ +| PF4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PF5 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PF6 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PF7 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PA5 | GPIO | Board Controller Enable VCOM_ENABLE | ++-------+-------------+-------------------------------------+ +| PA0 | USART0_TX | UART Console VCOM_TX US0_TX #0 | ++-------+-------------+-------------------------------------+ +| PA1 | USART0_RX | UART Console VCOM_RX US0_RX #0 | ++-------+-------------+-------------------------------------+ +| PC6 | SPI_MOSI | Flash MOSI US1_TX #11 | ++-------+-------------+-------------------------------------+ +| PC7 | SPI_MISO | Flash MISO US1_RX #11 | ++-------+-------------+-------------------------------------+ +| PC8 | SPI_SCLK | Flash SCLK US1_CLK #11 | ++-------+-------------+-------------------------------------+ +| PA4 | SPI_CS | Flash Chip Select (GPIO) | ++-------+-------------+-------------------------------------+ + +System Clock +============ + +The EFR32MG12P SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32MG12P SoC has four USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4161A radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: slwrb4161a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! slwrb4161a + + +.. _EFR32MG12 Website: + https://www.silabs.com/wireless/zigbee/efr32mg12-series-1-socs + +.. _EFR32MG12 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf + +.. _EFR32xG12 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf + +.. _BRD4161A User Guide: + https://www.silabs.com/documents/public/user-guides/ug260-brd4161a-user-guide.pdf diff --git a/boards/silabs/radio_boards/slwrb4161a/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4161a/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.dts b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts similarity index 75% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.dts rename to boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts index 64b9dce560dd8a..90804fbba05640 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.dts +++ b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts @@ -6,14 +6,14 @@ /dts-v1/; #include -#include "efr32_radio.dtsi" +#include "../common/efr32-series1-common.dtsi" / { - model = "Silicon Labs BRD4161A (Mighty Gecko Radio Board)"; - compatible = "silabs,efr32_radio_brd4161a", "silabs,efr32mg12p"; + model = "Silicon Labs BRD4161A (Mighty Gecko 12 Radio Board)"; + compatible = "silabs,slwrb4161a", "silabs,efr32mg12p"; - aliases { - spi-flash0 = &mx25r80; + chosen { + zephyr,bt-hci = &bt_hci_silabs; }; }; @@ -72,6 +72,16 @@ }; }; +&usart2 { + compatible = "silabs,gecko-spi-usart"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart2_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioa 9 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + &i2c0 { pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; @@ -83,3 +93,7 @@ status = "okay"; }; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.yaml b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.yaml similarity index 72% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.yaml rename to boards/silabs/radio_boards/slwrb4161a/slwrb4161a.yaml index ac0779d0d01768..6f46897683e9e7 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.yaml +++ b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32mg12p433f1024gm68 -name: BRD4170A +identifier: slwrb4161a +name: EFR32MG12 2.4 GHz 19 dBm Radio Board (SLWRB4161A) type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48_defconfig b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48_defconfig rename to boards/silabs/radio_boards/slwrb4161a/slwrb4161a_defconfig diff --git a/boards/silabs/radio_boards/slwrb4161a/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4161a/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4161a/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig new file mode 100644 index 00000000000000..1e7b4bee9382b5 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SLWRB4170A + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x0 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default n + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_SLWRB4170A diff --git a/boards/silabs/radio_boards/slwrb4170a/Kconfig.slwrb4170a b/boards/silabs/radio_boards/slwrb4170a/Kconfig.slwrb4170a new file mode 100644 index 00000000000000..6ae34218fc3b78 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/Kconfig.slwrb4170a @@ -0,0 +1,8 @@ +# EFR32MG12 BRD4170A + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4170A + select SOC_PART_NUMBER_EFR32MG12P433F1024GM68 diff --git a/boards/silabs/radio_boards/slwrb4170a/board.cmake b/boards/silabs/radio_boards/slwrb4170a/board.cmake new file mode 100644 index 00000000000000..be43109892de56 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32MG12PxxxF1024") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4170a/board.yml b/boards/silabs/radio_boards/slwrb4170a/board.yml new file mode 100644 index 00000000000000..3137d819edb34e --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4170a + socs: + - name: efr32mg12p433f1024gm68 diff --git a/boards/silabs/efr32_radio/doc/efr32mg12-slwrb4170a.jpg b/boards/silabs/radio_boards/slwrb4170a/doc/efr32mg12-slwrb4170a.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32mg12-slwrb4170a.jpg rename to boards/silabs/radio_boards/slwrb4170a/doc/efr32mg12-slwrb4170a.jpg diff --git a/boards/silabs/radio_boards/slwrb4170a/doc/index.rst b/boards/silabs/radio_boards/slwrb4170a/doc/index.rst new file mode 100644 index 00000000000000..b6a29d13ad1380 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/doc/index.rst @@ -0,0 +1,156 @@ +.. _slwrb4170a: + +EFR32MG12 2400/868-915 MHz 19 dBm Dual Band (SLWRB4170A) +######################################################## + +Overview +******** + +The EFR32MG12 Mighty Gecko Radio Board contains a Wireless System-On-Chip +from the EFR32MG12 family built on an ARM Cortex®-M4F processor with excellent +low power capabilities. + +.. figure:: efr32mg12-slwrb4170a.jpg + :align: center + :alt: SLWRB4170A Mighty Gecko Radio Board + + SLWRB4170A (image courtesy of Silicon Labs) + +The BRD4170A a.k.a. SLWRB4170A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. + +Hardware +******** + +- EFR32MG12P433F1024GM68 Mighty Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 1024 kB +- RAM: 256 kB +- Transmit power: up to +19 dBm +- Operation frequency: 2.4 GHz and Sub-Ghz +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32MG12 SoC and BRD4170A board, refer to these +documents: + +- `EFR32MG12 Website`_ +- `EFR32MG12 Datasheet`_ +- `EFR32xG12 Reference Manual`_ +- `BRD4170A User Guide`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| SPI(M) | on-chip | spi port-polling | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/slwrb4170a/slwrb4170a_defconfig` + +Connections and IOs +=================== + +In the following table, the column **Pin** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Pin | Function | Usage | ++=======+=============+=====================================+ +| PF4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PF5 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PF6 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PF7 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PA5 | GPIO | Board Controller Enable VCOM_ENABLE | ++-------+-------------+-------------------------------------+ +| PA0 | USART0_TX | UART Console VCOM_TX US0_TX #0 | ++-------+-------------+-------------------------------------+ +| PA1 | USART0_RX | UART Console VCOM_RX US0_RX #0 | ++-------+-------------+-------------------------------------+ +| PC6 | SPI_MOSI | Flash MOSI US1_TX #11 | ++-------+-------------+-------------------------------------+ +| PC7 | SPI_MISO | Flash MISO US1_RX #11 | ++-------+-------------+-------------------------------------+ +| PC8 | SPI_SCLK | Flash SCLK US1_CLK #11 | ++-------+-------------+-------------------------------------+ +| PA4 | SPI_CS | Flash Chip Select (GPIO) | ++-------+-------------+-------------------------------------+ + +System Clock +============ + +The EFR32MG12P SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32MG12P SoC has four USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4170A radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: slwrb4170a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! slwrb4170a + + +.. _EFR32MG12 Website: + https://www.silabs.com/wireless/zigbee/efr32mg12-series-1-socs + +.. _EFR32MG12 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32mg12-datasheet.pdf + +.. _EFR32xG12 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf + +.. _BRD4170A User Guide: + https://www.silabs.com/documents/public/user-guides/ug342-brd4170a-user-guide.pdf diff --git a/boards/silabs/radio_boards/slwrb4170a/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4170a/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.dts b/boards/silabs/radio_boards/slwrb4170a/slwrb4170a.dts similarity index 81% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.dts rename to boards/silabs/radio_boards/slwrb4170a/slwrb4170a.dts index effd66a8515b98..f1ec87f183b154 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68.dts +++ b/boards/silabs/radio_boards/slwrb4170a/slwrb4170a.dts @@ -6,14 +6,14 @@ /dts-v1/; #include -#include "efr32_radio.dtsi" +#include "../common/efr32-series1-common.dtsi" / { - model = "Silicon Labs BRD4170A (Mighty Gecko Radio Board)"; - compatible = "silabs,efr32_radio_brd4170a", "silabs,efr32mg12p"; + model = "Silicon Labs BRD4170A (Mighty Gecko 12 Radio Board)"; + compatible = "silabs,slwrb4170a", "silabs,efr32mg12p"; - aliases { - spi-flash0 = &mx25r80; + chosen { + zephyr,bt-hci = &bt_hci_silabs; }; }; @@ -60,3 +60,7 @@ }; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.yaml b/boards/silabs/radio_boards/slwrb4170a/slwrb4170a.yaml similarity index 68% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.yaml rename to boards/silabs/radio_boards/slwrb4170a/slwrb4170a.yaml index 8092040c672959..754d40f8840bac 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125.yaml +++ b/boards/silabs/radio_boards/slwrb4170a/slwrb4170a.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32mg12p432f1024gl125 -name: BRD4161A +identifier: slwrb4170a +name: EFR32MG12 2400/868-915 MHz 19 dBm Dual Band Radio Board (SLWRB4170A) type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125_defconfig b/boards/silabs/radio_boards/slwrb4170a/slwrb4170a_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p432f1024gl125_defconfig rename to boards/silabs/radio_boards/slwrb4170a/slwrb4170a_defconfig diff --git a/boards/silabs/radio_boards/slwrb4170a/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4170a/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4170a/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/efr32_radio/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig similarity index 67% rename from boards/silabs/efr32_radio/Kconfig.defconfig rename to boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig index ce20c2ef360b0d..ada9ac843a6abc 100644 --- a/boards/silabs/efr32_radio/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig @@ -4,10 +4,9 @@ # Copyright (c) 2020 TriaGnoSys GmbH # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFR32_RADIO +if BOARD_SLWRB4180A config CMU_HFXO_FREQ - default 39000000 if BOARD_EFR32_RADIO_EFR32MG24B220F1536IM48 default 38400000 config CMU_LFXO_FREQ @@ -15,7 +14,6 @@ config CMU_LFXO_FREQ config FLASH_BASE_ADDRESS hex - default 0x08000000 if BOARD_EFR32_RADIO_EFR32MG24B220F1536IM48 default 0x0 config LOG_BACKEND_SWO_FREQ_HZ @@ -25,7 +23,6 @@ config LOG_BACKEND_SWO_FREQ_HZ if SOC_GECKO_USE_RAIL config FPU - default n if SOC_FAMILY_SILABS_S1 default y endif # SOC_GECKO_USE_RAIL @@ -42,10 +39,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -choice BT_HCI_BUS_TYPE - default BT_SILABS_HCI -endchoice - endif # BT -endif # BOARD_EFR32_RADIO +endif # BOARD_SLWRB4180A diff --git a/boards/silabs/radio_boards/slwrb4180a/Kconfig.slwrb4180a b/boards/silabs/radio_boards/slwrb4180a/Kconfig.slwrb4180a new file mode 100644 index 00000000000000..2e1e6c0fd3ed75 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4180a/Kconfig.slwrb4180a @@ -0,0 +1,8 @@ +# EFR32MG21 BRD4180A + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4180A + select SOC_PART_NUMBER_EFR32MG21A020F1024IM32 diff --git a/boards/silabs/radio_boards/slwrb4180a/board.cmake b/boards/silabs/radio_boards/slwrb4180a/board.cmake new file mode 100644 index 00000000000000..aa7247647d8cea --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4180a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32MG21AxxxF1024") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4180a/board.yml b/boards/silabs/radio_boards/slwrb4180a/board.yml new file mode 100644 index 00000000000000..c6f825f735a3c0 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4180a/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4180a + socs: + - name: efr32mg21a020f1024im32 diff --git a/boards/silabs/efr32_radio/doc/efr32mg21-slwrb4180a.jpg b/boards/silabs/radio_boards/slwrb4180a/doc/efr32mg21-slwrb4180a.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32mg21-slwrb4180a.jpg rename to boards/silabs/radio_boards/slwrb4180a/doc/efr32mg21-slwrb4180a.jpg diff --git a/boards/silabs/efr32_radio/doc/brd4180a.rst b/boards/silabs/radio_boards/slwrb4180a/doc/index.rst similarity index 92% rename from boards/silabs/efr32_radio/doc/brd4180a.rst rename to boards/silabs/radio_boards/slwrb4180a/doc/index.rst index 4998122bbcdf5f..01864a54b1b3ac 100644 --- a/boards/silabs/efr32_radio/doc/brd4180a.rst +++ b/boards/silabs/radio_boards/slwrb4180a/doc/index.rst @@ -1,7 +1,7 @@ -.. _efr32_radio_brd4180a: +.. _slwrb4180a: -EFR32 BRD4180A (SLWRB4180A) -########################### +EFR32xG21 2.4 GHz 20 dBm (SLWRB4180A) +##################################### Overview ******** @@ -18,7 +18,7 @@ ARM Cortex®-M33F processor with excellent low power capabilities. SLWRB4180A (image courtesy of Silicon Labs) The BRD4180A a.k.a. SLWRB4180A radio board plugs into the Wireless Starter Kit -Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. Hardware ******** @@ -96,7 +96,7 @@ means Pin number 2 on PORTA, as used in the board's datasheets and manuals. +-------+-------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32_defconfig` +:zephyr_file:`boards/silabs/radio_boards/slwrb4180a/slwrb4180a_defconfig` System Clock ============ @@ -113,10 +113,6 @@ USART0 is connected to the board controller and is used for the console. Programming and Debugging ************************* -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - Flashing ======== @@ -127,7 +123,7 @@ Here is an example for the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32_radio/efr32mg21a020f1024im32 + :board: slwrb4180a :goals: flash Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -141,7 +137,7 @@ Reset the board and you should see the following message in the terminal: .. code-block:: console - Hello World! efr32_radio + Hello World! slwrb4180a .. _EFR32-SLWSTK6006A Website: diff --git a/boards/silabs/radio_boards/slwrb4180a/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4180a/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4180a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32-pinctrl.dtsi b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32-pinctrl.dtsi rename to boards/silabs/radio_boards/slwrb4180a/slwrb4180a-pinctrl.dtsi diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.dts b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.dts similarity index 93% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.dts rename to boards/silabs/radio_boards/slwrb4180a/slwrb4180a.dts index 379fd031e22dcf..9d7615047839a4 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.dts +++ b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.dts @@ -7,11 +7,11 @@ /dts-v1/; #include #include -#include "efr32_radio_efr32mg21a020f1024im32-pinctrl.dtsi" +#include "slwrb4180a-pinctrl.dtsi" / { - model = "Silicon Labs BRD4180A (Mighty Gecko Radio Board)"; - compatible = "silabs,efr32mg21_brd4180a", "silabs,efr32mg21"; + model = "Silicon Labs BRD4180A (Mighty Gecko 21 Radio Board)"; + compatible = "silabs,slwrb4180a", "silabs,efr32mg21"; chosen { zephyr,console = &usart0; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.yaml b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml similarity index 73% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.yaml rename to boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml index c6103f5336b572..ae9d5b7f2b85eb 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32.yaml +++ b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32mg21a020f1024im32 -name: BRD4180A +identifier: slwrb4180a +name: EFR32xG21 2.4 GHz 20 dBm Radio Board (SLWRB4180A) type: mcu arch: arm ram: 96 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32_defconfig b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg21a020f1024im32_defconfig rename to boards/silabs/radio_boards/slwrb4180a/slwrb4180a_defconfig diff --git a/boards/silabs/radio_boards/slwrb4180a/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4180a/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4180a/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig new file mode 100644 index 00000000000000..4ddb0000ca66a6 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SLWRB4250B + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x0 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default n + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_SLWRB4250B diff --git a/boards/silabs/radio_boards/slwrb4250b/Kconfig.slwrb4250b b/boards/silabs/radio_boards/slwrb4250b/Kconfig.slwrb4250b new file mode 100644 index 00000000000000..bab71ba23c9d30 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/Kconfig.slwrb4250b @@ -0,0 +1,8 @@ +# EFR32FG1P BRD4250B + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4250B + select SOC_PART_NUMBER_EFR32FG1P133F256GM48 diff --git a/boards/silabs/radio_boards/slwrb4250b/board.cmake b/boards/silabs/radio_boards/slwrb4250b/board.cmake new file mode 100644 index 00000000000000..a17aad7a8955fb --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32FG1PxxxF256") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4250b/board.yml b/boards/silabs/radio_boards/slwrb4250b/board.yml new file mode 100644 index 00000000000000..cffd4c63dbb30d --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4250b + socs: + - name: efr32fg1p133f256gm48 diff --git a/boards/silabs/efr32_radio/doc/efr32fg1-slwrb4250b.jpg b/boards/silabs/radio_boards/slwrb4250b/doc/efr32fg1-slwrb4250b.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32fg1-slwrb4250b.jpg rename to boards/silabs/radio_boards/slwrb4250b/doc/efr32fg1-slwrb4250b.jpg diff --git a/boards/silabs/radio_boards/slwrb4250b/doc/index.rst b/boards/silabs/radio_boards/slwrb4250b/doc/index.rst new file mode 100644 index 00000000000000..59a38cf26f8be5 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/doc/index.rst @@ -0,0 +1,169 @@ +.. _slwrb4250b: + +EFR32FG1 2400/868 MHz 13 dBm Dual Band (SLWRB4250B) +################################################### + +Overview +******** + +The EFR32FG1 Flex Gecko 2.4 GHz and 868 MHz Radio Board is delivered as part of +`SLWSTK6061B Proprietary Wireless Starter Kit`_. It contains a EFR32FG1 Wireless +SoC built on an ARM Cortex®-M4F processor with excellent low power capabilities. + +.. figure:: efr32fg1-slwrb4250b.jpg + :align: center + :alt: SLWRB4250B Flex Gecko 2.4 GHz and 868 MHz Radio Board + + SLWRB4250B (image courtesy of Silicon Labs) + +The BRD4250B a.k.a. SLWRB4250B radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. + +Hardware +******** + +- EFR32FG1P133F256GM48 Flex Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 256 kB +- RAM: 32 kB +- Transmit power: up to +13 dBm +- Operation frequency: 2.4 GHz, 868 MHz +- 8Mbit SPI NOR Flash +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32FG1 SoC and BRD4250B board, refer to these +documents: + +- `EFR32FG1 Website`_ +- `EFR32FG1 Datasheet`_ +- `EFR32xG1 Reference Manual`_ +- `SLWSTK6061B Proprietary Wireless Starter Kit`_ +- `BRD4250B User Guide`_ +- `BRD4250B Reference Manual`_ +- `EFR32FG1-BRD4250B Schematics`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| SPI(M) | on-chip | spi port-polling | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/slwrb4250b/slwrb4250b_defconfig` + +Connections and IOs +=================== + +In the following table, the column **Pin** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Pin | Function | Usage | ++=======+=============+=====================================+ +| PF4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PF5 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PF6 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PF7 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PA5 | GPIO | Board Controller Enable VCOM_ENABLE | ++-------+-------------+-------------------------------------+ +| PA0 | USART0_TX | UART Console VCOM_TX US0_TX #0 | ++-------+-------------+-------------------------------------+ +| PA1 | USART0_RX | UART Console VCOM_RX US0_RX #0 | ++-------+-------------+-------------------------------------+ +| PC6 | SPI_MOSI | Flash MOSI US1_TX #11 | ++-------+-------------+-------------------------------------+ +| PC7 | SPI_MISO | Flash MISO US1_RX #11 | ++-------+-------------+-------------------------------------+ +| PC8 | SPI_SCLK | Flash SCLK US1_CLK #11 | ++-------+-------------+-------------------------------------+ +| PA4 | SPI_CS | Flash Chip Select (GPIO) | ++-------+-------------+-------------------------------------+ + +System Clock +============ + +The EFR32FG1P SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32FG1P SoC has two USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4250B radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: slwrb4250b + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! slwrb4250b + + +.. _EFR32FG1 Website: + https://www.silabs.com/wireless/proprietary/efr32fg1-series-1-sub-ghz-2-4-ghz-socs + +.. _EFR32FG1 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32fg1-datasheet.pdf + +.. _EFR32xG1 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg1-rm.pdf + +.. _SLWSTK6061B Proprietary Wireless Starter Kit: + https://www.silabs.com/products/development-tools/wireless/proprietary/slwstk6061b-efr32-flex-gecko-868-mhz-2-4-ghz-and-sub-ghz-starter-kit + +.. _BRD4250B User Guide: + https://www.silabs.com/documents/public/user-guides/ug182-brd4250b-user-guide.pdf + +.. _BRD4250B Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/brd4250b-rm.pdf + +.. _EFR32FG1-BRD4250B Schematics: + https://www.silabs.com/documents/public/schematic-files/BRD4250B-B02-schematic.pdf diff --git a/boards/silabs/radio_boards/slwrb4250b/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4250b/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.dts b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.dts similarity index 89% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.dts rename to boards/silabs/radio_boards/slwrb4250b/slwrb4250b.dts index 2167b1b69b7864..7ca9e7388cedc5 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.dts +++ b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.dts @@ -7,11 +7,11 @@ /dts-v1/; #include #include -#include "efr32_radio.dtsi" +#include "../common/efr32-series1-common.dtsi" / { - model = "Silicon Labs BRD4250B (Flex Gecko Radio Board)"; - compatible = "silabs,efr32_radio_brd4250b", "silabs,efr32fg1p"; + model = "Silicon Labs BRD4250B (Flex Gecko 1 Radio Board)"; + compatible = "silabs,slwrb4250b", "silabs,efr32fg1p"; pwmleds { compatible = "pwm-leds"; @@ -23,7 +23,6 @@ aliases { pwm-led0 = &pwm_led0; - spi-flash0 = &mx25r80; }; }; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.yaml b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml similarity index 70% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.yaml rename to boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml index 356d959514cafe..8f54bc217527d2 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32fg1p133f256gm48.yaml +++ b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32fg1p133f256gm48 -name: BRD4250B +identifier: slwrb4250b +name: EFR32FG 2400/868 MHz 13 dBm Dual Band Radio Board (SLWRB4250B) type: mcu arch: arm ram: 32 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68_defconfig b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg12p433f1024gm68_defconfig rename to boards/silabs/radio_boards/slwrb4250b/slwrb4250b_defconfig diff --git a/boards/silabs/radio_boards/slwrb4250b/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4250b/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4250b/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig new file mode 100644 index 00000000000000..eda39b9173d91e --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SLWRB4255A + +config CMU_HFXO_FREQ + default 38400000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x0 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default n + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_SLWRB4255A diff --git a/boards/silabs/radio_boards/slwrb4255a/Kconfig.slwrb4255a b/boards/silabs/radio_boards/slwrb4255a/Kconfig.slwrb4255a new file mode 100644 index 00000000000000..6f95623eb75d13 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/Kconfig.slwrb4255a @@ -0,0 +1,8 @@ +# EFR32FG13P BRD4255A board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLWRB4255A + select SOC_PART_NUMBER_EFR32FG13P233F512GM48 diff --git a/boards/silabs/radio_boards/slwrb4255a/board.cmake b/boards/silabs/radio_boards/slwrb4255a/board.cmake new file mode 100644 index 00000000000000..7e93e543d55003 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32FG13PxxxF512") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/slwrb4255a/board.yml b/boards/silabs/radio_boards/slwrb4255a/board.yml new file mode 100644 index 00000000000000..4b76604b1708da --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/board.yml @@ -0,0 +1,4 @@ +boards: + - name: slwrb4255a + socs: + - name: efr32fg13p233f512gm48 diff --git a/boards/silabs/efr32_radio/doc/efr32fg13-slwrb4255a.jpg b/boards/silabs/radio_boards/slwrb4255a/doc/efr32fg13-slwrb4255a.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32fg13-slwrb4255a.jpg rename to boards/silabs/radio_boards/slwrb4255a/doc/efr32fg13-slwrb4255a.jpg diff --git a/boards/silabs/radio_boards/slwrb4255a/doc/index.rst b/boards/silabs/radio_boards/slwrb4255a/doc/index.rst new file mode 100644 index 00000000000000..d7e303c13262c1 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/doc/index.rst @@ -0,0 +1,159 @@ +.. _slwrb4255a: + +EFR32FG13 2400/915 MHz 19 dBm Dual Band (SLWRB4255A) +#################################################### + +Overview +******** + +The EFR32FG13P Flex Gecko 2.4 GHz and 915 MHz Radio Board is delivered as a +`standalone Proprietary Wireless radio board`_. It contains a EFR32FG13P Wireless +SoC built on an ARM Cortex®-M4F processor with excellent low power capabilities. + +.. figure:: efr32fg13-slwrb4255a.jpg + :align: center + :alt: SLWRB4255A Flex Gecko 2.4 GHz and 915 MHz Radio Board + + SLWRB4255A (image courtesy of Silicon Labs) + +The BRD4255A a.k.a. SLWRB4255A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`silabs_radio_boards`. + +Hardware +******** + +- EFR32FG13P233F512GM48 Flex Gecko SoC +- CPU core: ARM Cortex®-M4 with FPU +- Flash memory: 512 kB +- RAM: 64 kB +- Transmit power: up to 19 dBm +- Operation frequency: 2.4 GHz, 915 MHz +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32FG13 SoC and BRD4255A board, refer to these +documents: + +- `EFR32FG13 Website`_ +- `EFR32FG13 Datasheet`_ +- `EFR32xG13 Reference Manual`_ +- `BRD4255A Reference Manual`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| SPI(M) | on-chip | spi port-polling | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/slwrb4255/slwrb4255_defconfig` + +Connections and IOs +=================== + +In the following table, the column **Pin** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Pin | Function | Usage | ++=======+=============+=====================================+ +| PF4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PF5 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PF6 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PF7 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PA5 | GPIO | Board Controller Enable VCOM_ENABLE | ++-------+-------------+-------------------------------------+ +| PA0 | USART0_TX | UART Console VCOM_TX US0_TX #0 | ++-------+-------------+-------------------------------------+ +| PA1 | USART0_RX | UART Console VCOM_RX US0_RX #0 | ++-------+-------------+-------------------------------------+ +| PC6 | SPI_MOSI | Flash MOSI US1_TX #11 | ++-------+-------------+-------------------------------------+ +| PC7 | SPI_MISO | Flash MISO US1_RX #11 | ++-------+-------------+-------------------------------------+ +| PC8 | SPI_SCLK | Flash SCLK US1_CLK #11 | ++-------+-------------+-------------------------------------+ +| PA4 | SPI_CS | Flash Chip Select (GPIO) | ++-------+-------------+-------------------------------------+ + +System Clock +============ + +The EFR32FG13P SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32FG13P SoC has three USARTs and one Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4255A radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: slwrb4255a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! slwrb4255a + + +.. _EFR32FG13 Website: + https://www.silabs.com/wireless/proprietary/efr32fg13-series-1-sub-ghz-2-4-ghz-socs + +.. _EFR32FG13 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32fg13-datasheet.pdf + +.. _EFR32xG13 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdf + +.. _standalone Proprietary Wireless radio board: + https://www.silabs.com/development-tools/wireless/proprietary/slwrb4255a-efr32fg13-915-mhz-radio-board + +.. _BRD4255A Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/brd4255a-rm.pdf diff --git a/boards/silabs/radio_boards/slwrb4255a/pre_dt_board.cmake b/boards/silabs/radio_boards/slwrb4255a/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.dts b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.dts similarity index 92% rename from boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.dts rename to boards/silabs/radio_boards/slwrb4255a/slwrb4255a.dts index cf146428322d25..299a3c85263281 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32fg13p233f512gm48.dts +++ b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.dts @@ -8,11 +8,11 @@ /dts-v1/; #include #include -#include "efr32_radio.dtsi" +#include "../common/efr32-series1-common.dtsi" / { model = "Silicon Labs BRD4255A (Flex Gecko Radio Board)"; - compatible = "silabs,efr32_radio_brd4255a", "silabs,efr32fg13p"; + compatible = "silabs,slwrb4255a", "silabs,efr32fg13p"; }; &cpu0 { diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.yaml b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml similarity index 70% rename from boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.yaml rename to boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml index 8edaadbadf72ba..e1d6718fbce0d9 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32bg13p632f512gm48.yaml +++ b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32bg13p632f512gm48 -name: BRD4104A +identifier: slwrb4255a +name: EFR32FG13 2400/915 MHz 19 dBm Dual Band Radio Board (SLWRB4255A) type: mcu arch: arm ram: 64 diff --git a/boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a_defconfig b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a_defconfig similarity index 100% rename from boards/silabs/efr32mg_sltb004a/efr32mg_sltb004a_defconfig rename to boards/silabs/radio_boards/slwrb4255a/slwrb4255a_defconfig diff --git a/boards/silabs/radio_boards/slwrb4255a/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4255a/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/slwrb4255a/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/efm32gg_slwstk6121a/CMakeLists.txt b/boards/silabs/radio_boards/slwrb4321a/CMakeLists.txt similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/CMakeLists.txt rename to boards/silabs/radio_boards/slwrb4321a/CMakeLists.txt diff --git a/boards/silabs/efm32gg_slwstk6121a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4321a/Kconfig.defconfig similarity index 88% rename from boards/silabs/efm32gg_slwstk6121a/Kconfig.defconfig rename to boards/silabs/radio_boards/slwrb4321a/Kconfig.defconfig index 33e5b1192c0fec..63ff16bbad6342 100644 --- a/boards/silabs/efm32gg_slwstk6121a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4321a/Kconfig.defconfig @@ -4,7 +4,7 @@ # Copyright (c) 2020 Thorvald Natvig # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32GG_SLWSTK6121A +if BOARD_SLWRB4321A config CMU_HFXO_FREQ default 50000000 @@ -26,4 +26,4 @@ config NET_L2_ETHERNET endif # NETWORKING -endif # BOARD_EFM32GG_SLWSTK6121A +endif # BOARD_SLWRB4321A diff --git a/boards/silabs/efm32gg_slwstk6121a/Kconfig.efm32gg_slwstk6121a b/boards/silabs/radio_boards/slwrb4321a/Kconfig.slwrb4321a similarity index 72% rename from boards/silabs/efm32gg_slwstk6121a/Kconfig.efm32gg_slwstk6121a rename to boards/silabs/radio_boards/slwrb4321a/Kconfig.slwrb4321a index 2e064a306f1193..1ce37ed64468f1 100644 --- a/boards/silabs/efm32gg_slwstk6121a/Kconfig.efm32gg_slwstk6121a +++ b/boards/silabs/radio_boards/slwrb4321a/Kconfig.slwrb4321a @@ -1,8 +1,8 @@ -# EFM32GG SLWSTK6121A board configuration +# EFM32GG11 SLWRB4321A board configuration # Copyright (c) 2019 Interay Solutions B.V. # Copyright (c) 2019 Oane Kingma # Copyright (c) 2020 Thorvald Natvig # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFM32GG_SLWSTK6121A +config BOARD_SLWRB4321A select SOC_PART_NUMBER_EFM32GG11B820F2048GM64 diff --git a/boards/silabs/efm32gg_slwstk6121a/board.c b/boards/silabs/radio_boards/slwrb4321a/board.c similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/board.c rename to boards/silabs/radio_boards/slwrb4321a/board.c diff --git a/boards/silabs/efm32gg_slwstk6121a/board.cmake b/boards/silabs/radio_boards/slwrb4321a/board.cmake similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/board.cmake rename to boards/silabs/radio_boards/slwrb4321a/board.cmake diff --git a/boards/silabs/efm32gg_slwstk6121a/board.h b/boards/silabs/radio_boards/slwrb4321a/board.h similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/board.h rename to boards/silabs/radio_boards/slwrb4321a/board.h diff --git a/boards/silabs/efm32gg_slwstk6121a/board.yml b/boards/silabs/radio_boards/slwrb4321a/board.yml similarity index 69% rename from boards/silabs/efm32gg_slwstk6121a/board.yml rename to boards/silabs/radio_boards/slwrb4321a/board.yml index 7f91de02759384..a86f5c2d6209a7 100644 --- a/boards/silabs/efm32gg_slwstk6121a/board.yml +++ b/boards/silabs/radio_boards/slwrb4321a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32gg_slwstk6121a + name: slwrb4321a vendor: silabs socs: - name: efm32gg11b820f2048gm64 diff --git a/boards/silabs/efm32gg_slwstk6121a/doc/index.rst b/boards/silabs/radio_boards/slwrb4321a/doc/index.rst similarity index 95% rename from boards/silabs/efm32gg_slwstk6121a/doc/index.rst rename to boards/silabs/radio_boards/slwrb4321a/doc/index.rst index 47d2a5a93a10f2..1170205e1b8324 100644 --- a/boards/silabs/efm32gg_slwstk6121a/doc/index.rst +++ b/boards/silabs/radio_boards/slwrb4321a/doc/index.rst @@ -1,7 +1,7 @@ -.. _efm32gg_slwstk6121a: +.. _slwrb4321a: -WGM160P Starter Kit -################### +WGM160P Wi-Fi Module (SLWRB4321A) +################################# Overview ******** @@ -42,7 +42,7 @@ For more information about the WGM160P and SLWSTK6121A board: Supported Features ================== -The efm32gg_slwstk6121a board configuration supports the following hardware +The slwrb4321a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ @@ -69,7 +69,7 @@ features: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig` +:zephyr_file:`boards/silabs/slwrb4321a/slwrb4321a_defconfig` Other hardware features, including the WF200 WiFi transceiver, are currently not supported by the port. @@ -141,7 +141,7 @@ Here is an example to build and flash the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32gg_slwstk6121a + :board: slwrb4321a :goals: flash Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -156,7 +156,7 @@ terminal session: .. code-block:: console - Hello World! efm32gg_slwstk6121a + Hello World! slwrb4321a .. _WGM160P Website: https://www.silabs.com/wireless/wi-fi/wfm160-series-1-modules diff --git a/boards/silabs/efm32gg_slwstk6121a/doc/wgm160p-starter-kit.jpg b/boards/silabs/radio_boards/slwrb4321a/doc/wgm160p-starter-kit.jpg similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/doc/wgm160p-starter-kit.jpg rename to boards/silabs/radio_boards/slwrb4321a/doc/wgm160p-starter-kit.jpg diff --git a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a-pinctrl.dtsi rename to boards/silabs/radio_boards/slwrb4321a/slwrb4321a-pinctrl.dtsi diff --git a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts similarity index 96% rename from boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts rename to boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts index a82fa896722670..4dfff28a2dc82c 100644 --- a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts +++ b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts @@ -9,11 +9,11 @@ /dts-v1/; #include #include -#include "efm32gg_slwstk6121a-pinctrl.dtsi" +#include "slwrb4321a-pinctrl.dtsi" / { model = "Silicon Labs EFM32GG SLWSTK6121A board"; - compatible = "silabs,efm32gg_slwstk6121a", "silabs,efm32gg11b"; + compatible = "silabs,slwrb4321a", "silabs,efm32gg11b"; chosen { zephyr,console = &usart0; diff --git a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml similarity index 74% rename from boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml rename to boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml index 9e976e5ccaaba3..7b61761886f4c7 100644 --- a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml +++ b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml @@ -1,5 +1,5 @@ -identifier: efm32gg_slwstk6121a -name: EFM32GG-SLWSTK6121A +identifier: slwrb4321a +name: WGM160P Wi-Fi Module Radio Board (SLWRB4321A) type: mcu arch: arm ram: 512 diff --git a/boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a_defconfig similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig rename to boards/silabs/radio_boards/slwrb4321a/slwrb4321a_defconfig diff --git a/boards/silabs/efm32gg_slwstk6121a/support/openocd.cfg b/boards/silabs/radio_boards/slwrb4321a/support/openocd.cfg similarity index 100% rename from boards/silabs/efm32gg_slwstk6121a/support/openocd.cfg rename to boards/silabs/radio_boards/slwrb4321a/support/openocd.cfg diff --git a/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig new file mode 100644 index 00000000000000..92521052f37921 --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig @@ -0,0 +1,44 @@ +# EFR32 radio board + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XG24_RB4187C + +config CMU_HFXO_FREQ + default 39000000 + +config CMU_LFXO_FREQ + default 32768 + +config FLASH_BASE_ADDRESS + hex + default 0x08000000 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config MINIMAL_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_XG24_RB4187C diff --git a/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.xg24_rb4187c b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.xg24_rb4187c new file mode 100644 index 00000000000000..7d51709ba49b2b --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.xg24_rb4187c @@ -0,0 +1,8 @@ +# EFR32MG24 BRD4187C + +# Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_XG24_RB4187C + select SOC_PART_NUMBER_EFR32MG24B220F1536IM48 diff --git a/boards/silabs/radio_boards/xg24_rb4187c/board.cmake b/boards/silabs/radio_boards/xg24_rb4187c/board.cmake new file mode 100644 index 00000000000000..a6187e28f0f63f --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd) +board_runner_args(jlink "--device=EFR32MG24BxxxF1536") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/xg24_rb4187c/board.yml b/boards/silabs/radio_boards/xg24_rb4187c/board.yml new file mode 100644 index 00000000000000..09a4d0743700da --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/board.yml @@ -0,0 +1,4 @@ +boards: + - name: xg24_rb4187c + socs: + - name: efr32mg24b220f1536im48 diff --git a/boards/silabs/efr32_radio/doc/efr32mg24-xg24-rb4187c.jpg b/boards/silabs/radio_boards/xg24_rb4187c/doc/efr32mg24-xg24-rb4187c.jpg similarity index 100% rename from boards/silabs/efr32_radio/doc/efr32mg24-xg24-rb4187c.jpg rename to boards/silabs/radio_boards/xg24_rb4187c/doc/efr32mg24-xg24-rb4187c.jpg diff --git a/boards/silabs/efr32_radio/doc/brd4187c.rst b/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst similarity index 92% rename from boards/silabs/efr32_radio/doc/brd4187c.rst rename to boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst index f5a3cd808ddd0f..5100a4bf045cb0 100644 --- a/boards/silabs/efr32_radio/doc/brd4187c.rst +++ b/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst @@ -1,7 +1,7 @@ -.. _efr32_radio_brd4187c: +.. _xg24_rb4187c: -EFR32 BRD4187C (xG24-RB4187C) -############################# +EFR32xG24 2.4 GHz 20 dBm (xG24-RB4187C) +####################################### Overview ******** @@ -18,7 +18,7 @@ ARM Cortex®-M33F processor with excellent low power capabilities. xG24-RB4187C (image courtesy of Silicon Labs) The BRD4187C a.k.a. xG24-RB4187C radio board plugs into the Wireless Pro Kit -Mainboard BRD4002A and is supported as one of :ref:`efr32_radio`. +Mainboard BRD4002A and is supported as one of :ref:`silabs_radio_boards`. Hardware ******** @@ -97,7 +97,7 @@ means Pin number 2 on PORTA, as used in the board's datasheets and manuals. +-------+-------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48_defconfig` +:zephyr_file:`boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c_defconfig` System Clock ============ @@ -114,10 +114,6 @@ USART0 is connected to the board controller and is used for the console. Programming and Debugging ************************* -Please refer to -:ref:`Programming and Debugging EFR32 Radio Board ` -for details on the supported debug interfaces. - Flashing ======== @@ -128,7 +124,7 @@ Here is an example for the :ref:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efr32_radio/efr32mg24b220f1536im48 + :board: xg24_rb4187c :goals: flash Open a serial terminal (minicom, putty, etc.) with the following settings: @@ -142,7 +138,7 @@ Reset the board and you should see the following message in the terminal: .. code-block:: console - Hello World! efr32_radio + Hello World! xg24_rb4187c .. _xG24-PK6010A Website: diff --git a/boards/silabs/radio_boards/xg24_rb4187c/pre_dt_board.cmake b/boards/silabs/radio_boards/xg24_rb4187c/pre_dt_board.cmake new file mode 100644 index 00000000000000..beb76b85552d14 --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/radio_boards/xg24_rb4187c/support/openocd.cfg b/boards/silabs/radio_boards/xg24_rb4187c/support/openocd.cfg new file mode 100644 index 00000000000000..38409eb70ad795 --- /dev/null +++ b/boards/silabs/radio_boards/xg24_rb4187c/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48-pinctrl.dtsi b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c-pinctrl.dtsi similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48-pinctrl.dtsi rename to boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c-pinctrl.dtsi diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.dts b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.dts similarity index 91% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.dts rename to boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.dts index 0fb0b4becc3a0f..21a487e758fd55 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.dts +++ b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.dts @@ -7,11 +7,11 @@ /dts-v1/; #include #include -#include "efr32_radio_efr32mg24b220f1536im48-pinctrl.dtsi" +#include "xg24_rb4187c-pinctrl.dtsi" / { - model = "Silicon Labs BRD4187C (Mighty Gecko Radio Board)"; - compatible = "silabs,efr32mg24_brd4187c", "silabs,efr32mg24"; + model = "Silicon Labs BRD4187C (Mighty Gecko 24 Radio Board)"; + compatible = "silabs,xg24_rb4187c", "silabs,efr32mg24"; chosen { zephyr,console = &usart0; @@ -19,6 +19,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; }; /* These aliases are provided for compatibility with samples */ @@ -154,3 +155,7 @@ }; }; }; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.yaml b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml similarity index 72% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.yaml rename to boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml index 278f40a4866f67..4fbaf3b6d0af59 100644 --- a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48.yaml +++ b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml @@ -1,5 +1,5 @@ -identifier: efr32_radio/efr32mg24b220f1536im48 -name: BRD4187C +identifier: xg24_rb4187c +name: EFR32xG24 2.4 GHz 20 dBm Radio Board (xG24-RB4187C) type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48_defconfig b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c_defconfig similarity index 100% rename from boards/silabs/efr32_radio/efr32_radio_efr32mg24b220f1536im48_defconfig rename to boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c_defconfig diff --git a/boards/silabs/efm32wg_stk3800/Kconfig.defconfig b/boards/silabs/starter_kits/efm32wg_stk3800/Kconfig.defconfig similarity index 100% rename from boards/silabs/efm32wg_stk3800/Kconfig.defconfig rename to boards/silabs/starter_kits/efm32wg_stk3800/Kconfig.defconfig diff --git a/boards/silabs/efm32wg_stk3800/Kconfig.efm32wg_stk3800 b/boards/silabs/starter_kits/efm32wg_stk3800/Kconfig.efm32wg_stk3800 similarity index 100% rename from boards/silabs/efm32wg_stk3800/Kconfig.efm32wg_stk3800 rename to boards/silabs/starter_kits/efm32wg_stk3800/Kconfig.efm32wg_stk3800 diff --git a/boards/silabs/efm32wg_stk3800/board.cmake b/boards/silabs/starter_kits/efm32wg_stk3800/board.cmake similarity index 100% rename from boards/silabs/efm32wg_stk3800/board.cmake rename to boards/silabs/starter_kits/efm32wg_stk3800/board.cmake diff --git a/boards/silabs/efm32wg_stk3800/board.yml b/boards/silabs/starter_kits/efm32wg_stk3800/board.yml similarity index 100% rename from boards/silabs/efm32wg_stk3800/board.yml rename to boards/silabs/starter_kits/efm32wg_stk3800/board.yml diff --git a/boards/silabs/efm32wg_stk3800/doc/efm32wg_stk3800.jpg b/boards/silabs/starter_kits/efm32wg_stk3800/doc/efm32wg_stk3800.jpg similarity index 100% rename from boards/silabs/efm32wg_stk3800/doc/efm32wg_stk3800.jpg rename to boards/silabs/starter_kits/efm32wg_stk3800/doc/efm32wg_stk3800.jpg diff --git a/boards/silabs/efm32wg_stk3800/doc/index.rst b/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst similarity index 96% rename from boards/silabs/efm32wg_stk3800/doc/index.rst rename to boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst index 30810f0d71ec5d..139d89379b07e4 100644 --- a/boards/silabs/efm32wg_stk3800/doc/index.rst +++ b/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst @@ -1,7 +1,7 @@ .. _efm32wg_stk3800: -EFM32WG-STK3800 -############### +EFM32 Wonder Gecko (EFM32WG-STK3800) +#################################### Overview ******** @@ -60,7 +60,7 @@ The efm32wg_stk3800 board configuration supports the following hardware features +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32wg_stk3800/efm32wg_stk3800_defconfig` +:zephyr_file:`boards/silabs/starter_kit/efm32wg_stk3800/efm32wg_stk3800_defconfig` Other hardware features are currently not supported by the port. @@ -149,7 +149,7 @@ the following message: .. code-block:: console - Hello World! arm + Hello World! efm32wg_stk3800 .. _EFM32WG-STK3800 Website: diff --git a/boards/silabs/efm32wg_stk3800/efm32wg_stk3800.dts b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.dts similarity index 100% rename from boards/silabs/efm32wg_stk3800/efm32wg_stk3800.dts rename to boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.dts diff --git a/boards/silabs/efm32wg_stk3800/efm32wg_stk3800.yaml b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml similarity index 79% rename from boards/silabs/efm32wg_stk3800/efm32wg_stk3800.yaml rename to boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml index acd28a6623d34d..35dbe24db1fe43 100644 --- a/boards/silabs/efm32wg_stk3800/efm32wg_stk3800.yaml +++ b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml @@ -1,5 +1,5 @@ identifier: efm32wg_stk3800 -name: EFM32WG-STK3800 +name: EFM32 Wonder Gecko Starter Kit (EFM32WG-STK3800) type: mcu arch: arm ram: 32 diff --git a/boards/silabs/efm32wg_stk3800/efm32wg_stk3800_defconfig b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800_defconfig similarity index 100% rename from boards/silabs/efm32wg_stk3800/efm32wg_stk3800_defconfig rename to boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800_defconfig diff --git a/boards/silabs/starter_kits/index.rst b/boards/silabs/starter_kits/index.rst new file mode 100644 index 00000000000000..06d6c58f988465 --- /dev/null +++ b/boards/silabs/starter_kits/index.rst @@ -0,0 +1,10 @@ +.. _starter_kits: + +Starter Kits +############ + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/silabs/efm32hg_slstk3400a/Kconfig.defconfig b/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig similarity index 75% rename from boards/silabs/efm32hg_slstk3400a/Kconfig.defconfig rename to boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig index c15834e72295a9..78d39acd21af4a 100644 --- a/boards/silabs/efm32hg_slstk3400a/Kconfig.defconfig +++ b/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2018, Marcio Montenegro # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32HG_SLSTK3400A +if BOARD_SLSTK3400A config CMU_HFXO_FREQ default 24000000 @@ -11,4 +11,4 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -endif # BOARD_EFM32HG_SLSTK3400A +endif # BOARD_SLSTK3400A diff --git a/boards/silabs/efm32hg_slstk3400a/Kconfig.efm32hg_slstk3400a b/boards/silabs/starter_kits/slstk3400a/Kconfig.slstk3400a similarity index 81% rename from boards/silabs/efm32hg_slstk3400a/Kconfig.efm32hg_slstk3400a rename to boards/silabs/starter_kits/slstk3400a/Kconfig.slstk3400a index 3ab1289920f456..bdbf1d82750563 100644 --- a/boards/silabs/efm32hg_slstk3400a/Kconfig.efm32hg_slstk3400a +++ b/boards/silabs/starter_kits/slstk3400a/Kconfig.slstk3400a @@ -3,5 +3,5 @@ # Copyright (c) 2018, Marcio Montenegro # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFM32HG_SLSTK3400A +config BOARD_SLSTK3400A select SOC_PART_NUMBER_EFM32HG322F64 diff --git a/boards/silabs/efm32hg_slstk3400a/board.yml b/boards/silabs/starter_kits/slstk3400a/board.yml similarity index 67% rename from boards/silabs/efm32hg_slstk3400a/board.yml rename to boards/silabs/starter_kits/slstk3400a/board.yml index 8aae393fcae68b..e6573ac89f5d34 100644 --- a/boards/silabs/efm32hg_slstk3400a/board.yml +++ b/boards/silabs/starter_kits/slstk3400a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32hg_slstk3400a + name: slstk3400a vendor: silabs socs: - name: efm32hg322f64 diff --git a/boards/silabs/efm32hg_slstk3400a/doc/index.rst b/boards/silabs/starter_kits/slstk3400a/doc/index.rst similarity index 86% rename from boards/silabs/efm32hg_slstk3400a/doc/index.rst rename to boards/silabs/starter_kits/slstk3400a/doc/index.rst index a1e0b84f16d9c5..a48cc3f65faa76 100644 --- a/boards/silabs/efm32hg_slstk3400a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3400a/doc/index.rst @@ -1,20 +1,20 @@ -.. _efm32hg_slstk3400a: +.. _slstk3400a: -EFM32HG-SLSTK3400A -################## +EFM32 Happy Gecko (SLSTK3400A) +############################## Overview ******** -The EFM32 Happy Gecko Starter Kit EFM32HG-SLSTK3400A contains a MCU from the +The EFM32 Happy Gecko Starter Kit SLSTK3400A contains a MCU from the EFM32HG family built on ARM® Cortex®-M0+ processor with excellent low power capabilities. -.. figure:: efm32hg_slstk3400a.jpg +.. figure:: slstk3400a.jpg :align: center - :alt: EFM32HG-SLSTK3400A + :alt: SLSTK3400A - EFM32HG-SLSTK3400A (image courtesy of Silicon Labs) + SLSTK3400A (image courtesy of Silicon Labs) Hardware ******** @@ -35,9 +35,9 @@ See these documents for more information - `EFM32HG Website`_ - `EFM32HG Datasheet`_ - `EFM32HG Reference Manual`_ -- `EFM32HG-SLSTK3400A Website`_ -- `EFM32HG-SLSTK3400A User Guide`_ -- `EFM32HG-SLSTK3400A Schematics`_ +- `SLSTK3400A Website`_ +- `SLSTK3400A User Guide`_ +- `SLSTK3400A Schematics`_ Supported Features ================== @@ -60,7 +60,7 @@ The efm32hg_slstk3400 board configuration supports the following hardware featur +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a_defconfig` +:zephyr_file:`boards/silabs/starter_kit/slstk3400a/slstk3400a_defconfig` Other hardware features are currently not supported by the port. @@ -68,7 +68,7 @@ Connections and IOs =================== The EFM32HG SoC has six GPIO controllers (PORTA to PORTF), but only three are -currently enabled (PORTB, PORTE and PORTF) for the EFM32HG-SLSTK3400A board. +currently enabled (PORTB, PORTE and PORTF) for the SLSTK3400A board. In the following table, the column Name contains Pin names. For example, PF4 means Pin number 4 on PORTF, as used in the board's datasheets and manuals. @@ -114,7 +114,7 @@ Programming and Debugging Flashing ======== -The EFM32HG-SLSTK3400 includes an `J-Link`_ serial and debug adaptor built into the +The SLSTK3400 includes an `J-Link`_ serial and debug adaptor built into the board. The adaptor provides: - A USB connection to the host computer, which exposes a Mass Storage and a @@ -130,10 +130,10 @@ Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32hg_slstk3400a + :board: slstk3400a :goals: build -Connect the EFM32HG-SLSTK3400A to your host computer using the USB port and +Connect the SLSTK3400A to your host computer using the USB port and you should see a USB connection that exposes a mass storage device (STK3400) and a USB Serial Port. Copy the generated ``zephyr.bin`` in the STK3400 drive. @@ -148,16 +148,16 @@ Reset the board and you will see this message written to the serial port: .. code-block:: console - Hello World! arm + Hello World! slstk3400a -.. _EFM32HG-SLSTK3400A Website: +.. _SLSTK3400A Website: https://www.silabs.com/products/development-tools/mcu/32-bit/efm32-happy-gecko-starter-kit -.. _EFM32HG-SLSTK3400A User Guide: +.. _SLSTK3400A User Guide: https://www.silabs.com/documents/public/user-guides/ug255-stk3400-user-guide.pdf -.. _EFM32HG-SLSTK3400A Schematics: +.. _SLSTK3400A Schematics: https://www.silabs.com/documents/public/schematic-files/BRD2012A-B01-schematic.pdf .. _EFM32HG Website: diff --git a/boards/silabs/efm32hg_slstk3400a/doc/efm32hg_slstk3400a.jpg b/boards/silabs/starter_kits/slstk3400a/doc/slstk3400a.jpg similarity index 100% rename from boards/silabs/efm32hg_slstk3400a/doc/efm32hg_slstk3400a.jpg rename to boards/silabs/starter_kits/slstk3400a/doc/slstk3400a.jpg diff --git a/boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.dts b/boards/silabs/starter_kits/slstk3400a/slstk3400a.dts similarity index 96% rename from boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.dts rename to boards/silabs/starter_kits/slstk3400a/slstk3400a.dts index 01c1f4d7766abe..d7baf87f753c8d 100644 --- a/boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.dts +++ b/boards/silabs/starter_kits/slstk3400a/slstk3400a.dts @@ -10,7 +10,7 @@ / { model = "Silicon Labs EFM32HG SLSTK3400A board"; - compatible = "silabs,efm32hg_slstk3400a", "silabs,efm32hg"; + compatible = "silabs,slstk3400a", "silabs,efm32hg"; chosen { zephyr,console = &usart1; diff --git a/boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml b/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml similarity index 71% rename from boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml rename to boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml index d14ffbbd10ad1b..0739c38d858759 100644 --- a/boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a.yaml +++ b/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml @@ -1,5 +1,5 @@ -identifier: efm32hg_slstk3400a -name: EFM32HG-SLSTK3400A +identifier: slstk3400a +name: EFM32 Happy Gecko Starter Kit (SLSTK3400A) type: mcu arch: arm ram: 8 diff --git a/boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a_defconfig b/boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig similarity index 100% rename from boards/silabs/efm32hg_slstk3400a/efm32hg_slstk3400a_defconfig rename to boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig diff --git a/boards/silabs/efm32pg_stk3401a/Kconfig.defconfig b/boards/silabs/starter_kits/slstk3401a/Kconfig.defconfig similarity index 68% rename from boards/silabs/efm32pg_stk3401a/Kconfig.defconfig rename to boards/silabs/starter_kits/slstk3401a/Kconfig.defconfig index 9853bf434cca96..992f7da89d4fb1 100644 --- a/boards/silabs/efm32pg_stk3401a/Kconfig.defconfig +++ b/boards/silabs/starter_kits/slstk3401a/Kconfig.defconfig @@ -1,9 +1,9 @@ -# EFM32PG STK3401A board +# EFM32PG SLSTK3401A board # Copyright (c) 2020, Rafael Dias Menezes # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32PG_STK3401A +if BOARD_SLSTK3401A config CMU_HFXO_FREQ default 40000000 @@ -11,4 +11,4 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -endif # BOARD_EFM32PG_STK3401A +endif # BOARD_SLSTK3401A diff --git a/boards/silabs/efm32pg_stk3401a/Kconfig.efm32pg_stk3401a b/boards/silabs/starter_kits/slstk3401a/Kconfig.slstk3401a similarity index 72% rename from boards/silabs/efm32pg_stk3401a/Kconfig.efm32pg_stk3401a rename to boards/silabs/starter_kits/slstk3401a/Kconfig.slstk3401a index 42de02a430abaa..ef6df9553d6add 100644 --- a/boards/silabs/efm32pg_stk3401a/Kconfig.efm32pg_stk3401a +++ b/boards/silabs/starter_kits/slstk3401a/Kconfig.slstk3401a @@ -1,7 +1,7 @@ -# EFM32PG STK3401A board +# EFM32PG SLSTK3401A board # Copyright (c) 2020, Rafael Dias Menezes # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFM32PG_STK3401A +config BOARD_SLSTK3401A select SOC_PART_NUMBER_EFM32PG1B200F256GM48 diff --git a/boards/silabs/efm32pg_stk3401a/board.cmake b/boards/silabs/starter_kits/slstk3401a/board.cmake similarity index 100% rename from boards/silabs/efm32pg_stk3401a/board.cmake rename to boards/silabs/starter_kits/slstk3401a/board.cmake diff --git a/boards/silabs/efm32pg_stk3401a/board.yml b/boards/silabs/starter_kits/slstk3401a/board.yml similarity index 71% rename from boards/silabs/efm32pg_stk3401a/board.yml rename to boards/silabs/starter_kits/slstk3401a/board.yml index 636c7e8c5621e7..98ae08c1992160 100644 --- a/boards/silabs/efm32pg_stk3401a/board.yml +++ b/boards/silabs/starter_kits/slstk3401a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32pg_stk3401a + name: slstk3401a vendor: silabs socs: - name: efm32pg1b200f256gm48 diff --git a/boards/silabs/efm32pg_stk3401a/doc/index.rst b/boards/silabs/starter_kits/slstk3401a/doc/index.rst similarity index 86% rename from boards/silabs/efm32pg_stk3401a/doc/index.rst rename to boards/silabs/starter_kits/slstk3401a/doc/index.rst index a38930275a2651..2de4948e2175e4 100644 --- a/boards/silabs/efm32pg_stk3401a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3401a/doc/index.rst @@ -1,16 +1,16 @@ -.. _efm32pg_stk3401a: +.. _slstk3401a: -EFM32 Pearl Gecko Starter Kit -############################# +EFM32 Pearl Gecko (SLSTK3401A) +############################## Overview ******** -The EFM32 Pearl Gecko Starter Kit EFM32PG-STK3401A contains an MCU from the +The EFM32 Pearl Gecko Starter Kit SLSTK3401A contains an MCU from the EFM32PG family built on an ARM® Cortex®-M4F processor with excellent low power capabilities. -.. figure:: efm32pg_stk3401a.jpg +.. figure:: slstk3401a.jpg :align: center :alt: EFM32PG-SLSTK3401A @@ -26,18 +26,18 @@ Hardware - Humidity and temperature sensor - On-board Segger J-Link USB debugger -For more information about the EFM32PG SoC and EFM32PG-STK3401A board: +For more information about the EFM32PG SoC and SLSTK3401A board: - `EFM32PG Website`_ - `EFM32PG1 Datasheet`_ - `EFM32PG1 Reference Manual`_ -- `EFM32PG-STK3401A Website`_ -- `EFM32PG-STK3401A User Guide`_ +- `SLSTK3401A Website`_ +- `SLSTK3401A User Guide`_ Supported Features ================== -The efm32pg_stk3401a board configuration supports the following hardware features: +The slstk3401a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | @@ -63,7 +63,7 @@ The efm32pg_stk3401a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_defconfig` +:zephyr_file:`boards/silabs/starter_kits/slstk3401a/slstk3401a_defconfig` Other hardware features are currently not supported by the port. @@ -71,7 +71,7 @@ Connections and IOs =================== The EFM32PG1 SoC has five GPIO controllers (PORTA to PORTD and PORTF) and -all are enabled for the EFM32PG-STK3401A board. +all are enabled for the SLSTK3401A board. In the following table, the column **Name** contains pin names. For example, PF4 means pin number 4 on PORTF, as used in the board's datasheets and manuals. @@ -125,7 +125,7 @@ Programming and Debugging Flashing ======== -The EFM32PG-STK3401A includes an `J-Link`_ serial and debug adaptor built into the +The SLSTK3401A includes an `J-Link`_ serial and debug adaptor built into the board. The adaptor provides: - A USB connection to the host computer, which exposes a mass storage device and a @@ -133,20 +133,20 @@ board. The adaptor provides: - A serial flash device, which implements the USB flash disk file storage. - A physical UART connection which is relayed over interface USB serial port. -Flashing an application to EFM32PG-STK3401A -------------------------------------------- +Flashing an application to SLSTK3401A +------------------------------------- The sample application :ref:`hello_world` is used for this example. Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32pg_stk3401a + :board: slstk3401a :goals: build -Connect the EFM32PG-STK3401A to your host computer using the USB port and you -should see a USB connection which exposes a mass storage device(STK3401A). -Copy the generated zephyr.bin to the STK3401A drive. +Connect the SLSTK3401A to your host computer using the USB port and you +should see a USB connection which exposes a mass storage device(SLSTK3401A). +Copy the generated zephyr.bin to the SLSTK3401A drive. Use a USB-to-UART converter such as an FT232/CP2102 to connect to the UART on the expansion header. @@ -163,13 +163,13 @@ terminal session: .. code-block:: console - Hello World! arm + Hello World! slstk3401a -.. _EFM32PG-STK3401A Website: +.. _SLSTK3401A Website: https://www.silabs.com/development-tools/mcu/32-bit/efm32pg1-starter-kit -.. _EFM32PG-STK3401A User Guide: +.. _SLSTK3401A User Guide: https://www.silabs.com/documents/public/user-guides/ug154-stk3401-user-guide.pdf .. _EFM32PG Website: diff --git a/boards/silabs/efm32pg_stk3401a/doc/efm32pg_stk3401a.jpg b/boards/silabs/starter_kits/slstk3401a/doc/slstk3401a.jpg similarity index 100% rename from boards/silabs/efm32pg_stk3401a/doc/efm32pg_stk3401a.jpg rename to boards/silabs/starter_kits/slstk3401a/doc/slstk3401a.jpg diff --git a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_common.dtsi b/boards/silabs/starter_kits/slstk3401a/slstk3401a-common.dtsi similarity index 95% rename from boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_common.dtsi rename to boards/silabs/starter_kits/slstk3401a/slstk3401a-common.dtsi index 97427b8581729f..9b1b8195a105f5 100644 --- a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_common.dtsi +++ b/boards/silabs/starter_kits/slstk3401a/slstk3401a-common.dtsi @@ -5,10 +5,10 @@ */ #include -#include "efm32pg_stk3401a-pinctrl.dtsi" +#include "slstk3401a-pinctrl.dtsi" / { - model = "Silicon Labs EFM32PG STK3401A board"; + model = "Silicon Labs EFM32PG SLSTK3401A board"; chosen { zephyr,console = &usart0; diff --git a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a-pinctrl.dtsi b/boards/silabs/starter_kits/slstk3401a/slstk3401a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a-pinctrl.dtsi rename to boards/silabs/starter_kits/slstk3401a/slstk3401a-pinctrl.dtsi diff --git a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.dts b/boards/silabs/starter_kits/slstk3401a/slstk3401a.dts similarity index 54% rename from boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.dts rename to boards/silabs/starter_kits/slstk3401a/slstk3401a.dts index 1a7f9eddec4ea6..b2afe5d40cf8ad 100644 --- a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.dts +++ b/boards/silabs/starter_kits/slstk3401a/slstk3401a.dts @@ -6,9 +6,9 @@ /dts-v1/; #include -#include "efm32pg_stk3401a_common.dtsi" +#include "slstk3401a-common.dtsi" / { - model = "Silicon Labs EFM32PG STK3401A board"; - compatible = "silabs,efm32pg_stk3401a", "silabs,efm32pg1b"; + model = "Silicon Labs EFM32PG SLSTK3401A board"; + compatible = "silabs,slstk3401a", "silabs,efm32pg1b"; }; diff --git a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.yaml b/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml similarity index 73% rename from boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.yaml rename to boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml index ee707a08caaf52..c2eab5f1756f53 100644 --- a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a.yaml +++ b/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml @@ -1,5 +1,5 @@ -identifier: efm32pg_stk3401a -name: EFM32PG-STK3401A +identifier: slstk3401a +name: EFM32 Pearl Gecko Starter Kit (SLSTK3401A) type: mcu arch: arm ram: 32 diff --git a/boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_defconfig b/boards/silabs/starter_kits/slstk3401a/slstk3401a_defconfig similarity index 100% rename from boards/silabs/efm32pg_stk3401a/efm32pg_stk3401a_defconfig rename to boards/silabs/starter_kits/slstk3401a/slstk3401a_defconfig diff --git a/boards/silabs/efm32pg_stk3402a/Kconfig.defconfig b/boards/silabs/starter_kits/slstk3402a/Kconfig.defconfig similarity index 70% rename from boards/silabs/efm32pg_stk3402a/Kconfig.defconfig rename to boards/silabs/starter_kits/slstk3402a/Kconfig.defconfig index 3d9a498ecd5984..87181e6b602ad0 100644 --- a/boards/silabs/efm32pg_stk3402a/Kconfig.defconfig +++ b/boards/silabs/starter_kits/slstk3402a/Kconfig.defconfig @@ -1,10 +1,10 @@ -# EFM32PG STK3402A board +# EFM32PG12 SLSTK3402A board # Copyright (c) 2018, Christian Taedcke # Copyright (c) 2019 Lemonbeat GmbH # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32PG_STK3402A +if BOARD_SLSTK3402A config CMU_HFXO_FREQ default 40000000 @@ -12,4 +12,4 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -endif # BOARD_EFM32PG_STK3402A +endif # BOARD_SLSTK3402A diff --git a/boards/silabs/starter_kits/slstk3402a/Kconfig.slstk3402a b/boards/silabs/starter_kits/slstk3402a/Kconfig.slstk3402a new file mode 100644 index 00000000000000..e4d6444823bc50 --- /dev/null +++ b/boards/silabs/starter_kits/slstk3402a/Kconfig.slstk3402a @@ -0,0 +1,9 @@ +# EFM32PG12 SLSTK3402A board + +# Copyright (c) 2018, Christian Taedcke +# Copyright (c) 2019 Lemonbeat GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SLSTK3402A + select SOC_PART_NUMBER_EFM32PG12B500F1024GL125 if BOARD_SLSTK3402A_EFM32PG12B500F1024GL125 + select SOC_PART_NUMBER_EFM32JG12B500F1024GL125 if BOARD_SLSTK3402A_EFM32JG12B500F1024GL125 diff --git a/boards/silabs/efm32pg_stk3402a/board.cmake b/boards/silabs/starter_kits/slstk3402a/board.cmake similarity index 100% rename from boards/silabs/efm32pg_stk3402a/board.cmake rename to boards/silabs/starter_kits/slstk3402a/board.cmake diff --git a/boards/silabs/efm32pg_stk3402a/board.yml b/boards/silabs/starter_kits/slstk3402a/board.yml similarity index 80% rename from boards/silabs/efm32pg_stk3402a/board.yml rename to boards/silabs/starter_kits/slstk3402a/board.yml index 068aa663798de3..539af134c6d8b0 100644 --- a/boards/silabs/efm32pg_stk3402a/board.yml +++ b/boards/silabs/starter_kits/slstk3402a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32pg_stk3402a + name: slstk3402a vendor: silabs socs: - name: efm32pg12b500f1024gl125 diff --git a/boards/silabs/efm32pg_stk3402a/doc/index.rst b/boards/silabs/starter_kits/slstk3402a/doc/index.rst similarity index 79% rename from boards/silabs/efm32pg_stk3402a/doc/index.rst rename to boards/silabs/starter_kits/slstk3402a/doc/index.rst index 8014f310b0c2a1..8d6193e85cdc7d 100644 --- a/boards/silabs/efm32pg_stk3402a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3402a/doc/index.rst @@ -1,20 +1,20 @@ -.. _efm32pg_stk3402a: +.. _slstk3402a: -EFM32 Pearl Gecko Starter Kit -############################# +EFM32 Pearl Gecko 12 (SLSTK3402A) +################################# Overview ******** -The EFM32 Pearl Gecko Starter Kit EFM32PG-STK3402A contains an MCU from the +The EFM32 Pearl Gecko 12 Starter Kit SLSTK3402A contains an MCU from the EFM32PG family built on an ARM® Cortex®-M4F processor with excellent low power capabilities. -.. figure:: efm32pg_stk3402a.jpg +.. figure:: slstk3402a.jpg :align: center - :alt: EFM32PG-SLSTK3402A + :alt: SLSTK3402A - EFM32PG-SLSTK3402A (image courtesy of Silicon Labs) + EFM32PG12 SLSTK3402A (image courtesy of Silicon Labs) Hardware ******** @@ -26,19 +26,19 @@ Hardware - Humidity, temperature, and inductive-capacitive metal sensor - On-board Segger J-Link USB debugger -For more information about the EFM32PG SoC and EFM32PG-STK3402A board: +For more information about the EFM32PG SoC and SLSTK3402A board: - `EFM32PG Website`_ - `EFM32PG12 Datasheet`_ - `EFM32PG12 Reference Manual`_ -- `EFM32PG-STK3402A Website`_ -- `EFM32PG-STK3402A User Guide`_ -- `EFM32PG-STK3402A Schematics`_ +- `SLSTK3402A Website`_ +- `SLSTK3402A User Guide`_ +- `SLSTK3402A Schematics`_ Supported Features ================== -The efm32pg_stk3402a board configuration supports the following hardware features: +The slstk3402a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | @@ -66,18 +66,19 @@ The efm32pg_stk3402a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125_defconfig` +:zephyr_file:`boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125_defconfig` -The default configuration when building for this EFM32JG12B SoC can be found in -:zephyr_file:`boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125_defconfig` +The default configuration when building using this board to develop for the +EFM32JG12 SoC can be found in +:zephyr_file:`boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125_defconfig` Other hardware features are currently not supported by the port. EFM32 Jade Gecko SoC -------------------- -The EFM32 Pearl Gecko Starter Kit EFM32PG-STK3402A can also be used to evaluate -the EFM32 Jade Gecko SoC (EFM32JG12B). The only difference between the Pearl +The EFM32 Pearl Gecko Starter Kit SLSTK3402A can also be used to evaluate +the EFM32 Jade Gecko SoC (EFM32JG12). The only difference between the Pearl Gecko and the Jade Gecko is their core. The Pearl Gecko contains an ARM® Cortex®-M4F core, and the Jade Gecko an ARM® Cortex®-M3 core. Other features such as memory and peripherals are the same. @@ -85,13 +86,14 @@ such as memory and peripherals are the same. Code that is built for the Jade Gecko also runs on an equivalent Pearl Gecko. To build firmware for the Jade Gecko and run it on the EFM32 Pearl Gecko Starter -Kit, use the board ``efm32pg_stk3402a/efm32pg12b500f1024gl125`` instead of ``efm32pg_stk3402a/efm32jg12b500f1024gl125``. +Kit, use the board ``slstk3402a/efm32jg12b500f1024gl125`` instead of +``slstk3402a/efm32pg12b500f1024gl125``. Connections and IOs =================== The EFM32PG12 SoC has twelve GPIO controllers (PORTA to PORTL), but only four -are currently enabled (PORTA, PORTB, PORTD and PORTF) for the EFM32PG-STK3402A +are currently enabled (PORTA, PORTB, PORTD and PORTF) for the SLSTK3402A board. In the following table, the column **Name** contains pin names. For example, PE2 @@ -128,13 +130,13 @@ means pin number 2 on PORTE, as used in the board's datasheets and manuals. System Clock ============ -The EFM32PG SoC is configured to use the 40 MHz external oscillator on the +The EFM32PG12 SoC is configured to use the 40 MHz external oscillator on the board. Serial Port =========== -The EFM32PG SoC has four USARTs and one Low Energy UART (LEUART). +The EFM32PG12 SoC has four USARTs and one Low Energy UART (LEUART). Programming and Debugging ************************* @@ -146,7 +148,7 @@ Programming and Debugging Flashing ======== -The EFM32PG-STK3402A includes an `J-Link`_ serial and debug adaptor built into the +The SLSTK3402A includes an `J-Link`_ serial and debug adaptor built into the board. The adaptor provides: - A USB connection to the host computer, which exposes a mass storage device and a @@ -154,18 +156,18 @@ board. The adaptor provides: - A serial flash device, which implements the USB flash disk file storage. - A physical UART connection which is relayed over interface USB serial port. -Flashing an application to EFM32PG-STK3402A -------------------------------------------- +Flashing an application to SLSTK3402A +------------------------------------- The sample application :ref:`hello_world` is used for this example. Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32pg_stk3402a/efm32pg12b500f1024gl125 + :board: slstk3402a/efm32pg12b500f1024gl125 :goals: build -Connect the EFM32PG-STK3402A to your host computer using the USB port and you +Connect the SLSTK3402A to your host computer using the USB port and you should see a USB connection which exposes a mass storage device(STK3402A). Copy the generated zephyr.bin to the STK3402A drive. @@ -184,16 +186,16 @@ terminal session: .. code-block:: console - Hello World! arm + Hello World! slstk3402a -.. _EFM32PG-STK3402A Website: +.. _SLSTK3402A Website: https://www.silabs.com/products/development-tools/mcu/32-bit/efm32-pearl-gecko-pg12-starter-kit -.. _EFM32PG-STK3402A User Guide: +.. _SLSTK3402A User Guide: https://www.silabs.com/documents/public/user-guides/ug257-stk3402-usersguide.pdf -.. _EFM32PG-STK3402A Schematics: +.. _SLSTK3402A Schematics: https://www.silabs.com/documents/public/schematic-files/BRD2501A-A01-schematic.pdf .. _EFM32PG Website: diff --git a/boards/silabs/efm32pg_stk3402a/doc/efm32pg_stk3402a.jpg b/boards/silabs/starter_kits/slstk3402a/doc/slstk3402a.jpg similarity index 100% rename from boards/silabs/efm32pg_stk3402a/doc/efm32pg_stk3402a.jpg rename to boards/silabs/starter_kits/slstk3402a/doc/slstk3402a.jpg diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a-pinctrl.dtsi b/boards/silabs/starter_kits/slstk3402a/slstk3402a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a-pinctrl.dtsi rename to boards/silabs/starter_kits/slstk3402a/slstk3402a-pinctrl.dtsi diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi b/boards/silabs/starter_kits/slstk3402a/slstk3402a_common.dtsi similarity index 96% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_common.dtsi index 05729334fcdd3c..db100cd289b3e5 100644 --- a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_common.dtsi @@ -5,11 +5,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "efm32pg_stk3402a-pinctrl.dtsi" +#include "slstk3402a-pinctrl.dtsi" #include / { - model = "Silicon Labs EFM32PG STK3402A board"; + model = "Silicon Labs EFM32PG12 STK3402A board"; chosen { zephyr,console = &usart0; diff --git a/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.dts b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.dts new file mode 100644 index 00000000000000..184c3c51a07da5 --- /dev/null +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.dts @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019 Lemonbeat GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "slstk3402a_common.dtsi" + +/ { + model = "Silicon Labs EFM32JG12 STK3402A board "; + compatible = "silabs,slstk3402a_jg", "silabs,efm32jg12b"; + +}; diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.yaml b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml similarity index 70% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.yaml rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml index 7373e65edb28db..f6981091500934 100644 --- a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125.yaml +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml @@ -1,5 +1,5 @@ -identifier: efm32pg_stk3402a/efm32jg12b500f1024gl125 -name: EFM32PG-STK3402A-JG +identifier: slstk3402a/efm32jg12b500f1024gl125 +name: EFM32JG12 SLSTK3402A type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125_defconfig b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125_defconfig similarity index 100% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32jg12b500f1024gl125_defconfig rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125_defconfig diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.dts b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.dts similarity index 56% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.dts rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.dts index a4e98955ae3377..a35289d0cbf493 100644 --- a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.dts +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.dts @@ -7,9 +7,9 @@ /dts-v1/; #include -#include "efm32pg_stk3402a_common.dtsi" +#include "slstk3402a_common.dtsi" / { - model = "Silicon Labs EFM32PG STK3402A board"; - compatible = "silabs,efm32pg_stk3402a", "silabs,efm32pg12b"; + model = "Silicon Labs EFM32PG12 SLSTK3402A board"; + compatible = "silabs,slstk3402a", "silabs,efm32pg12b"; }; diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.yaml b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml similarity index 72% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.yaml rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml index 153ebae67ef919..1ce7433a7aa49e 100644 --- a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125.yaml +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml @@ -1,5 +1,5 @@ -identifier: efm32pg_stk3402a/efm32pg12b500f1024gl125 -name: EFM32PG-STK3402A +identifier: slstk3402a/efm32pg12b500f1024gl125 +name: EFM32PG12 SLSTK3402A type: mcu arch: arm ram: 256 diff --git a/boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125_defconfig b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125_defconfig similarity index 100% rename from boards/silabs/efm32pg_stk3402a/efm32pg_stk3402a_efm32pg12b500f1024gl125_defconfig rename to boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125_defconfig diff --git a/boards/silabs/efm32gg_stk3701a/CMakeLists.txt b/boards/silabs/starter_kits/slstk3701a/CMakeLists.txt similarity index 100% rename from boards/silabs/efm32gg_stk3701a/CMakeLists.txt rename to boards/silabs/starter_kits/slstk3701a/CMakeLists.txt diff --git a/boards/silabs/efm32gg_stk3701a/Kconfig.defconfig b/boards/silabs/starter_kits/slstk3701a/Kconfig.defconfig similarity index 88% rename from boards/silabs/efm32gg_stk3701a/Kconfig.defconfig rename to boards/silabs/starter_kits/slstk3701a/Kconfig.defconfig index c56b944202f294..24d55ad5a9b352 100644 --- a/boards/silabs/efm32gg_stk3701a/Kconfig.defconfig +++ b/boards/silabs/starter_kits/slstk3701a/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2019 Oane Kingma # SPDX-License-Identifier: Apache-2.0 -if BOARD_EFM32GG_STK3701A +if BOARD_SLSTK3701A config CMU_HFXO_FREQ default 50000000 @@ -25,4 +25,4 @@ config NET_L2_ETHERNET endif # NETWORKING -endif # BOARD_EFM32GG_STK3701A +endif # BOARD_SLSTK3701A diff --git a/boards/silabs/efm32gg_stk3701a/Kconfig.efm32gg_stk3701a b/boards/silabs/starter_kits/slstk3701a/Kconfig.slstk3701a similarity index 70% rename from boards/silabs/efm32gg_stk3701a/Kconfig.efm32gg_stk3701a rename to boards/silabs/starter_kits/slstk3701a/Kconfig.slstk3701a index 058ea533a21466..e0fd2b5412ee8a 100644 --- a/boards/silabs/efm32gg_stk3701a/Kconfig.efm32gg_stk3701a +++ b/boards/silabs/starter_kits/slstk3701a/Kconfig.slstk3701a @@ -1,7 +1,7 @@ -# EFM32GG STK3701A board configuration +# EFM32GG11 SLSTK3701A board configuration # Copyright (c) 2019 Interay Solutions B.V. # Copyright (c) 2019 Oane Kingma # SPDX-License-Identifier: Apache-2.0 -config BOARD_EFM32GG_STK3701A +config BOARD_SLSTK3701A select SOC_PART_NUMBER_EFM32GG11B820F2048GL192 diff --git a/boards/silabs/efm32gg_stk3701a/board.c b/boards/silabs/starter_kits/slstk3701a/board.c similarity index 100% rename from boards/silabs/efm32gg_stk3701a/board.c rename to boards/silabs/starter_kits/slstk3701a/board.c diff --git a/boards/silabs/efm32gg_stk3701a/board.cmake b/boards/silabs/starter_kits/slstk3701a/board.cmake similarity index 100% rename from boards/silabs/efm32gg_stk3701a/board.cmake rename to boards/silabs/starter_kits/slstk3701a/board.cmake diff --git a/boards/silabs/efm32gg_stk3701a/board.h b/boards/silabs/starter_kits/slstk3701a/board.h similarity index 100% rename from boards/silabs/efm32gg_stk3701a/board.h rename to boards/silabs/starter_kits/slstk3701a/board.h diff --git a/boards/silabs/efm32gg_stk3701a/board.yml b/boards/silabs/starter_kits/slstk3701a/board.yml similarity index 72% rename from boards/silabs/efm32gg_stk3701a/board.yml rename to boards/silabs/starter_kits/slstk3701a/board.yml index d69afebb60bbe2..5c1db884a42bb4 100644 --- a/boards/silabs/efm32gg_stk3701a/board.yml +++ b/boards/silabs/starter_kits/slstk3701a/board.yml @@ -1,5 +1,5 @@ board: - name: efm32gg_stk3701a + name: slstk3701a vendor: silabs socs: - name: efm32gg11b820f2048gl192 diff --git a/boards/silabs/efm32gg_stk3701a/doc/index.rst b/boards/silabs/starter_kits/slstk3701a/doc/index.rst similarity index 86% rename from boards/silabs/efm32gg_stk3701a/doc/index.rst rename to boards/silabs/starter_kits/slstk3701a/doc/index.rst index ddb5a1f38d7cc2..d270bf346c240d 100644 --- a/boards/silabs/efm32gg_stk3701a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3701a/doc/index.rst @@ -1,20 +1,20 @@ .. _efm32gg_stk3701a: -EFM32 Giant Gecko GG11 Starter Kit -################################## +EFM32 Giant Gecko 11 (SLSTK3701A) +################################# Overview ******** -The EFM32 Giant Gecko Starter Kit EFM32GG-STK3701A contains an MCU from the +The EFM32 Giant Gecko Starter Kit SLSTK3701A contains an MCU from the EFM32GG Series 1 family built on an ARM® Cortex®-M4F processor with excellent low power capabilities. -.. figure:: efm32gg_stk3701a.jpg +.. figure:: slstk3701a.jpg :align: center - :alt: EFM32GG-SLSTK3701A + :alt: EFM32GG11 SLSTK3701A - EFM32GG-SLSTK3701A (image courtesy of Silicon Labs) + EFM32GG11 SLSTK3701A (image courtesy of Silicon Labs) Hardware ******** @@ -31,19 +31,19 @@ Hardware - 2 digital microphones - On-board Segger J-Link USB debugger -For more information about the EFM32GG11 SoC and EFM32GG-STK3701A board: +For more information about the EFM32GG11 SoC and SLSTK3701A board: - `EFM32GG Series 1 Website`_ - `EFM32GG11 Datasheet`_ - `EFM32GG11 Reference Manual`_ -- `EFM32GG-STK3701A Website`_ -- `EFM32GG-STK3701A User Guide`_ -- `EFM32GG-STK3701A Schematics`_ +- `SLSTK3701A Website`_ +- `SLSTK3701A User Guide`_ +- `SLSTK3701A Schematics`_ Supported Features ================== -The efm32gg_stk3701a board configuration supports the following hardware +The slstk3701a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ @@ -70,7 +70,7 @@ features: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a_defconfig` +:zephyr_file:`boards/silabs/starter_kits/slstk3701a/slstk3701a_defconfig` Other hardware features are currently not supported by the port. @@ -78,7 +78,7 @@ Connections and IOs =================== The EFM32GG11 SoC has nine GPIO controllers (PORTA to PORTI), all of which are -currently enabled for the EFM32GG-STK3701A board. +currently enabled for the SLSTK3701A board. In the following table, the column **Name** contains pin names. For example, PE1 means pin number 1 on PORTE, as used in the board's datasheets and manuals. @@ -137,7 +137,7 @@ Programming and Debugging Flashing ======== -The EFM32GG-STK3701A includes an `J-Link`_ serial and debug adaptor built into the +The SLSTK3701A includes an `J-Link`_ serial and debug adaptor built into the board. The adaptor provides: - A USB connection to the host computer, which exposes a mass storage device and a @@ -145,18 +145,18 @@ board. The adaptor provides: - A serial flash device, which implements the USB flash disk file storage. - A physical UART connection which is relayed over interface USB serial port. -Flashing an application to EFM32GG-STK3701A -------------------------------------------- +Flashing an application to SLSTK3701A +------------------------------------- The sample application :ref:`hello_world` is used for this example. Build the Zephyr kernel and application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: efm32gg_stk3701a + :board: slstk3701a :goals: build -Connect the EFM32GG-STK3701A to your host computer using the USB port and you +Connect the SLSTK3701A to your host computer using the USB port and you should see a USB connection which exposes a mass storage device(STK3701A) and a USB Serial Port. Copy the generated zephyr.bin to the STK3701A drive. @@ -172,16 +172,16 @@ terminal session: .. code-block:: console - Hello World! efm32gg_stk3701a + Hello World! slstk3701a -.. _EFM32GG-STK3701A Website: +.. _SLSTK3701A Website: https://www.silabs.com/products/development-tools/mcu/32-bit/efm32-giant-gecko-gg11-starter-kit -.. _EFM32GG-STK3701A User Guide: +.. _SLSTK3701A User Guide: https://www.silabs.com/documents/public/user-guides/ug287-stk3701.pdf -.. _EFM32GG-STK3701A Schematics: +.. _SLSTK3701A Schematics: https://www.silabs.com/documents/public/schematic-files/BRD2204A-B00-schematic.pdf .. _EFM32GG Series 1 Website: diff --git a/boards/silabs/efm32gg_stk3701a/doc/efm32gg_stk3701a.jpg b/boards/silabs/starter_kits/slstk3701a/doc/slstk3701a.jpg similarity index 100% rename from boards/silabs/efm32gg_stk3701a/doc/efm32gg_stk3701a.jpg rename to boards/silabs/starter_kits/slstk3701a/doc/slstk3701a.jpg diff --git a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi b/boards/silabs/starter_kits/slstk3701a/slstk3701a-pinctrl.dtsi similarity index 100% rename from boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a-pinctrl.dtsi rename to boards/silabs/starter_kits/slstk3701a/slstk3701a-pinctrl.dtsi diff --git a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.dts b/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts similarity index 93% rename from boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.dts rename to boards/silabs/starter_kits/slstk3701a/slstk3701a.dts index 39589b61855062..1e67f024d7f438 100644 --- a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.dts +++ b/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts @@ -8,11 +8,11 @@ /dts-v1/; #include #include -#include "efm32gg_stk3701a-pinctrl.dtsi" +#include "slstk3701a-pinctrl.dtsi" / { - model = "Silicon Labs EFM32GG STK3701A board"; - compatible = "silabs,efm32gg_stk3701a", "silabs,efm32gg11b"; + model = "Silicon Labs EFM32GG11 SLSTK3701A board"; + compatible = "silabs,slstk3701a", "silabs,efm32gg11b"; chosen { zephyr,console = &usart4; @@ -33,11 +33,11 @@ leds { compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpioh 10 0>; + gpios = <&gpioh 10 GPIO_ACTIVE_LOW>; label = "LED 0"; }; led1: led_1 { - gpios = <&gpioh 13 0>; + gpios = <&gpioh 13 GPIO_ACTIVE_LOW>; label = "LED 1"; }; }; diff --git a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.yaml b/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml similarity index 71% rename from boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.yaml rename to boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml index 426328eae97118..bfad741b9183bf 100644 --- a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a.yaml +++ b/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml @@ -1,5 +1,5 @@ -identifier: efm32gg_stk3701a -name: EFM32GG-STK3701A +identifier: slstk3701a +name: EFM32GG11 Giant Gecko Starter Kit (SLSTK3701A) type: mcu arch: arm ram: 512 diff --git a/boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a_defconfig b/boards/silabs/starter_kits/slstk3701a/slstk3701a_defconfig similarity index 100% rename from boards/silabs/efm32gg_stk3701a/efm32gg_stk3701a_defconfig rename to boards/silabs/starter_kits/slstk3701a/slstk3701a_defconfig diff --git a/boards/silabs/efm32gg_stk3701a/support/openocd.cfg b/boards/silabs/starter_kits/slstk3701a/support/openocd.cfg similarity index 100% rename from boards/silabs/efm32gg_stk3701a/support/openocd.cfg rename to boards/silabs/starter_kits/slstk3701a/support/openocd.cfg diff --git a/boards/sipeed/longan_nano/doc/index.rst b/boards/sipeed/longan_nano/doc/index.rst index b62d91c3130070..6150c2378cf81f 100644 --- a/boards/sipeed/longan_nano/doc/index.rst +++ b/boards/sipeed/longan_nano/doc/index.rst @@ -74,6 +74,11 @@ The board configuration supports the following hardware features: * - ADC - :kconfig:option:`CONFIG_ADC` - :dtcompatible:`gd,gd32-adc` + * - SPI + - :kconfig:option:`CONFIG_SPI` + - :dtcompatible:`gd,gd32-spi` + +The microSD card reader in Longan Nano board is connected to SPI1. Serial Port =========== diff --git a/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_3.overlay b/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_3.overlay index bb7e6a3ee9bd77..590d0aefb8a8cb 100644 --- a/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_3.overlay +++ b/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_3.overlay @@ -19,7 +19,6 @@ uart-0 = &uart0; uart-1 = &uart1; uart-2 = &uart2; - spi-flash0 = &w25q128bv; }; chosen { diff --git a/boards/snps/em_starterkit/em_starterkit_r23.dtsi b/boards/snps/em_starterkit/em_starterkit_r23.dtsi index 3de7425d975015..ef93abcfd46d33 100644 --- a/boards/snps/em_starterkit/em_starterkit_r23.dtsi +++ b/boards/snps/em_starterkit/em_starterkit_r23.dtsi @@ -5,10 +5,6 @@ */ / { - aliases { - spi-flash0 = &w25q128bv; - }; - soc { i2c@f0004000 { interrupts = <25 1>; diff --git a/boards/snps/emsdp/emsdp_emsdp_em11d.dts b/boards/snps/emsdp/emsdp_emsdp_em11d.dts index 6a24a9ec5bd6f2..d3a9a10d0e73a6 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em11d.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em11d.dts @@ -17,7 +17,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em4.dts b/boards/snps/emsdp/emsdp_emsdp_em4.dts index 0d0306065c09d4..04414f10c6e64a 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em4.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em4.dts @@ -15,7 +15,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em5d.dts b/boards/snps/emsdp/emsdp_emsdp_em5d.dts index 66a544e95ef769..57ba196e1dde35 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em5d.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em5d.dts @@ -15,7 +15,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em6.dts b/boards/snps/emsdp/emsdp_emsdp_em6.dts index 0d0306065c09d4..04414f10c6e64a 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em6.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em6.dts @@ -15,7 +15,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em7d.dts b/boards/snps/emsdp/emsdp_emsdp_em7d.dts index 66a544e95ef769..57ba196e1dde35 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em7d.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em7d.dts @@ -15,7 +15,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em7d_esp.dts b/boards/snps/emsdp/emsdp_emsdp_em7d_esp.dts index 89fc30499b7fb5..1880de517b9648 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em7d_esp.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em7d_esp.dts @@ -15,7 +15,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/emsdp/emsdp_emsdp_em9d.dts b/boards/snps/emsdp/emsdp_emsdp_em9d.dts index c28956b9f60024..c87bfe3e7f6a89 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em9d.dts +++ b/boards/snps/emsdp/emsdp_emsdp_em9d.dts @@ -16,7 +16,6 @@ aliases { uart-0 = &uart0; - spi-flash0 = &s25fl256s; }; chosen { diff --git a/boards/snps/nsim/CMakeLists.txt b/boards/snps/nsim/arc_classic/CMakeLists.txt similarity index 100% rename from boards/snps/nsim/CMakeLists.txt rename to boards/snps/nsim/arc_classic/CMakeLists.txt diff --git a/boards/snps/nsim/Kconfig b/boards/snps/nsim/arc_classic/Kconfig similarity index 100% rename from boards/snps/nsim/Kconfig rename to boards/snps/nsim/arc_classic/Kconfig diff --git a/boards/snps/nsim/Kconfig.nsim b/boards/snps/nsim/arc_classic/Kconfig.nsim similarity index 100% rename from boards/snps/nsim/Kconfig.nsim rename to boards/snps/nsim/arc_classic/Kconfig.nsim diff --git a/boards/snps/nsim/arc_mpu_regions.c b/boards/snps/nsim/arc_classic/arc_mpu_regions.c similarity index 100% rename from boards/snps/nsim/arc_mpu_regions.c rename to boards/snps/nsim/arc_classic/arc_mpu_regions.c diff --git a/boards/snps/nsim/board.cmake b/boards/snps/nsim/arc_classic/board.cmake similarity index 100% rename from boards/snps/nsim/board.cmake rename to boards/snps/nsim/arc_classic/board.cmake diff --git a/boards/snps/nsim/board.yml b/boards/snps/nsim/arc_classic/board.yml similarity index 100% rename from boards/snps/nsim/board.yml rename to boards/snps/nsim/arc_classic/board.yml diff --git a/boards/snps/nsim/doc/index.rst b/boards/snps/nsim/arc_classic/doc/index.rst similarity index 100% rename from boards/snps/nsim/doc/index.rst rename to boards/snps/nsim/arc_classic/doc/index.rst diff --git a/boards/snps/nsim/haps_arcv3_init.c b/boards/snps/nsim/arc_classic/haps_arcv3_init.c similarity index 100% rename from boards/snps/nsim/haps_arcv3_init.c rename to boards/snps/nsim/arc_classic/haps_arcv3_init.c diff --git a/boards/snps/nsim/nsim-ccm-mem.dtsi b/boards/snps/nsim/arc_classic/nsim-ccm-mem.dtsi similarity index 100% rename from boards/snps/nsim/nsim-ccm-mem.dtsi rename to boards/snps/nsim/arc_classic/nsim-ccm-mem.dtsi diff --git a/boards/snps/nsim/nsim-flash-sram-mem.dtsi b/boards/snps/nsim/arc_classic/nsim-flash-sram-mem.dtsi similarity index 100% rename from boards/snps/nsim/nsim-flash-sram-mem.dtsi rename to boards/snps/nsim/arc_classic/nsim-flash-sram-mem.dtsi diff --git a/boards/snps/nsim/nsim-flat-mem.dtsi b/boards/snps/nsim/arc_classic/nsim-flat-mem.dtsi similarity index 100% rename from boards/snps/nsim/nsim-flat-mem.dtsi rename to boards/snps/nsim/arc_classic/nsim-flat-mem.dtsi diff --git a/boards/snps/nsim/nsim-smp.dtsi b/boards/snps/nsim/arc_classic/nsim-smp.dtsi similarity index 100% rename from boards/snps/nsim/nsim-smp.dtsi rename to boards/snps/nsim/arc_classic/nsim-smp.dtsi diff --git a/boards/snps/nsim/nsim-uart-hostlink.dtsi b/boards/snps/nsim/arc_classic/nsim-uart-hostlink.dtsi similarity index 100% rename from boards/snps/nsim/nsim-uart-hostlink.dtsi rename to boards/snps/nsim/arc_classic/nsim-uart-hostlink.dtsi diff --git a/boards/snps/nsim/nsim-uart-ns16550.dtsi b/boards/snps/nsim/arc_classic/nsim-uart-ns16550.dtsi similarity index 100% rename from boards/snps/nsim/nsim-uart-ns16550.dtsi rename to boards/snps/nsim/arc_classic/nsim-uart-ns16550.dtsi diff --git a/boards/snps/nsim/nsim.dtsi b/boards/snps/nsim/arc_classic/nsim.dtsi similarity index 100% rename from boards/snps/nsim/nsim.dtsi rename to boards/snps/nsim/arc_classic/nsim.dtsi diff --git a/boards/snps/nsim/nsim_em-sec.dtsi b/boards/snps/nsim/arc_classic/nsim_em-sec.dtsi similarity index 100% rename from boards/snps/nsim/nsim_em-sec.dtsi rename to boards/snps/nsim/arc_classic/nsim_em-sec.dtsi diff --git a/boards/snps/nsim/nsim_em.dtsi b/boards/snps/nsim/arc_classic/nsim_em.dtsi similarity index 100% rename from boards/snps/nsim/nsim_em.dtsi rename to boards/snps/nsim/arc_classic/nsim_em.dtsi diff --git a/boards/snps/nsim/nsim_nsim_em.dts b/boards/snps/nsim/arc_classic/nsim_nsim_em.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_em.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_em.dts diff --git a/boards/snps/nsim/nsim_nsim_em.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_em.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_em.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_em.yaml diff --git a/boards/snps/nsim/nsim_nsim_em11d.dts b/boards/snps/nsim/arc_classic/nsim_nsim_em11d.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_em11d.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_em11d.dts diff --git a/boards/snps/nsim/nsim_nsim_em11d.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_em11d.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_em11d.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_em11d.yaml diff --git a/boards/snps/nsim/nsim_nsim_em11d_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_em11d_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_em11d_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_em11d_defconfig diff --git a/boards/snps/nsim/nsim_nsim_em7d_v22.dts b/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_em7d_v22.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts diff --git a/boards/snps/nsim/nsim_nsim_em7d_v22.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_em7d_v22.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.yaml diff --git a/boards/snps/nsim/nsim_nsim_em7d_v22_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_em7d_v22_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22_defconfig diff --git a/boards/snps/nsim/nsim_nsim_em_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_em_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_em_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_em_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs.dts diff --git a/boards/snps/nsim/nsim_nsim_hs.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs5x.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x.dts diff --git a/boards/snps/nsim/nsim_nsim_hs5x.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs5x_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp.dts diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp_12cores.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp_12cores.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores.dts diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp_12cores.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp_12cores.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp_12cores_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp_12cores_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_12cores_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs5x_smp_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs5x_smp_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs5x_smp_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs6x.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x.dts diff --git a/boards/snps/nsim/nsim_nsim_hs6x.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs6x_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp.dts diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp_12cores.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp_12cores.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores.dts diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp_12cores.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp_12cores.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp_12cores_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp_12cores_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_12cores_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs6x_smp_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs6x_smp_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs6x_smp_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_flash_xip.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_flash_xip.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip.dts diff --git a/boards/snps/nsim/nsim_nsim_hs_flash_xip.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_flash_xip.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs_flash_xip_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_flash_xip_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_flash_xip_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_hostlink.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_hostlink.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink.dts diff --git a/boards/snps/nsim/nsim_nsim_hs_hostlink.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_hostlink.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs_hostlink_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_hostlink_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_hostlink_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_mpuv6.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_mpuv6.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6.dts diff --git a/boards/snps/nsim/nsim_nsim_hs_mpuv6.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_mpuv6.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs_mpuv6_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_mpuv6_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_mpuv6_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_smp.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs_smp.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_smp.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_smp.dts diff --git a/boards/snps/nsim/nsim_nsim_hs_smp.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs_smp.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_smp.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_smp.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs_smp_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_smp_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_smp_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_smp_defconfig diff --git a/boards/snps/nsim/nsim_nsim_hs_sram.dts b/boards/snps/nsim/arc_classic/nsim_nsim_hs_sram.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_sram.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_sram.dts diff --git a/boards/snps/nsim/nsim_nsim_hs_sram.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_hs_sram.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_sram.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_sram.yaml diff --git a/boards/snps/nsim/nsim_nsim_hs_sram_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_hs_sram_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_hs_sram_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_hs_sram_defconfig diff --git a/boards/snps/nsim/nsim_nsim_sem.dts b/boards/snps/nsim/arc_classic/nsim_nsim_sem.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_sem.dts diff --git a/boards/snps/nsim/nsim_nsim_sem.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml diff --git a/boards/snps/nsim/nsim_nsim_sem_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_sem_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_sem_defconfig diff --git a/boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard.dts b/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts diff --git a/boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.yaml diff --git a/boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_sem_mpu_stack_guard_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard_defconfig diff --git a/boards/snps/nsim/nsim_nsim_vpx5.dts b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5.dts similarity index 100% rename from boards/snps/nsim/nsim_nsim_vpx5.dts rename to boards/snps/nsim/arc_classic/nsim_nsim_vpx5.dts diff --git a/boards/snps/nsim/nsim_nsim_vpx5.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5.yaml similarity index 100% rename from boards/snps/nsim/nsim_nsim_vpx5.yaml rename to boards/snps/nsim/arc_classic/nsim_nsim_vpx5.yaml diff --git a/boards/snps/nsim/nsim_nsim_vpx5_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_defconfig similarity index 100% rename from boards/snps/nsim/nsim_nsim_vpx5_defconfig rename to boards/snps/nsim/arc_classic/nsim_nsim_vpx5_defconfig diff --git a/boards/snps/nsim/support/mdb_em.args b/boards/snps/nsim/arc_classic/support/mdb_em.args similarity index 100% rename from boards/snps/nsim/support/mdb_em.args rename to boards/snps/nsim/arc_classic/support/mdb_em.args diff --git a/boards/snps/nsim/support/mdb_em11d.args b/boards/snps/nsim/arc_classic/support/mdb_em11d.args similarity index 100% rename from boards/snps/nsim/support/mdb_em11d.args rename to boards/snps/nsim/arc_classic/support/mdb_em11d.args diff --git a/boards/snps/nsim/support/mdb_em7d_v22.args b/boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args similarity index 100% rename from boards/snps/nsim/support/mdb_em7d_v22.args rename to boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args diff --git a/boards/snps/nsim/support/mdb_hs.args b/boards/snps/nsim/arc_classic/support/mdb_hs.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs.args rename to boards/snps/nsim/arc_classic/support/mdb_hs.args diff --git a/boards/snps/nsim/support/mdb_hs5x.args b/boards/snps/nsim/arc_classic/support/mdb_hs5x.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs5x.args rename to boards/snps/nsim/arc_classic/support/mdb_hs5x.args diff --git a/boards/snps/nsim/support/mdb_hs5x_smp.args b/boards/snps/nsim/arc_classic/support/mdb_hs5x_smp.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs5x_smp.args rename to boards/snps/nsim/arc_classic/support/mdb_hs5x_smp.args diff --git a/boards/snps/nsim/support/mdb_hs5x_smp_12cores.args b/boards/snps/nsim/arc_classic/support/mdb_hs5x_smp_12cores.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs5x_smp_12cores.args rename to boards/snps/nsim/arc_classic/support/mdb_hs5x_smp_12cores.args diff --git a/boards/snps/nsim/support/mdb_hs6x.args b/boards/snps/nsim/arc_classic/support/mdb_hs6x.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs6x.args rename to boards/snps/nsim/arc_classic/support/mdb_hs6x.args diff --git a/boards/snps/nsim/support/mdb_hs6x_smp.args b/boards/snps/nsim/arc_classic/support/mdb_hs6x_smp.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs6x_smp.args rename to boards/snps/nsim/arc_classic/support/mdb_hs6x_smp.args diff --git a/boards/snps/nsim/support/mdb_hs6x_smp_12cores.args b/boards/snps/nsim/arc_classic/support/mdb_hs6x_smp_12cores.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs6x_smp_12cores.args rename to boards/snps/nsim/arc_classic/support/mdb_hs6x_smp_12cores.args diff --git a/boards/snps/nsim/support/mdb_hs_flash_xip.args b/boards/snps/nsim/arc_classic/support/mdb_hs_flash_xip.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs_flash_xip.args rename to boards/snps/nsim/arc_classic/support/mdb_hs_flash_xip.args diff --git a/boards/snps/nsim/support/mdb_hs_hostlink.args b/boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs_hostlink.args rename to boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args diff --git a/boards/snps/nsim/support/mdb_hs_mpuv6.args b/boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs_mpuv6.args rename to boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args diff --git a/boards/snps/nsim/support/mdb_hs_smp.args b/boards/snps/nsim/arc_classic/support/mdb_hs_smp.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs_smp.args rename to boards/snps/nsim/arc_classic/support/mdb_hs_smp.args diff --git a/boards/snps/nsim/support/mdb_hs_sram.args b/boards/snps/nsim/arc_classic/support/mdb_hs_sram.args similarity index 100% rename from boards/snps/nsim/support/mdb_hs_sram.args rename to boards/snps/nsim/arc_classic/support/mdb_hs_sram.args diff --git a/boards/snps/nsim/support/mdb_sem.args b/boards/snps/nsim/arc_classic/support/mdb_sem.args similarity index 100% rename from boards/snps/nsim/support/mdb_sem.args rename to boards/snps/nsim/arc_classic/support/mdb_sem.args diff --git a/boards/snps/nsim/support/mdb_sem_mpu_stack_guard.args b/boards/snps/nsim/arc_classic/support/mdb_sem_mpu_stack_guard.args similarity index 100% rename from boards/snps/nsim/support/mdb_sem_mpu_stack_guard.args rename to boards/snps/nsim/arc_classic/support/mdb_sem_mpu_stack_guard.args diff --git a/boards/snps/nsim/support/mdb_vpx5.args b/boards/snps/nsim/arc_classic/support/mdb_vpx5.args similarity index 100% rename from boards/snps/nsim/support/mdb_vpx5.args rename to boards/snps/nsim/arc_classic/support/mdb_vpx5.args diff --git a/boards/snps/nsim/support/nsim_em.props b/boards/snps/nsim/arc_classic/support/nsim_em.props similarity index 100% rename from boards/snps/nsim/support/nsim_em.props rename to boards/snps/nsim/arc_classic/support/nsim_em.props diff --git a/boards/snps/nsim/support/nsim_em11d.props b/boards/snps/nsim/arc_classic/support/nsim_em11d.props similarity index 100% rename from boards/snps/nsim/support/nsim_em11d.props rename to boards/snps/nsim/arc_classic/support/nsim_em11d.props diff --git a/boards/snps/nsim/support/nsim_em7d_v22.props b/boards/snps/nsim/arc_classic/support/nsim_em7d_v22.props similarity index 100% rename from boards/snps/nsim/support/nsim_em7d_v22.props rename to boards/snps/nsim/arc_classic/support/nsim_em7d_v22.props diff --git a/boards/snps/nsim/support/nsim_hs.props b/boards/snps/nsim/arc_classic/support/nsim_hs.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs.props rename to boards/snps/nsim/arc_classic/support/nsim_hs.props diff --git a/boards/snps/nsim/support/nsim_hs5x.props b/boards/snps/nsim/arc_classic/support/nsim_hs5x.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs5x.props rename to boards/snps/nsim/arc_classic/support/nsim_hs5x.props diff --git a/boards/snps/nsim/support/nsim_hs6x.props b/boards/snps/nsim/arc_classic/support/nsim_hs6x.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs6x.props rename to boards/snps/nsim/arc_classic/support/nsim_hs6x.props diff --git a/boards/snps/nsim/support/nsim_hs_flash_xip.props b/boards/snps/nsim/arc_classic/support/nsim_hs_flash_xip.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs_flash_xip.props rename to boards/snps/nsim/arc_classic/support/nsim_hs_flash_xip.props diff --git a/boards/snps/nsim/support/nsim_hs_hostlink.props b/boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs_hostlink.props rename to boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props diff --git a/boards/snps/nsim/support/nsim_hs_mpuv6.props b/boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs_mpuv6.props rename to boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props diff --git a/boards/snps/nsim/support/nsim_hs_sram.props b/boards/snps/nsim/arc_classic/support/nsim_hs_sram.props similarity index 100% rename from boards/snps/nsim/support/nsim_hs_sram.props rename to boards/snps/nsim/arc_classic/support/nsim_hs_sram.props diff --git a/boards/snps/nsim/support/nsim_sem.props b/boards/snps/nsim/arc_classic/support/nsim_sem.props similarity index 100% rename from boards/snps/nsim/support/nsim_sem.props rename to boards/snps/nsim/arc_classic/support/nsim_sem.props diff --git a/boards/snps/nsim/support/nsim_sem_mpu_stack_guard.props b/boards/snps/nsim/arc_classic/support/nsim_sem_mpu_stack_guard.props similarity index 100% rename from boards/snps/nsim/support/nsim_sem_mpu_stack_guard.props rename to boards/snps/nsim/arc_classic/support/nsim_sem_mpu_stack_guard.props diff --git a/boards/snps/nsim/support/nsim_vpx5.props b/boards/snps/nsim/arc_classic/support/nsim_vpx5.props similarity index 100% rename from boards/snps/nsim/support/nsim_vpx5.props rename to boards/snps/nsim/arc_classic/support/nsim_vpx5.props diff --git a/boards/snps/nsim/arc_v/Kconfig.defconfig b/boards/snps/nsim/arc_v/Kconfig.defconfig new file mode 100644 index 00000000000000..469d5e2a92b415 --- /dev/null +++ b/boards/snps/nsim/arc_v/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Synopsys, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NSIM_ARC_V_RMX100 + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 5000000 + +endif # BOARD_NSIM_ARC_V_RMX100 diff --git a/boards/snps/nsim/arc_v/Kconfig.nsim_arc_v b/boards/snps/nsim/arc_v/Kconfig.nsim_arc_v new file mode 100644 index 00000000000000..600a7e7499d234 --- /dev/null +++ b/boards/snps/nsim/arc_v/Kconfig.nsim_arc_v @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Synopsys, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NSIM_ARC_V + select SOC_RMX100 if BOARD_NSIM_ARC_V_RMX100 diff --git a/boards/snps/nsim/arc_v/board.cmake b/boards/snps/nsim/arc_v/board.cmake new file mode 100644 index 00000000000000..2c0230917d1ed0 --- /dev/null +++ b/boards/snps/nsim/arc_v/board.cmake @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(SUPPORTED_EMU_PLATFORMS nsim) + +string(SUBSTRING "${BOARD_QUALIFIERS}" 1 -1 NSIM_BASE_FILENAME) +string(REPLACE "/" "_" NSIM_BASE_FILENAME "${NSIM_BASE_FILENAME}") + +board_set_flasher_ifnset(arc-nsim) +board_set_debugger_ifnset(arc-nsim) + +set(NSIM_PROPS "${NSIM_BASE_FILENAME}.props") +board_runner_args(arc-nsim "--props=${NSIM_PROPS}") + +board_finalize_runner_args(arc-nsim) +include(${ZEPHYR_BASE}/boards/common/mdb-nsim.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/snps/nsim/arc_v/board.yml b/boards/snps/nsim/arc_v/board.yml new file mode 100644 index 00000000000000..a91eaffd90a001 --- /dev/null +++ b/boards/snps/nsim/arc_v/board.yml @@ -0,0 +1,5 @@ +board: + name: nsim_arc_v + vendor: snps + socs: + - name: rmx100 diff --git a/boards/snps/nsim/arc_v/doc/index.rst b/boards/snps/nsim/arc_v/doc/index.rst new file mode 100644 index 00000000000000..8586758be7757d --- /dev/null +++ b/boards/snps/nsim/arc_v/doc/index.rst @@ -0,0 +1,194 @@ +.. _nsim_arc_v: + +DesignWare RISC-V nSIM and HAPS FPGA boards +########################################### + +Overview +******** + +This platform can be used to run Zephyr RTOS on the widest possible range of Synopsys RISC-V processors in +simulation with `Designware ARC nSIM`_ or run same images on FPGA prototyping platform `HAPS`_. The +platform includes the following features: + +* RISC-V processor core, which implements riscv32 ISA +* Virtual serial console (a standard ``ns16550`` UART model) + +Supported board targets for that platform are listed below: + +* ``nsim_arc_v/rmx100`` - Synopsys RISC-V RMX100 core + +.. _board_nsim_arc_v_prop_files: + +It is recommended to look at precise description of a particular board target in ``.props`` +files in :zephyr_file:`boards/snps/nsim_arc_v/support/` directory to understand +which options are configured and so will be used on invocation of the simulator. + +.. warning:: + All nSIM targets are used for demo and testing purposes. They are not meant to + represent any real system and so might be renamed, removed or modified at any point. + +Programming and Debugging +************************* + +Required Hardware and Software +============================== + +To run single-core Zephyr RTOS applications in simulation on this board, +either `DesignWare ARC nSIM`_ or `DesignWare ARC Free nSIM`_ is required. + +Building & Running Sample Applications +====================================== + +Most board targets support building with GNU toolchains, however +there might be exceptions from that, especially for newly added targets. You can check supported +toolchains for the board targets in the corresponding ``.yaml`` file. + +I.e. for the ``nsim_arc_v/rmx100`` board we can check :zephyr_file:`boards/snps/nsim_arc_v/nsim_arc_v_rmx100.yaml` + +The supported toolchains are listed in ``toolchain:`` array in ``.yaml`` file, where we can find: + +* **zephyr** - implies RISC-V GNU toolchain from Zephyr SDK. You can find more information about + Zephyr SDK :ref:`here `. +* **cross-compile** - implies RISC-V GNU cross toolchain, which is not a part of Zephyr SDK. Note that + some (especially new) board targets may declare ``cross-compile`` toolchain support without + ``zephyr`` toolchain support because corresponding target CPU support hasn't been added to Zephyr + SDK yet. You can find more information about its usage here: :ref:`here `. +* **arcmwdt** - implies proprietary ARC MWDT toolchain. You can find more information about its + usage here: :ref:`here `. Not yet supported: work in progress. + +Use this configuration to run basic Zephyr applications and kernel tests in +nSIM, for example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: nsim_arc_v/rmx100 + :goals: flash + +This will build an image with the synchronization sample app, boot it using +nSIM, and display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.2.0-3948-gd351a024dc87 *** + thread_a: Hello World from cpu 0 on nsim_arc_v! + thread_b: Hello World from cpu 0 on nsim_arc_v! + thread_a: Hello World from cpu 0 on nsim_arc_v! + thread_b: Hello World from cpu 0 on nsim_arc_v! + thread_a: Hello World from cpu 0 on nsim_arc_v! + +.. note:: + To exit the simulator, use :kbd:`Ctrl+]`, then :kbd:`Ctrl+c` + +.. _board_nsim_arc_v_verbose_build: + +.. tip:: + You can get more details about the building process by running build in verbose mode. It can be + done by passing ``-v`` flag to the west: ``west -v build -b nsim_hs samples/synchronization`` + +Debugging +========= + +.. _board_nsim_arc_v_debugging_gdb: + +Debugging with GDB +------------------ + +.. note:: + Debugging on nSIM via GDB is only supported on single-core targets (which use standalone + nSIM). + +.. note:: + The normal ``west debug`` command won't work for debugging applications using nsim boards + because both the nSIM simulator and the debugger use the same console for + input / output. + In case of GDB debugger it's possible to use a separate terminal windows for GDB and nSIM to + avoid intermixing their output. + +After building your application, open two terminal windows. In terminal one, use nSIM to start a GDB +server and wait for a remote connection with following command: + +.. code-block:: console + + west debugserver --runner arc-nsim + +In terminal two, connect to the GDB server using RISC-V GDB. You can find it in Zephyr SDK: + +* you should use :file:`riscv64-zephyr-elf-gdb` + +This command loads the symbol table from the elf binary file, for example the +:file:`build/zephyr/zephyr.elf` file: + +.. code-block:: console + + riscv64-zephyr-elf-gdb -ex 'target remote localhost:3333' -ex load build/zephyr/zephyr.elf + +Now the debug environment has been set up, and it's possible to debug the application with gdb +commands. + +Modifying the configuration +*************************** + +If modification of existing nsim configuration is required or even there's a need in creation of a +new one it's required to maintain alignment between + +* Zephyr OS configuration +* nSIM configuration +* GNU toolchain compiler options + +.. note:: + The ``.tcf`` configuration files are not supported by Zephyr directly. There are multiple + reasons for that. ``.tcf`` perfectly suits building of bare-metal single-thread application - + in that case all the compiler options from ``.tcf`` are passed to the compiler, so all the HW + features are used by the application and optimal code is being generated. + The situation is completely different when multi-thread feature-rich operation system is + considered. Of course it is still possible to build all the code with all the + options from ``.tcf`` - but that may be far from optimal solution. For example, such approach + require so save & restore full register context for all tasks (and sometimes even for + interrupts). And for DSP-enabled or for FPU-enabled systems that leads to dozens of extra + registers save and restore even if the most of the user and kernel tasks don't actually use + DSP or FPU. Instead we prefer to fine-tune the HW features usage which (with all its pros) + require us to maintain them separately from ``.tcf`` configuration. + + +Zephyr OS configuration +======================= + +Zephyr OS configuration is defined via Kconfig and Device tree. These are non RISC-V-specific +mechanisms which are described in :ref:`board porting guide `. + +It is advised to look for ``_defconfig``, ``.dts`` and +``.yaml`` as an entry point for board target. + +nSIM configuration +================== + +nSIM configuration is defined in :ref:`props files `. +Generally they are identical to the values from corresponding ``.tcf`` configuration with few +exceptions: + +* The UART model is added +* CLINT model is added + +GNU toolchain compiler options +===================================== + +The hardware-specific compiler options are set in corresponding SoC cmake file. For ``nsim_arc_v`` board +it is :zephyr_file:`soc/snps/nsim/arc_v/CMakeLists.txt`. + +For the GNU toolchain the basic configuration is set via ``-march`` which is defined in generic code +and based on the selected CPU model via Kconfig. It still can be forcefully set to required value +on SoC level. + +.. note:: + The non hardware-specific compiler options like optimizations, library selections, C / C++ + language options are still set in Zephyr generic code. It could be observed by + :ref:`running build in verbose mode `. + +References +********** + +.. _Designware ARC nSIM: https://www.synopsys.com/dw/ipdir.php?ds=sim_nsim +.. _DesignWare ARC Free nSIM: https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi +.. _HAPS: https://www.synopsys.com/verification/prototyping/haps.html +.. _ARC MWDT: https://www.synopsys.com/dw/ipdir.php?ds=sw_metaware diff --git a/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.dts b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.dts new file mode 100644 index 00000000000000..351b88c2679b81 --- /dev/null +++ b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.dts @@ -0,0 +1,24 @@ +/dts-v1/; + +#include "rmx100.dtsi" + +/ { + model = "Synopsys RMX100"; + compatible = "snps,rmx100"; + + aliases { + uart-0 = &uart0; + }; + + chosen { + zephyr,sram = &ddr0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.yaml b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.yaml new file mode 100644 index 00000000000000..548d0f3dbf7fd8 --- /dev/null +++ b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100.yaml @@ -0,0 +1,14 @@ +identifier: nsim_arc_v/rmx100 +name: Synopsys rmx100 +simulation: nsim +simulation_exec: nsimdrv +type: sim +arch: riscv +toolchain: + - zephyr + - cross-compile +testing: + ignore_tags: + - net + - bluetooth +vendor: snps diff --git a/boards/snps/nsim/arc_v/nsim_arc_v_rmx100_defconfig b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100_defconfig new file mode 100644 index 00000000000000..17283e7b6649c3 --- /dev/null +++ b/boards/snps/nsim/arc_v/nsim_arc_v_rmx100_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Synopsys, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_XIP=n +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_LOG=y diff --git a/boards/snps/nsim/arc_v/rmx100.dtsi b/boards/snps/nsim/arc_v/rmx100.dtsi new file mode 100644 index 00000000000000..89586284c61f2a --- /dev/null +++ b/boards/snps/nsim/arc_v/rmx100.dtsi @@ -0,0 +1,8 @@ +#include "rmx1xx.dtsi" + +/ { + ddr0: memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; +}; diff --git a/boards/snps/nsim/arc_v/rmx1xx.dtsi b/boards/snps/nsim/arc_v/rmx1xx.dtsi new file mode 100644 index 00000000000000..9480922e2176d3 --- /dev/null +++ b/boards/snps/nsim/arc_v/rmx1xx.dtsi @@ -0,0 +1,55 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + timebase-frequency = <5000000>; + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "snps,av5rmx", "riscv"; + device_type = "cpu"; + reg = <0>; + clock-frequency = <5000000>; + riscv,isa = "rv32imac_zicsr_zifencei"; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + + soc { + compatible = "simple-bus"; + ranges; + interrupt-parent = <&clint>; + #address-cells = <1>; + #size-cells = <1>; + + clint: clint@2000000 { + compatible = "sifive,clint0"; + reg = <0x2000000 0x1000>; + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7>; + interrupt-names = "soft0", "timer0"; + }; + + uart0: serial@10000000{ + compatible = "ns16550", "snps,dw-apb-uart"; + reg = <0x10000000 0x400>; + reg-shift = <2>; + + /* AIA interrupt controller is not currently implemented, + * so connect UART interrupt to 17th line as a stub to + * make build system and test framework happy. + */ + interrupt-parent = <&cpu0_intc>; + interrupts = <17>; + clock-frequency = <50000000>; + status = "disabled"; + }; + }; +}; diff --git a/boards/snps/nsim/arc_v/support/rmx100.props b/boards/snps/nsim/arc_v/support/rmx100.props new file mode 100644 index 00000000000000..31aed21b49499c --- /dev/null +++ b/boards/snps/nsim/arc_v/support/rmx100.props @@ -0,0 +1,6 @@ + nsim_isa_family=rv32 + nsim_isa_ext=-all.i.zicsr.zifencei.zihintpause.a.m.zba.zbb.zbs.zca.zcb.zcmp.zcmt.zicbom + nsim_isa_big_endian=0 + nsim_mem-dev=clint,base=0x2000000,size=4096 + nsim_mem-dev=uart0,kind=16550,base=0x10000000,irq=24 + nsim_mem-dev=plic,base=0xc000000,size=0x04000000,interrupts=128,priorities=16 diff --git a/boards/st/b_l4s5i_iot01a/Kconfig.defconfig b/boards/st/b_l4s5i_iot01a/Kconfig.defconfig index 0000fc670f3ce7..317d096e0cea7d 100644 --- a/boards/st/b_l4s5i_iot01a/Kconfig.defconfig +++ b/boards/st/b_l4s5i_iot01a/Kconfig.defconfig @@ -27,9 +27,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts index 531c5a5b20d936..d41c75c44bf0d1 100644 --- a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts +++ b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts @@ -22,6 +22,7 @@ zephyr,code-partition = &slot0_partition; zephyr,flash-controller = &mx25r6435f; zephyr,bt-c2h-uart = &usart1; + zephyr,bt-hci = &hci_spi; }; leds { @@ -50,7 +51,6 @@ sw0 = &user_button; watchdog0 = &iwdg; accel0 = &lsm6dsl; - spi-flash0 = &mx25r6435f; }; }; @@ -152,7 +152,7 @@ cs-gpios = <&gpiod 13 GPIO_ACTIVE_LOW>, <&gpioe 0 GPIO_ACTIVE_LOW>; - spbtle-rf@0 { + hci_spi: spbtle-rf@0 { compatible = "st,hci-spi-v1"; reg = <0>; reset-gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; diff --git a/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi b/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi index 97fe4e0be57b7d..b3227455f6fc45 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi @@ -35,7 +35,6 @@ aliases { watchdog0 = &iwdg; - spi-flash0 = &mx25lm51245; die-temp0 = &die_temp; volt-sensor0 = &vref1; volt-sensor1 = &vbat4; diff --git a/boards/st/b_u585i_iot02a/b_u585i_iot02a.dts b/boards/st/b_u585i_iot02a/b_u585i_iot02a.dts index c2df9e5aa5af09..b452f4b3eba394 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a.dts +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a.dts @@ -19,7 +19,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; - zephyr,bt-uart=&uart4; + zephyr,bt-hci = &bt_hci_uart; }; aliases { @@ -81,4 +81,9 @@ pinctrl-names = "default"; current-speed = <100000>; status = "okay"; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; }; diff --git a/boards/st/disco_l475_iot1/Kconfig.defconfig b/boards/st/disco_l475_iot1/Kconfig.defconfig index b99f7c57511eb7..808425eae05693 100644 --- a/boards/st/disco_l475_iot1/Kconfig.defconfig +++ b/boards/st/disco_l475_iot1/Kconfig.defconfig @@ -27,9 +27,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/disco_l475_iot1/disco_l475_iot1.dts b/boards/st/disco_l475_iot1/disco_l475_iot1.dts index 572e8768c9e015..c57f9f01e91c02 100644 --- a/boards/st/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/st/disco_l475_iot1/disco_l475_iot1.dts @@ -22,6 +22,7 @@ zephyr,code-partition = &slot0_partition; zephyr,flash-controller = &mx25r6435f; zephyr,bt-c2h-uart = &usart1; + zephyr,bt-hci = &hci_spi; }; leds { @@ -67,7 +68,6 @@ sw0 = &user_button; eswifi0 = &wifi0; watchdog0 = &iwdg; - spi-flash0 = &mx25r6435f; accel0 = &lsm6dsl; volt-sensor0 = &vref; volt-sensor1 = &vbat; @@ -191,7 +191,7 @@ cs-gpios = <&gpiod 13 GPIO_ACTIVE_LOW>, <&gpioe 0 GPIO_ACTIVE_LOW>; - spbtle-rf@0 { + hci_spi: spbtle-rf@0 { compatible = "st,hci-spi-v1"; reg = <0>; reset-gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; diff --git a/boards/st/nucleo_f103rb/nucleo_f103rb.dts b/boards/st/nucleo_f103rb/nucleo_f103rb.dts index 1f225b4131263b..53b9089e554964 100644 --- a/boards/st/nucleo_f103rb/nucleo_f103rb.dts +++ b/boards/st/nucleo_f103rb/nucleo_f103rb.dts @@ -69,6 +69,7 @@ ahb-prescaler = <1>; apb1-prescaler = <2>; apb2-prescaler = <1>; + adc-prescaler = <2>; }; &usart1 { diff --git a/boards/st/nucleo_f303k8/nucleo_f303k8.dts b/boards/st/nucleo_f303k8/nucleo_f303k8.dts index 1090ae23ab27cb..efdf58a848fbef 100644 --- a/boards/st/nucleo_f303k8/nucleo_f303k8.dts +++ b/boards/st/nucleo_f303k8/nucleo_f303k8.dts @@ -63,6 +63,7 @@ ahb-prescaler = <1>; apb1-prescaler = <2>; apb2-prescaler = <1>; + adc12-prescaler = <0>; }; &timers2 { diff --git a/boards/st/nucleo_f303re/nucleo_f303re.dts b/boards/st/nucleo_f303re/nucleo_f303re.dts index af1bea6d92ac74..efa840c140ad45 100644 --- a/boards/st/nucleo_f303re/nucleo_f303re.dts +++ b/boards/st/nucleo_f303re/nucleo_f303re.dts @@ -69,6 +69,8 @@ ahb-prescaler = <1>; apb1-prescaler = <2>; apb2-prescaler = <1>; + adc12-prescaler = <0>; + adc34-prescaler = <0>; }; &usart2 { diff --git a/boards/st/nucleo_f413zh/nucleo_f413zh.yaml b/boards/st/nucleo_f413zh/nucleo_f413zh.yaml index 415b1d08f563cc..4a8dda323d2f61 100644 --- a/boards/st/nucleo_f413zh/nucleo_f413zh.yaml +++ b/boards/st/nucleo_f413zh/nucleo_f413zh.yaml @@ -17,5 +17,6 @@ supported: - spi - gpio - usb_device + - usbd - counter vendor: st diff --git a/boards/st/nucleo_g071rb/nucleo_g071rb.dts b/boards/st/nucleo_g071rb/nucleo_g071rb.dts index ba832c389cc399..9237cd779b0148 100644 --- a/boards/st/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/st/nucleo_g071rb/nucleo_g071rb.dts @@ -94,6 +94,10 @@ clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, <&rcc STM32_SRC_LSI RTC_SEL(2)>; status = "okay"; + + backup_regs { + status = "okay"; + }; }; &iwdg { diff --git a/boards/st/nucleo_h533re/Kconfig.nucleo_h533re b/boards/st/nucleo_h533re/Kconfig.nucleo_h533re new file mode 100644 index 00000000000000..3d48952fb5896e --- /dev/null +++ b/boards/st/nucleo_h533re/Kconfig.nucleo_h533re @@ -0,0 +1,5 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_H533RE + select SOC_STM32H533XX diff --git a/boards/st/nucleo_h533re/arduino_r3_connector.dtsi b/boards/st/nucleo_h533re/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..15bb1aab0bf5e8 --- /dev/null +++ b/boards/st/nucleo_h533re/arduino_r3_connector.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 0 0>, /* A0 */ + <1 0 &gpioa 1 0>, /* A1 */ + <2 0 &gpiob 1 0>, /* A2 */ + <3 0 &gpiob 0 0>, /* A3 */ + <4 0 &gpioc 1 0>, /* A4 */ + <5 0 &gpioc 0 0>, /* A5 */ + <6 0 &gpiob 15 0>, /* D0 */ + <7 0 &gpiob 14 0>, /* D1 */ + <8 0 &gpioc 8 0>, /* D2 */ + <9 0 &gpiob 3 0>, /* D3 */ + <10 0 &gpiob 5 0>, /* D4 */ + <11 0 &gpiob 4 0>, /* D5 */ + <12 0 &gpiob 10 0>, /* D6 */ + <13 0 &gpioa 8 0>, /* D7 */ + <14 0 &gpioc 7 0>, /* D8 */ + <15 0 &gpioc 6 0>, /* D9 */ + <16 0 &gpioc 9 0>, /* D10 */ + <17 0 &gpioa 7 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 7 0>, /* D14 */ + <21 0 &gpiob 6 0>; /* D15 */ + }; +}; + +arduino_serial: &usart1 {}; diff --git a/boards/st/nucleo_h533re/board.cmake b/boards/st/nucleo_h533re/board.cmake new file mode 100644 index 00000000000000..cec3a36c40362f --- /dev/null +++ b/boards/st/nucleo_h533re/board.cmake @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") + +board_runner_args(pyocd "--target=stm32h533retx") + +board_runner_args(jlink "--device=STM32H533RE" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/nucleo_h533re/board.yml b/boards/st/nucleo_h533re/board.yml new file mode 100644 index 00000000000000..4b633011b714a1 --- /dev/null +++ b/boards/st/nucleo_h533re/board.yml @@ -0,0 +1,5 @@ +board: + name: nucleo_h533re + vendor: st + socs: + - name: stm32h533xx diff --git a/boards/st/nucleo_h533re/doc/img/nucleo_h533re.jpg b/boards/st/nucleo_h533re/doc/img/nucleo_h533re.jpg new file mode 100644 index 00000000000000..aed4a9752f909c Binary files /dev/null and b/boards/st/nucleo_h533re/doc/img/nucleo_h533re.jpg differ diff --git a/boards/st/nucleo_h533re/doc/index.rst b/boards/st/nucleo_h533re/doc/index.rst new file mode 100644 index 00000000000000..b2ddb225e137f5 --- /dev/null +++ b/boards/st/nucleo_h533re/doc/index.rst @@ -0,0 +1,306 @@ +.. _nucleo_h533re_board: + +ST Nucleo H533RE +################ + +Overview +******** + +The Nucleo H533RE board is designed as an affordable development platform for +STMicroelectronics ARM |reg| Cortex |reg|-M33 core-based STM32H533RET6 +microcontroller with TrustZone |reg|. +Here are some highlights of the Nucleo H533RE board: + +- STM32H533RE microcontroller featuring 512 kbytes of Flash memory and 272 Kbytes of + SRAM in LQFP64 package + +- Board connectors: + + - USB Type-C |trade| Sink device FS + - ST Zio expansion connector including Arduino Uno V3 connectivity (CN5, CN6, CN8, CN9) + - ST morpho extension connector (CN7, CN10) + +- Flexible board power supply: + + - 5V_USB_STLK from ST-Link USB connector + - VIN (7 - 12V, 0.8) supplied via pin header CN6 pin 8 or CN7 pin 24 + - ESV on the ST morpho connector CN7 Pin 6 (5V, O.5A) + - VBUS_STLK from a USB charger via the ST-LINK USB connector + - VBUSC from the USB user connector (5V, 0.5A) + - 3V3_EXT supplied via a pin header CN6 pin 4 or CN7 pin 16 (3.3V, 1.3A) + +- On-board ST-LINK/V3EC debugger/programmer + + - mass storage + - Virtual COM port + - debug port + +- One user LED shared with ARDUINO |reg| Uno V3 +- Two push-buttons: USER and RESET +- 32.768 kHz crystal oscillator + +More information about the board can be found at the `NUCLEO_H533RE website`_. + +.. image:: img/nucleo_h533re.jpg + :align: center + :alt: NUCLEO H533RE + +Hardware +******** + +The STM32H533xx devices are high-performance microcontrollers from the STM32H5 +Series based on the high-performance Arm |reg| Cortex |reg|-M33 32-bit RISC core. +They operate at a frequency of up to 250 MHz. + +- Core: ARM |reg| 32-bit Cortex |reg| -M33 CPU with TrustZone |reg| and FPU. +- Performance benchmark: + + - 375 DMPIS/MHz (Dhrystone 2.1) + +- Security + + - Arm |reg| TrustZone |reg| with Armv8-M mainline security extension + - Up to eight configurable SAU regions + - TrustZone |reg| aware and securable peripherals + - Flexible life cycle scheme with secure debug authentication + - SESIP3 and PSA Level 3 certified assurance target + - Preconfigured immutable root of trust (ST-iROT) + - SFI (secure firmware installation) + - Root of trust thanks to unique boot entry and secure hide protection area (HDP) + - Secure data storage with hardware unique key (HUK) + - Secure firmware upgrade support with TF-M + - Two AES coprocessors including one with DPA resistance + - Public key accelerator, DPA resistant + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - True random number generator, NIST SP800-90B compliant + - 96-bit unique ID + - Active tampers + +- Clock management: + + - 24 MHz crystal oscillator (HSE) + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 64 MHz (HSI) trimmable by software + - Internal low-power 32 kHz RC (LSI)( |plusminus| 5%) + - Internal 4 MHz oscillator (CSI), trimmable by software + - Internal 48 MHz (HSI48) with recovery system + - 3 PLLs for system clock, USB, audio, ADC + +- Power management + + - Embedded regulator (LDO) with three configurable range output to supply the digital circuitry + - Embedded SMPS step-down converter + +- RTC with HW calendar, alarms and calibration +- Up to 112 fast I/Os, most 5 V-tolerant, up to 10 I/Os with independent supply down to 1.08 V +- Up to 16 timers and 2 watchdogs + + - 8x 16-bit + - 2x 32-bit timers with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input + - 2x 16-bit low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - 2x SysTick timer + +- Memories + + - Up to 512 Kbytes Flash, 2 banks read-while-write + - 1 Kbyte OTP (one-time programmable) + - 272 Kbytes of SRAM (80-Kbyte SRAM2 with ECC) + - 2 Kbytes of backup SRAM available in the lowest power modes + - Flexible external memory controller with up to 16-bit data bus: SRAM, PSRAM, FRAM, NOR/NAND memories + - 1x OCTOSPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 1x SD/SDIO/MMC interfaces + +- Rich analog peripherals (independent supply) + + - 2x 12-bit ADC with up to 5 MSPS in 12-bit + - 1x 12-bit DAC with 2 channels + - 1x Digital temperature sensor + - Voltage reference buffer + +- 34x communication interfaces + + - 1x USB Type-C / USB power-delivery controller + - 1x USB 2.0 full-speed host and device (crystal-less) + - 3x I2C FM+ interfaces (SMBus/PMBus) + - 2x I3C interface + - 6x U(S)ARTS (ISO7816 interface, LIN, IrDA, modem control) + - 1x LP UART + - 4x SPIs including 3 muxed with full-duplex I2S + - 4x additional SPI from 4x USART when configured in Synchronous mode + - 2x FDCAN + - 1x SDMMC interface + - 2x 16 channel DMA controllers + - 1x 8- to 14- bit camera interface + - 1x HDMI-CEC + - 1x 16-bit parallel slave synchronous-interface + +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| + +More information about STM32H533RE can be found here: + +- `STM32H533re on www.st.com`_ +- `STM32H533 reference manual`_ + +Supported Features +================== + +The Zephyr nucleo_h533re board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | PWM | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | Real Time Clock | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig and dts files: + +- Secure target: + + - :zephyr_file:`boards/st/nucleo_h533re/nucleo_h533re_defconfig` + - :zephyr_file:`boards/st/nucleo_h533re/nucleo_h533re.dts` + +Zephyr board options +==================== + +The STM32H533 is a SoC with Cortex-M33 architecture. Zephyr provides support +for building for Secure firmware. + +The BOARD options are summarized below: + ++----------------------+-----------------------------------------------+ +| BOARD | Description | ++======================+===============================================+ +| nucleo_h533re | For building Secure firmware | ++----------------------+-----------------------------------------------+ + +Connections and IOs +=================== + +Nucleo H533RE Board has 8 GPIO controllers. These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +For more details please refer to `STM32H5 Nucleo-64 board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- ADC1 channel 14 input: PB1 +- USART1 TX/RX : PB14/PB15 (Arduino USART1) +- SPI1 SCK/MISO/MOSI/NSS: PA5/PA6/PA7/PC9 +- UART2 TX/RX : PA2/PA3 (VCP) +- USER_PB : PC13 + +System Clock +------------ + +Nucleo H533RE System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +240MHz, driven by an 24MHz high-speed external clock. + +Serial Port +----------- + +Nucleo H533RE board has up to 6 U(S)ARTs. The Zephyr console output is assigned +to USART2. Default settings are 115200 8N1. + +Programming and Debugging +************************* + +Applications for the ``nucleo_h533re`` board can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +Nucleo H533RE board includes an ST-LINK/V3EC embedded debug tool interface. +This probe allows to flash the board using various tools. + +Board is configured to be flashed using west STM32CubeProgrammer runner. +Installation of `STM32CubeProgrammer`_ is then required to flash the board. + +Alternatively, pyocd or jlink via an external probe can also be used to flash +and debug the board if west is told to use it as runner, which can be done by +passing either or ``-r pyocd``, or ``-r jlink``. + +For pyocd additional target information needs to be installed. +This can be done by executing the following commands. + +.. code-block:: console + + $ pyocd pack --update + $ pyocd pack --install stm32h5 + + +Flashing an application to Nucleo H533RE +------------------------------------------ + +Connect the Nucleo H533RE to your host computer using the USB port. +Then build and flash an application. Here is an example for the +:ref:`hello_world` application. + +Run a serial host program to connect with your Nucleo board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then build and flash the application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h533re + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! nucleo_h533re + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_h533re + :goals: debug + +.. _NUCLEO_H533RE website: + https://www.st.com/en/evaluation-tools/nucleo-h533re + +.. _STM32H5 Nucleo-64 board User Manual: + https://www.st.com/resource/en/user_manual/um3121-stm32h5-nucleo64-board-mb1814-stmicroelectronics.pdf + +.. _STM32H533RE on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32h533re + +.. _STM32H533 reference manual: + https://www.st.com/resource/en/reference_manual/rm0481-stm32h533-stm32h563-stm32h573-and-stm32h562-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_h533re/nucleo_h533re.dts b/boards/st/nucleo_h533re/nucleo_h533re.dts new file mode 100644 index 00000000000000..7071a5e21a8fb1 --- /dev/null +++ b/boards/st/nucleo_h533re/nucleo_h533re.dts @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include "st_morpho_connector.dtsi" +#include + +/ { + model = "STMicroelectronics STM32H533RE-NUCLEO board"; + compatible = "st,stm32h533re-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram1; + zephyr,flash = &flash0; + }; + + leds: leds { + compatible = "gpio-leds"; + green_led_2: led_42 { + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + label = "User LD2"; + }; + }; + + + pwmleds { + compatible = "pwm-leds"; + + green_pwm_led: green_pwm_led { + pwms = <&pwm3 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led_2; + pwm-led0 = &green_pwm_led; + sw0 = &user_button; + watchdog0 = &iwdg; + volt-sensor0 = &vref; + }; +}; + +&clk_csi { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&pll { + div-m = <2>; + mul-n = <40>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb14 &usart1_rx_pb15>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&timers3 { + st,prescaler = <1000>; + status = "okay"; + + pwm3: pwm { + pinctrl-0 = <&tim3_ch3_pb0>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&vref { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00200000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; diff --git a/boards/st/nucleo_h533re/nucleo_h533re.yaml b/boards/st/nucleo_h533re/nucleo_h533re.yaml new file mode 100644 index 00000000000000..8262b95a843796 --- /dev/null +++ b/boards/st/nucleo_h533re/nucleo_h533re.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2024 +# SPDX-License-Identifier: Apache-2.0 + +identifier: nucleo_h533re +name: ST Nucleo H533RE +type: mcu +arch: arm +toolchain: + - zephyr +ram: 272 +flash: 512 +supported: + - gpio + - watchdog + - pwm + - rtc +vendor: st diff --git a/boards/st/nucleo_h533re/nucleo_h533re_defconfig b/boards/st/nucleo_h533re/nucleo_h533re_defconfig new file mode 100644 index 00000000000000..5b88c80b24fec2 --- /dev/null +++ b/boards/st/nucleo_h533re/nucleo_h533re_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +# enable uart driver +CONFIG_SERIAL=y + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable clock +CONFIG_CLOCK_CONTROL=y + +# enable GPIO +CONFIG_GPIO=y +# enable pin controller +CONFIG_PINCTRL=y diff --git a/boards/st/nucleo_h533re/st_morpho_connector.dtsi b/boards/st/nucleo_h533re/st_morpho_connector.dtsi new file mode 100644 index 00000000000000..ce3d7c84017381 --- /dev/null +++ b/boards/st/nucleo_h533re/st_morpho_connector.dtsi @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + st_morpho_header: st-morpho-header { + compatible = "st-morpho-header"; + #gpio-cells = <2>; + gpio-map-mask = ; + gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; + gpio-map = , + , + , + , + , /* SB40=ON, SB41=ON */ + , /* SB40=ON, SB41=ON */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + + , + , + , + , + , + , + , /* SB13=ON, SB17=ON */ + , + , /* SB13=ON, SB17=ON */ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; +}; diff --git a/boards/st/nucleo_h563zi/doc/index.rst b/boards/st/nucleo_h563zi/doc/index.rst index e707e81fefa559..ecb32665261100 100644 --- a/boards/st/nucleo_h563zi/doc/index.rst +++ b/boards/st/nucleo_h563zi/doc/index.rst @@ -150,6 +150,8 @@ The Zephyr nucleo_h563zi board configuration supports the following hardware fea +===========+============+=====================================+ | ADC | on-chip | ADC Controller | +-----------+------------+-------------------------------------+ +| CAN/CANFD | on-chip | CAN | ++-----------+------------+-------------------------------------+ | CLOCK | on-chip | reset and clock control | +-----------+------------+-------------------------------------+ | DAC | on-chip | DAC Controller | @@ -216,6 +218,7 @@ Default Zephyr Peripheral Mapping: - ADC1 channel 3 input: PA6 - ADC1 channel 15 input: PA3 - DAC1 channel 2 output: PA5 +- CAN/CANFD TX/RX: PD1/PD0 - LD1 (green): PB0 - LD2 (yellow): PF4 - LD3 (red): PG4 diff --git a/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi b/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi index 4d37501620885a..030bab86a0cb28 100644 --- a/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi +++ b/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi @@ -66,7 +66,7 @@ div-m = <2>; mul-n = <120>; div-p = <2>; - div-q = <2>; + div-q = <3>; div-r = <2>; clocks = <&clk_hse>; status = "okay"; @@ -152,6 +152,15 @@ status = "okay"; }; +&fdcan1 { + pinctrl-0 = <&fdcan1_rx_pd0 &fdcan1_tx_pd1>; + pinctrl-names = "default"; + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>, + <&rcc STM32_SRC_PLL1_Q FDCAN_SEL(1)>; + clk-divider = <2>; + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/st/nucleo_h563zi/nucleo_h563zi.dts b/boards/st/nucleo_h563zi/nucleo_h563zi.dts index 915a0ddee60469..8acb70d0e6c42a 100644 --- a/boards/st/nucleo_h563zi/nucleo_h563zi.dts +++ b/boards/st/nucleo_h563zi/nucleo_h563zi.dts @@ -22,6 +22,7 @@ zephyr,sram = &sram1; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,canbus = &fdcan1; }; aliases { diff --git a/boards/st/nucleo_h563zi/nucleo_h563zi.yaml b/boards/st/nucleo_h563zi/nucleo_h563zi.yaml index 0130798df9dd0f..2b7c314c976439 100644 --- a/boards/st/nucleo_h563zi/nucleo_h563zi.yaml +++ b/boards/st/nucleo_h563zi/nucleo_h563zi.yaml @@ -11,12 +11,14 @@ supported: - gpio - arduino_serial - arduino_spi + - can - gpio - uart - entropy - adc - dac - pwm + - netif:eth - counter - spi - usb_device diff --git a/boards/st/nucleo_h743zi/nucleo_h743zi.dts b/boards/st/nucleo_h743zi/nucleo_h743zi.dts index f410d6f956e9d4..6e5a80b4593109 100644 --- a/boards/st/nucleo_h743zi/nucleo_h743zi.dts +++ b/boards/st/nucleo_h743zi/nucleo_h743zi.dts @@ -80,10 +80,10 @@ }; &pll { - div-m = <1>; - mul-n = <24>; + div-m = <2>; + mul-n = <240>; div-p = <2>; - div-q = <4>; + div-q = <2>; div-r = <2>; clocks = <&clk_hse>; status = "okay"; @@ -91,13 +91,13 @@ &rcc { clocks = <&pll>; - clock-frequency = ; + clock-frequency = ; d1cpre = <1>; - hpre = <1>; - d1ppre = <1>; - d2ppre1 = <1>; - d2ppre2 = <1>; - d3ppre = <1>; + hpre = <2>; + d1ppre = <2>; + d2ppre1 = <2>; + d2ppre2 = <2>; + d3ppre = <2>; }; &usart3 { diff --git a/boards/st/nucleo_h753zi/nucleo_h753zi.dts b/boards/st/nucleo_h753zi/nucleo_h753zi.dts index e3b52c2b50cfe8..2a2d68b4001569 100644 --- a/boards/st/nucleo_h753zi/nucleo_h753zi.dts +++ b/boards/st/nucleo_h753zi/nucleo_h753zi.dts @@ -77,10 +77,10 @@ }; &pll { - div-m = <1>; - mul-n = <24>; + div-m = <2>; + mul-n = <240>; div-p = <2>; - div-q = <4>; + div-q = <2>; div-r = <2>; clocks = <&clk_hse>; status = "okay"; @@ -88,13 +88,13 @@ &rcc { clocks = <&pll>; - clock-frequency = ; + clock-frequency = ; d1cpre = <1>; - hpre = <1>; - d1ppre = <1>; - d2ppre1 = <1>; - d2ppre2 = <1>; - d3ppre = <1>; + hpre = <2>; + d1ppre = <2>; + d2ppre1 = <2>; + d2ppre2 = <2>; + d3ppre = <2>; }; &usart3 { diff --git a/boards/st/nucleo_wb55rg/Kconfig.defconfig b/boards/st/nucleo_wb55rg/Kconfig.defconfig index a4822901739803..cd63e8d080e014 100644 --- a/boards/st/nucleo_wb55rg/Kconfig.defconfig +++ b/boards/st/nucleo_wb55rg/Kconfig.defconfig @@ -5,9 +5,8 @@ if BOARD_NUCLEO_WB55RG -choice BT_HCI_BUS_TYPE - default BT_STM32_IPM +config BT_STM32_IPM + default y depends on BT -endchoice endif diff --git a/boards/st/sensortile_box/Kconfig.defconfig b/boards/st/sensortile_box/Kconfig.defconfig index 8e3f0bb167041f..faa5dc0864c4d4 100644 --- a/boards/st/sensortile_box/Kconfig.defconfig +++ b/boards/st/sensortile_box/Kconfig.defconfig @@ -10,9 +10,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/sensortile_box/sensortile_box.dts b/boards/st/sensortile_box/sensortile_box.dts index 102dbb6a73a73f..70a0b4f9007012 100644 --- a/boards/st/sensortile_box/sensortile_box.dts +++ b/boards/st/sensortile_box/sensortile_box.dts @@ -19,6 +19,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,bt-c2h-uart = &usart1; + zephyr,bt-hci = &spbtle_1s_sensortile_box; }; leds { diff --git a/boards/st/sensortile_box_pro/Kconfig.defconfig b/boards/st/sensortile_box_pro/Kconfig.defconfig index f0271728a9a3e3..caa346b0075406 100644 --- a/boards/st/sensortile_box_pro/Kconfig.defconfig +++ b/boards/st/sensortile_box_pro/Kconfig.defconfig @@ -10,9 +10,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/sensortile_box_pro/sensortile_box_pro.dts b/boards/st/sensortile_box_pro/sensortile_box_pro.dts index 8bd870151a574f..06185c32d40a3a 100644 --- a/boards/st/sensortile_box_pro/sensortile_box_pro.dts +++ b/boards/st/sensortile_box_pro/sensortile_box_pro.dts @@ -29,6 +29,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &hci_spi; }; leds { @@ -163,7 +164,7 @@ stm32_lp_tick_source: &lptim1 { cs-gpios = <&gpioa 2 GPIO_ACTIVE_LOW>; status = "okay"; - bluenrg-lp@0 { + hci_spi: bluenrg-lp@0 { compatible = "st,hci-spi-v2"; reg = <0>; irq-gpios = <&gpiod 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; diff --git a/boards/st/steval_stwinbx1/Kconfig.defconfig b/boards/st/steval_stwinbx1/Kconfig.defconfig index f10fea5e293b88..594ebede5a70ff 100644 --- a/boards/st/steval_stwinbx1/Kconfig.defconfig +++ b/boards/st/steval_stwinbx1/Kconfig.defconfig @@ -10,9 +10,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/steval_stwinbx1/steval_stwinbx1.dts b/boards/st/steval_stwinbx1/steval_stwinbx1.dts index 23eda67338aeca..4debd8cc5c19c0 100644 --- a/boards/st/steval_stwinbx1/steval_stwinbx1.dts +++ b/boards/st/steval_stwinbx1/steval_stwinbx1.dts @@ -32,6 +32,8 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + + zephyr,bt-hci = &hci_spi; }; leds { @@ -164,7 +166,7 @@ stm32_lp_tick_source: &lptim1 { pinctrl-names = "default"; status = "okay"; cs-gpios = <&gpioe 1 GPIO_ACTIVE_LOW>; - bluenrg-2@0 { + hci_spi: bluenrg-2@0 { compatible = "st,hci-spi-v2"; reg = <0>; reset-gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; diff --git a/boards/st/stm32c0116_dk/stm32c0116_dk.dts b/boards/st/stm32c0116_dk/stm32c0116_dk.dts index f9791268886a9b..79b4db1fa25834 100644 --- a/boards/st/stm32c0116_dk/stm32c0116_dk.dts +++ b/boards/st/stm32c0116_dk/stm32c0116_dk.dts @@ -53,7 +53,7 @@ select_key { press-thresholds-mv = <0>; - zephyr,code = ; + zephyr,code = ; }; left_key { diff --git a/boards/st/stm32f723e_disco/stm32f723e_disco.dts b/boards/st/stm32f723e_disco/stm32f723e_disco.dts index 4c6641c7f2c75e..a9ca03675df184 100644 --- a/boards/st/stm32f723e_disco/stm32f723e_disco.dts +++ b/boards/st/stm32f723e_disco/stm32f723e_disco.dts @@ -52,7 +52,6 @@ led1 = &red_led; led2 = &green_led; sw0 = &user_button; - spi-flash0 = &mx25r512; }; }; diff --git a/boards/st/stm32f723e_disco/stm32f723e_disco.yaml b/boards/st/stm32f723e_disco/stm32f723e_disco.yaml index d8f5b1a14a7f44..1908ae26279a79 100644 --- a/boards/st/stm32f723e_disco/stm32f723e_disco.yaml +++ b/boards/st/stm32f723e_disco/stm32f723e_disco.yaml @@ -16,4 +16,5 @@ supported: - spi - arduino_spi - usb_device + - usbd vendor: st diff --git a/boards/st/stm32f746g_disco/stm32f746g_disco.dts b/boards/st/stm32f746g_disco/stm32f746g_disco.dts index 6250c4e8e80d8a..2c31fef1c92c42 100644 --- a/boards/st/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/st/stm32f746g_disco/stm32f746g_disco.dts @@ -59,7 +59,6 @@ aliases { led0 = &green_led_1; sw0 = &user_button; - spi-flash0 = &n25q128a1; }; }; diff --git a/boards/st/stm32f7508_dk/stm32f7508_dk.dts b/boards/st/stm32f7508_dk/stm32f7508_dk.dts index b98cf5aeed9e4c..100fd6e661d9b5 100644 --- a/boards/st/stm32f7508_dk/stm32f7508_dk.dts +++ b/boards/st/stm32f7508_dk/stm32f7508_dk.dts @@ -59,7 +59,6 @@ aliases { led0 = &green_led_1; sw0 = &user_button; - spi-flash0 = &n25q128a1; }; }; diff --git a/boards/st/stm32f769i_disco/stm32f769i_disco.dts b/boards/st/stm32f769i_disco/stm32f769i_disco.dts index 03ff90c729baaf..9ad4f4ef3bc57a 100644 --- a/boards/st/stm32f769i_disco/stm32f769i_disco.dts +++ b/boards/st/stm32f769i_disco/stm32f769i_disco.dts @@ -77,7 +77,6 @@ led2 = &green_led_3; led3 = &red_led_4; sw0 = &user_button; - spi-flash0 = &mx25l51245g; }; quadspi_memory_avail: memory-avail@90000000 { diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk.dts b/boards/st/stm32h573i_dk/stm32h573i_dk.dts index 721cea3ab6aeb8..a02d042e25d4c7 100644 --- a/boards/st/stm32h573i_dk/stm32h573i_dk.dts +++ b/boards/st/stm32h573i_dk/stm32h573i_dk.dts @@ -56,7 +56,6 @@ led0 = &blue_led_0; sw0 = &user_button; watchdog0 = &iwdg; - spi-flash0 = &mx25lm51245; die-temp0 = &die_temp; volt-sensor0 = &vref; volt-sensor1 = &vbat; diff --git a/boards/st/stm32h745i_disco/board.cmake b/boards/st/stm32h745i_disco/board.cmake index 699e51ae5959fc..94731b3e0f9969 100644 --- a/boards/st/stm32h745i_disco/board.cmake +++ b/boards/st/stm32h745i_disco/board.cmake @@ -8,8 +8,15 @@ board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) elseif(CONFIG_BOARD_STM32H745I_DISCO_STM32H745XX_M4) board_runner_args(openocd --target-handle=_CHIPNAME.cpu1) endif() + +if(CONFIG_STM32_MEMMAP) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--hex-file=${ZEPHYR_BASE}/build/zephyr/zephyr.hex") +board_runner_args(stm32cubeprogrammer "--extload=MT25TL01G_STM32H745I-DISCO.stldr") +else() board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +endif() -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/stm32h745i_disco/doc/index.rst b/boards/st/stm32h745i_disco/doc/index.rst index 0b74a8903d0d3f..4a17b24f16f2ad 100644 --- a/boards/st/stm32h745i_disco/doc/index.rst +++ b/boards/st/stm32h745i_disco/doc/index.rst @@ -102,7 +102,7 @@ The current Zephyr stm32h745i_disco board configuration supports the following h Other hardware features are not yet supported on this Zephyr port. The default configuration per core can be found in the defconfig files: -:zephyr_file:`boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7_defconfig`` and +:zephyr_file:`boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7_defconfig` and :zephyr_file:`boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m4_defconfig` For more details please refer to `STM32H745-Disco UM`_. diff --git a/boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7.dts b/boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7.dts index eb33539d8799c7..09b8177b7c449c 100644 --- a/boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7.dts +++ b/boards/st/stm32h745i_disco/stm32h745i_disco_stm32h745xx_m7.dts @@ -42,10 +42,19 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; + ext_memory: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + aliases { led0 = &green_led; pwm-led0 = &green_pwm_led; sw0 = &user_button; + spi-flash0 = &mt25ql512ab1; }; }; @@ -167,7 +176,7 @@ &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3 >; - flash-id = <1>; + dual-flash; status = "okay"; mt25ql512ab1: qspi-nor-flash-1@90000000 { diff --git a/boards/st/stm32h747i_disco/board.cmake b/boards/st/stm32h747i_disco/board.cmake index 93b40d3634d376..288e16557cfd62 100644 --- a/boards/st/stm32h747i_disco/board.cmake +++ b/boards/st/stm32h747i_disco/board.cmake @@ -10,8 +10,15 @@ elseif(CONFIG_BOARD_STM32H747I_DISCO_STM32H747XX_M4) board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd_stm32h747i_disco_m4.cfg") board_runner_args(openocd --target-handle=_CHIPNAME.cpu1) endif() + +if(CONFIG_STM32_MEMMAP) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--hex-file=${ZEPHYR_BASE}/build/zephyr/zephyr.hex") +board_runner_args(stm32cubeprogrammer "--extload=MT25TL01G_STM32H747I-DISCO.stldr") +else() board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +endif() -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts index a660f92af1772a..f1de8789781d63 100644 --- a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts +++ b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.dts @@ -31,6 +31,14 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; + ext_memory: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + leds { green_led_1:led_1 { status = "okay"; @@ -55,7 +63,6 @@ led0 = &green_led_1; led1 = &orange_led_2; sw0 = &wake_up; - spi-flash0 = &mt25ql512ab1; }; }; @@ -240,6 +247,7 @@ zephyr_udc0: &usbotg_hs { &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3 &quadspi_bk2_io2_pg9 &quadspi_bk2_io3_pg14>; pinctrl-names = "default"; + dual-flash; status = "okay"; mt25ql512ab1: qspi-nor-flash-1@90000000 { diff --git a/boards/st/stm32h750b_dk/board.cmake b/boards/st/stm32h750b_dk/board.cmake index 6500e7b1a4a914..56e0e8df96a2ab 100644 --- a/boards/st/stm32h750b_dk/board.cmake +++ b/boards/st/stm32h750b_dk/board.cmake @@ -3,5 +3,14 @@ board_runner_args(jlink "--device=STM32H735IG" "--speed=4000") board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) +if(CONFIG_STM32_MEMMAP) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(stm32cubeprogrammer "--hex-file=${ZEPHYR_BASE}/build/zephyr/zephyr.hex") +board_runner_args(stm32cubeprogrammer "--extload=MT25TL01G_STM32H750B-DISCO.stldr") +else() +board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw" ) +endif() + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk.dts b/boards/st/stm32h750b_dk/stm32h750b_dk.dts index bb90724deadcb7..ad0ecf065f3a42 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk.dts +++ b/boards/st/stm32h750b_dk/stm32h750b_dk.dts @@ -29,6 +29,14 @@ zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; }; + ext_memory: memory@90000000 { + compatible = "zephyr,memory-region"; + reg = <0x90000000 DT_SIZE_M(256)>; /* max addressable area */ + zephyr,memory-region = "EXTMEM"; + /* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */ + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; + }; + leds { compatible = "gpio-leds"; red_led: led_1 { @@ -54,7 +62,6 @@ led0 = &green_led; led1 = &red_led; sw0 = &user_button; - spi-flash0 = &mt25ql512ab1; }; }; @@ -103,7 +110,7 @@ &quadspi_bk1_io2_pf7 &quadspi_bk1_io3_pf6 &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3 &quadspi_bk2_io2_pg9 &quadspi_bk2_io3_pg14>; - flash-id = <1>; + dual-flash; status = "okay"; mt25ql512ab1: qspi-nor-flash-1@90000000 { diff --git a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts index f05809f523ba5b..95325e254b5578 100644 --- a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -78,7 +78,6 @@ led0 = &blue_led; led1 = &red_led; sw0 = &user_button; - spi-flash0 = &mx25lm51245; }; }; diff --git a/boards/st/stm32h7s78_dk/Kconfig.defconfig b/boards/st/stm32h7s78_dk/Kconfig.defconfig new file mode 100644 index 00000000000000..d8a0c6ecdcd501 --- /dev/null +++ b/boards/st/stm32h7s78_dk/Kconfig.defconfig @@ -0,0 +1,17 @@ +# STM32H7S78 DISCOVERY KIT board configuration +# +# Copyright (c) 2024 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +if BOARD_STM32H7S78_DK + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_STM32H7S78_DK diff --git a/boards/st/stm32h7s78_dk/Kconfig.stm32h7s78_dk b/boards/st/stm32h7s78_dk/Kconfig.stm32h7s78_dk new file mode 100644 index 00000000000000..d3c5737a289336 --- /dev/null +++ b/boards/st/stm32h7s78_dk/Kconfig.stm32h7s78_dk @@ -0,0 +1,9 @@ +# STM32H7S78-DK Discovery kit board configuration +# +# Copyright (c) 2024 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +config BOARD_STM32H7S78_DK + select SOC_STM32H7S7XX diff --git a/boards/st/stm32h7s78_dk/arduino_r3_connector.dtsi b/boards/st/stm32h7s78_dk/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..c1d06e17bc13ef --- /dev/null +++ b/boards/st/stm32h7s78_dk/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioc 0 0>, /* A0 */ + <1 0 &gpioc 2 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpiof 12 0>, /* A3 */ + <4 0 &gpiof 13 0>, /* A4 */ + <5 0 &gpioc 1 0>, /* A5 */ + <6 0 &gpioe 7 0>, /* D0 */ + <7 0 &gpioe 8 0>, /* D1 */ + <8 0 &gpiof 1 0>, /* D2 */ + <9 0 &gpiod 12 0>, /* D3 */ + <10 0 &gpiof 2 0>, /* D4 */ + <11 0 &gpiod 13 0>, /* D5 */ + <12 0 &gpiod 15 0>, /* D6 */ + <13 0 &gpiof 3 0>, /* D7 */ + <14 0 &gpiof 4 0>, /* D8 */ + <15 0 &gpiof 6 0>, /* D9 */ + <16 0 &gpiof 8 0>, /* D10 */ + <17 0 &gpioe 14 0>, /* D11 */ + <18 0 &gpioe 13 0>, /* D12 */ + <19 0 &gpioe 12 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 6 0>; /* D15 */ + }; +}; + +arduino_spi: &spi4 {}; +arduino_i2c: &i2c1 {}; diff --git a/boards/st/stm32h7s78_dk/board.cmake b/boards/st/stm32h7s78_dk/board.cmake new file mode 100644 index 00000000000000..04b6ed24de4607 --- /dev/null +++ b/boards/st/stm32h7s78_dk/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(stm32cubeprogrammer "--erase" "--port=swd" "--reset-mode=hw") +board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +# FIXME: openocd runner not yet available. +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/st/stm32h7s78_dk/board.yml b/boards/st/stm32h7s78_dk/board.yml new file mode 100644 index 00000000000000..c17be71480c2dd --- /dev/null +++ b/boards/st/stm32h7s78_dk/board.yml @@ -0,0 +1,5 @@ +board: + name: stm32h7s78_dk + vendor: st + socs: + - name: stm32h7s7xx diff --git a/boards/st/stm32h7s78_dk/doc/img/stm32h7s78_dk.jpg b/boards/st/stm32h7s78_dk/doc/img/stm32h7s78_dk.jpg new file mode 100644 index 00000000000000..523ff89970c715 Binary files /dev/null and b/boards/st/stm32h7s78_dk/doc/img/stm32h7s78_dk.jpg differ diff --git a/boards/st/stm32h7s78_dk/doc/index.rst b/boards/st/stm32h7s78_dk/doc/index.rst new file mode 100644 index 00000000000000..3cea4994c779c9 --- /dev/null +++ b/boards/st/stm32h7s78_dk/doc/index.rst @@ -0,0 +1,300 @@ +.. _stm32h7s78_dk_board: + +ST STM32H7S78-DK Discovery +########################## + +Overview +******** + +The STM32H7S78-DK Discovery kit is designed as a complete demonstration and +development platform for STMicroelectronics Arm |reg| Cortex |reg|-M7 core-based +STM32H7S7L8H6H microcontroller with TrustZone |reg|. Here are some highlights of +the STM32H7S78-DK Discovery board: + + +- STM32H7S7L8H6H microcontroller featuring 64Kbytes of Flash memory and 620 Kbytes of SRAM in 225-pin TFBGA package +- USB Type-C |trade| Host and device with USB power-delivery controller +- SAI Audio DAC stereo with one audio jacks for input/output, +- ST MEMS digital microphone with PDM interface +- Octo-SPI interface connected to 512Mbit Octo-SPI NORFlash memory device (MX66UW1G45GXD100 from MACRONIX) +- 10/100-Mbit Ethernet, + +- Board connectors + + - STMod+ expansion connector with fan-out expansion board for Wi‑Fi |reg|, Grove and mikroBUS |trade| compatible connectors + - Pmod |trade| expansion connector + - Audio MEMS daughterboard expansion connector + - ARDUINO |reg| Uno V3 expansion connector + +- Flexible power-supply options + + - ST-LINK + - USB VBUS + - external sources + +- On-board STLINK-V3E debugger/programmer with USB re-enumeration capability: + + - mass storage + - Virtual COM port + - debug port + +- 4 user LEDs +- User and reset push-buttons + +.. image:: img/stm32h7s78_dk.jpg + :align: center + :alt: STM32H7S78-DK Discovery + +More information about the board can be found at the `STM32H7S78-DK Discovery website`_. + +Hardware +******** + +The STM32H7S7xx devices are a high-performance microcontrollers family (STM32H7 +Series) based on the high-performance Arm |reg| Cortex |reg|-M7 32-bit RISC core. +They operate at a frequency of up to 500 MHz. + +- Core: ARM |reg| 32-bit Cortex |reg| -M7 CPU with TrustZone |reg| and FPU. +- Performance benchmark: + + - 1284 DMPIS/MHz (Dhrystone 2.1) + +- Security + + - Arm |reg| TrustZone |reg| with ARMv8-M mainline security extension + - Up to 8 configurable SAU regions + - TrustZone |reg| aware and securable peripherals + - Flexible lifecycle scheme with secure debug authentication + - Preconfigured immutable root of trust (ST-iROT) + - SFI (secure firmware installation) + - Secure data storage with hardware unique key (HUK) + - Secure firmware upgrade support with TF-M + - 2x AES coprocessors including one with DPA resistance + - Public key accelerator, DPA resistant + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - True random number generator, NIST SP800-90B compliant + - 96-bit unique ID + - Active tampers + - True Random Number Generator (RNG) NIST SP800-90B compliant + +- Clock management: + + - 24 MHz crystal oscillator (HSE) + - 32768 Hz crystal oscillator for RTC (LSE) + - Internal 64 MHz (HSI) trimmable by software + - Internal low-power 32 kHz RC (LSI)( |plusminus| 5%) + - Internal 4 MHz oscillator (CSI), trimmable by software + - Internal 48 MHz (HSI48) with recovery system + - 3 PLLs for system clock, USB, audio, ADC + +- Power management + + - Embedded regulator (LDO) with three configurable range output to supply the digital circuitry + - Embedded SMPS step-down converter + +- RTC with HW calendar, alarms and calibration +- Up to 152 fast I/Os, most 5 V-tolerant, up to 10 I/Os with independent supply down to 1.08 V +- Up to 16 timers and 2 watchdogs + + - 16x 16-bit + - 4x 32-bit timers with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input + - 5x 16-bit low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - 1x SysTick timer + +- Memories + + - Up to 64KB Flash, 2 banks read-while-write + - 1 Kbyte OTP (one-time programmable) + - 640 KB of SRAM including 64 KB with hardware parity check and 320 Kbytes with flexible ECC + - 4 Kbytes of backup SRAM available in the lowest power modes + - Flexible external memory controller with up to 16-bit data bus: SRAM, PSRAM, FRAM, SDRAM/LPSDR SDRAM, NOR/NAND memories + - 2x OCTOSPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 1x HEXASPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 2x SD/SDIO/MMC interfaces + +- Rich analog peripherals (independent supply) + + - 2x 12-bit ADC with up to 5 MSPS in 12-bit + - 1x Digital temperature sensor + +- 35x communication interfaces + + - 1x USB Type-C / USB power-delivery controller + - 1x USB OTG full-speed with PHY + - 1x USB OTG high-speed with PHY + - 3x I2C FM+ interfaces (SMBus/PMBus) + - 1x I3C interface + - 7x U(S)ARTS (ISO7816 interface, LIN, IrDA, modem control) + - 2x LP UART + - 6x SPIs including 3 muxed with full-duplex I2S + - 2x SAI + - 2x FDCAN + - 2x SD/SDIO/MMC interface + - 2x 16 channel DMA controllers + - 1x 8- to 16- bit camera interface + - 1x HDMI-CEC + - 1x Ethernel MAC interface with DMA controller + - 1x 16-bit parallel slave synchronous-interface + - 1x SPDIF-IN interface + - 1x MDIO slave interface + +- CORDIC for trigonometric functions acceleration +- FMAC (filter mathematical accelerator) +- CRC calculation unit +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| + + +More information about STM32H7S7 can be found here: + +- `STM32H7Sx on www.st.com`_ +- `STM32H7Sx reference manual`_ + +Supported Features +================== + +The Zephyr STM32H7S78_DK board configuration supports the following +hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi bus | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig and dts files: + +- Secure target: + + - :zephyr_file:`boards/st/stm32h7s78_dk/stm32h7s78_dk_defconfig` + - :zephyr_file:`boards/st/stm32h7s78_dk/stm32h7s78_dk.dts` + +Zephyr board options +==================== + +The STM32HS7 is a SoC with Cortex-M7 architecture. Zephyr provides support +for building for Secure firmware. + +The BOARD options are summarized below: + ++----------------------+-----------------------------------------------+ +| BOARD | Description | ++======================+===============================================+ +| stm32h7s78_dk | For building Secure firmware | ++----------------------+-----------------------------------------------+ + +Connections and IOs +=================== + +STM32H7S78-DK Discovery Board has 12 GPIO controllers. These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +For more details please refer to `STM32H7S78-DK Discovery board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- USART_4 TX/RX : PD1/PD0 (VCP) +- USART_7 TX/RX : PE8/PE7 (Arduino USART7) +- USER_PB : PC13 +- LD1 (green) : PO1 +- LD2 (orange) : PO5 +- LD3 (red) : PM2 +- LD4 (blue) : PM3 +- ADC1 channel 6 input : PF12 + +System Clock +------------ + +STM32H7S78-DK System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +500MHz, driven by 24MHz external oscillator (HSE). + +Serial Port +----------- + +STM32H7S78-DK Discovery board has 2 U(S)ARTs. The Zephyr console output is +assigned to USART4. Default settings are 115200 8N1. + + +Programming and Debugging +************************* + +Applications for the ``stm32h7s78_dk`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +STM32H7S78-DK Discovery board includes an ST-LINK/V3E embedded debug tool +interface. Support is available on STM32CubeProgrammer V2.13.0. + +Alternatively, this interface will be supported by a next openocd version. + +Flashing an application to STM32H7S78-DK Discovery +-------------------------------------------------- + +Connect the STM32H7S78-DK Discovery to your host computer using the USB port. +Then build and flash an application. Here is an example for the +:ref:`hello_world` application. + +Run a serial host program to connect with your Nucleo board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then build and flash the application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32h7s78_dk + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! stm32h7s78_dk + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32h7s78_dk + :maybe-skip-config: + :goals: debug + +.. _STM32H7S78-DK Discovery website: + https://www.st.com/en/evaluation-tools/stm32h7s78-dk.html + +.. _STM32H7S78-DK Discovery board User Manual: + https://www.st.com/en/evaluation-tools/stm32h7s78-dk.html + +.. _STM32H7Sx on www.st.com: + https://www.st.com/en/evaluation-tools/stm32h7s78-dk.html + +.. _STM32H7Sx reference manual: + https://www.st.com/resource/en/reference_manual/rm0477-stm32h7rx7sx-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/stm32h7s78_dk/stm32h7s78.yaml b/boards/st/stm32h7s78_dk/stm32h7s78.yaml new file mode 100644 index 00000000000000..16df86085ca4c0 --- /dev/null +++ b/boards/st/stm32h7s78_dk/stm32h7s78.yaml @@ -0,0 +1,13 @@ +identifier: stm32h7s78_dk +name: ST STM32H7S78 Discovery Kit +type: mcu +arch: arm +toolchain: + - zephyr +ram: 640 +flash: 64 +supported: + - arduino_gpio + - gpio + - uart +vendor: st diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts b/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts new file mode 100644 index 00000000000000..d8bb4444b184a3 --- /dev/null +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + model = "STMicroelectronics STM32H7S78 DISCOVERY KIT board"; + compatible = "st,stm32h7s78-dk"; + + chosen { + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + zephyr,flash = &flash0; + zephyr,sram = &sram0; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_1 { + gpios = <&gpioo 1 GPIO_ACTIVE_LOW>; + label = "User LD1"; + }; + orange_led: led_2 { + gpios = <&gpioo 5 GPIO_ACTIVE_LOW>; + label = "User LD2"; + }; + red_led: led_3 { + gpios = <&gpiom 2 GPIO_ACTIVE_LOW>; + label = "User LD3"; + }; + blue_led: led_4 { + gpios = <&gpiom 3 GPIO_ACTIVE_LOW>; + label = "User LD4"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &blue_led; + sw0 = &user_button; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + hse-bypass; /* X3 is a 24MHz oscillator on PH0 */ + status = "okay"; +}; + +&pll { + div-m = <12>; + mul-n = <250>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + div-s = <2>; + div-t = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + dcpre = <1>; + hpre = <1>; + ppre1 = <2>; + ppre2 = <2>; + ppre4 = <2>; + ppre5 = <2>; +}; + +&uart4 { + pinctrl-0 = <&uart4_tx_pd1 &uart4_rx_pd0>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&uart7 { + pinctrl-0 = <&uart7_tx_pe8 &uart7_rx_pe7>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&timers2 { + st,prescaler = <10000>; + status = "okay"; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch4_pa3>; + pinctrl-names = "default"; + }; +}; + +&timers3 { + st,prescaler = <10000>; + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch2_pb5>; + pinctrl-names = "default"; + }; +}; + +&spi4 { + pinctrl-0 = <&spi4_nss_pe4 &spi4_sck_pe12 + &spi4_miso_pe13 &spi4_mosi_pe14>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb9>; + pinctrl-names = "default"; +}; diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk_defconfig b/boards/st/stm32h7s78_dk/stm32h7s78_dk_defconfig new file mode 100644 index 00000000000000..d8caa7276387a6 --- /dev/null +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk_defconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# Enable SMPS +CONFIG_POWER_SUPPLY_DIRECT_SMPS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable uart driver +CONFIG_SERIAL=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable Clocks +CONFIG_CLOCK_CONTROL=y + +# enable pin controller +CONFIG_PINCTRL=y diff --git a/boards/st/stm32h7s78_dk/support/openocd.cfg b/boards/st/stm32h7s78_dk/support/openocd.cfg new file mode 100644 index 00000000000000..b32c9f26c2ca24 --- /dev/null +++ b/boards/st/stm32h7s78_dk/support/openocd.cfg @@ -0,0 +1,41 @@ +source [find interface/stlink-dap.cfg] +transport select "dapdirect_swd" + +set WORKAREASIZE 0x8000 +set CHIPNAME STM32H7S7XX +set BOARDNAME STM32H7S78_DK + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +# reset_config srst_only srst_nogate connect_assert_srst + +#set CONNECT_UNDER_RESET 1 +#set CORE_RESET 0 + +source [find target/stm32h7rx.cfg] + + +$_CHIPNAME.cpu0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + gdb_breakpoint_override hard +} + +$_CHIPNAME.cpu0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/st/stm32l496g_disco/stm32l496g_disco.dts b/boards/st/stm32l496g_disco/stm32l496g_disco.dts index e2a70f6163d523..a6d1e876f4e81c 100644 --- a/boards/st/stm32l496g_disco/stm32l496g_disco.dts +++ b/boards/st/stm32l496g_disco/stm32l496g_disco.dts @@ -68,7 +68,6 @@ sw4 = &joy_left; volt-sensor0 = &vref; volt-sensor1 = &vbat; - spi-flash0 = &mx25r6435; }; }; diff --git a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts index 3d54fbc3cdf626..49737c68c8f56a 100644 --- a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts +++ b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts @@ -44,7 +44,6 @@ die-temp0 = &die_temp; volt-sensor0 = &vref; volt-sensor1 = &vbat; - spi-flash0 = &mx25lm51245; }; }; diff --git a/boards/st/stm32l562e_dk/Kconfig.defconfig b/boards/st/stm32l562e_dk/Kconfig.defconfig index 5dea5bc3a74180..ed9a04edc17a48 100644 --- a/boards/st/stm32l562e_dk/Kconfig.defconfig +++ b/boards/st/stm32l562e_dk/Kconfig.defconfig @@ -10,9 +10,8 @@ if BT config SPI default y -choice BT_HCI_BUS_TYPE - default BT_SPI -endchoice +config BT_SPI + default y config BT_BLUENRG_ACI default y diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi index ccd74b46ece551..6922b6be83fa9f 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -32,11 +32,14 @@ }; aliases { - spi-flash0 = &mx25lm51245; die-temp0 = &die_temp; volt-sensor0 = &vref; volt-sensor1 = &vbat; }; + + chosen { + zephyr,bt-hci = &hci_spi; + }; }; &clk_hsi48 { @@ -114,7 +117,7 @@ stm32_lp_tick_source: &lptim1 { cs-gpios = <&gpiog 5 GPIO_ACTIVE_LOW>; status = "okay"; - spbtle-rf@0 { + hci_spi: spbtle-rf@0 { compatible = "st,hci-spi-v1"; reg = <0>; irq-gpios = <&gpiog 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; diff --git a/boards/st/stm32wb5mm_dk/Kconfig.defconfig b/boards/st/stm32wb5mm_dk/Kconfig.defconfig index 37be19b4d1c657..b75d5bdb31d8fe 100644 --- a/boards/st/stm32wb5mm_dk/Kconfig.defconfig +++ b/boards/st/stm32wb5mm_dk/Kconfig.defconfig @@ -5,9 +5,8 @@ if BOARD_STM32WB5MM_DK -choice BT_HCI_BUS_TYPE - default BT_STM32_IPM +config BT_STM32_IPM + default y depends on BT -endchoice endif diff --git a/boards/st/stm32wb5mm_dk/doc/stm32wb5mm_dk.rst b/boards/st/stm32wb5mm_dk/doc/stm32wb5mm_dk.rst index bc7218a4d9497d..84322f1bc7173e 100644 --- a/boards/st/stm32wb5mm_dk/doc/stm32wb5mm_dk.rst +++ b/boards/st/stm32wb5mm_dk/doc/stm32wb5mm_dk.rst @@ -121,6 +121,8 @@ The Zephyr STM32WB5MM-DK board configuration supports the following hardware fea | UART | on-chip | serial port-polling; | | | | serial port-interrupt | +-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -157,6 +159,7 @@ Default Zephyr Peripheral Mapping: - LPUART_1 TX/RX : PA3/PA2 - USB : PA11/PA12 - SWD : PA13/PA14 +- I2C3: SDA/SCL PB11/PB13 (Sensor I2C bus) System Clock ------------ diff --git a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts index 60fb751f30050e..e11ec3f0f20bd8 100644 --- a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts +++ b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts @@ -9,6 +9,7 @@ #include #include #include +#include / { model = "STMicroelectronics STM32WB5MM Discovery Development Kit"; @@ -56,6 +57,7 @@ led-strip = &rgb_led_strip; sw0 = &button0; sw1 = &button1; + accel0 = &ism330dhcx; }; }; @@ -174,6 +176,27 @@ zephyr_udc0: &usb { }; }; +&i2c3 { + pinctrl-0 = <&i2c3_scl_pb13 &i2c3_sda_pb11>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; + + vl53l0x@29 { + compatible = "st,vl53l0x"; + reg = <0x29>; + xshut-gpios = <&gpioc 6 GPIO_ACTIVE_LOW>; + }; + + ism330dhcx: ism330dhcx@6b { + compatible = "st,ism330dhcx"; + reg = <0x6b>; + drdy-gpios = <&gpiod 2 GPIO_ACTIVE_HIGH>; + accel-odr= ; + gyro-odr= ; + }; +}; + &vref { status = "okay"; }; diff --git a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml index 63c75d4473fb1f..a90491d13aa88d 100644 --- a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml +++ b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml @@ -7,8 +7,11 @@ toolchain: - gnuarmemb - xtools ram: 256 -flash: 1024 +flash: 876 supported: - gpio - uart + - i2c + - vl53l0x + - ism330dhcx vendor: st diff --git a/boards/st/stm32wb5mmg/Kconfig.defconfig b/boards/st/stm32wb5mmg/Kconfig.defconfig index e63531f897bac2..e07cc7210b21c1 100644 --- a/boards/st/stm32wb5mmg/Kconfig.defconfig +++ b/boards/st/stm32wb5mmg/Kconfig.defconfig @@ -5,9 +5,8 @@ if BOARD_STM32WB5MMG -choice BT_HCI_BUS_TYPE - default BT_STM32_IPM +config BT_STM32_IPM + default y depends on BT -endchoice endif diff --git a/boards/toradex/colibri_imx7d/doc/index.rst b/boards/toradex/colibri_imx7d/doc/index.rst index 22b356fc1c6259..dd13a140b3c824 100644 --- a/boards/toradex/colibri_imx7d/doc/index.rst +++ b/boards/toradex/colibri_imx7d/doc/index.rst @@ -221,6 +221,195 @@ configured in the Zephyr compilation: setenv bootm4ddr 'run m4ddr && run bootm4' run bootm4ddr +M4<->Linux IPC using RPMSG +************************** + +The IMX7D soc supports the subsys/ipc/openamp_rsc_table sample to demonstrate the +usage of rpmsg_tty as an inter processor communication. + +The board configuration is provided for the colibri_imx7d board. +The boot process of the M4 core is handled solely by the Linux kernel using the RPROC +framework. + +The sample was tested with Toradex's LTS BSP 6.6.0 Minimal Open Embedded image with +upstream Linux kernel 6.1.83. + +Required kernel modules must be loaded for RPMSG to work: + +- imx_rproc +- virtio_rpmsg_bus +- rpmsg_tty (requiring rpmsg_core) + +You need to modify your Linux device tree to add the M4 definitions: + +- Enable MU_A +- Reserve memory areas for the M4 so Linux won't touch them. +- Define the M4 remoteproc node for the drivers. + +If you have not downloaded the BSP sources, you can modify the board's device tree +from its currently loaded dtb file. + + +.. code-block:: none + + #Check the which fdtfile is loaded for your board in U-boot + printenv + #For a Colibri_imx7d on Viola Carrier on BSP 6.6.0 + fdtfile = imx7d-colibri-emmc-eval-v3.dtb + + #Copy this file to your Linux PC through SSH from /boot + #Convert the dtb into a dts + dtc -I dtb -O dts -f imx7d-colibri-emmc-eval-v3.dtb -o imx7d-colibri-emmc-eval-v3.dts + + #You need to find the following phandle numbers: + # reset-controller + # mailbox@30aa0000 + + #Note down the phandle value (0xbd) + grep -A10 "mailbox@30aa0000 {" imx7d-colibri-emmc-eval-v3.dts + # outputs your DTS's mailbox definition + # mailbox@30aa0000 { + # compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu"; + # reg = <0x30aa0000 0x10000>; + # interrupts = <0x00 0x58 0x04>; + # clocks = <0x01 0x1b1>; + # #mbox-cells = <0x02>; + # status = "disabled"; + # phandle = <0xbd>; + # }; + + #Note down the phandle value (0x32) + grep -A8 "reset-controller@30390000 {" imx7d-colibri-emmc-eval-v3.dts + # outputs your DTS's reset-controller definition + # reset-controller@30390000 { + # compatible = "fsl,imx7d-src\0syscon"; + # reg = <0x30390000 0x10000>; + # interrupts = <0x00 0x59 0x04>; + # #reset-cells = <0x01>; + # phandle = <0x32>; + # }; + + #Node down the biggest phandle value + grep "phandle = <" imx7d-colibri-emmc-eval-v3.dts | sort -r | head -1 + # outputs your DTS's largest phandle definition + # phandle = <0xca>; + + #Now we can add our nodes to the .dts file: + cp imx7d-colibri-emmc-eval-v3.dts imx7d-m4.dts + nano imx7d-m4.dts + + #Modify MU_A node to enable it + mailbox@30aa0000 { + compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu"; + reg = <0x30aa0000 0x10000>; + interrupts = <0x00 0x58 0x04>; + clocks = <0x01 0x1b1>; + #mbox-cells = <0x02>; + status = "okay"; + phandle = <0xbd>; + }; + + #Add these definitions under / { } just before the __symbols__ + #Disgard the comments with #--> + reserved-memory { + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges; + + vdev0buffer0@90002000 { + compatible = "shared-dma-pool"; + reg = <0x90002000 0x8000>; + no-map; + phandle = <0xcb>; #--> biggest phandle +1 + }; + + vdev0vring0@90000000 { + compatible = "shared-dma-pool"; + reg = <0x90000000 0x1000>; + no-map; + phandle = <0xcc>; #--> biggest phandle +2 + }; + + vdev0vring1@90001000 { + compatible = "shared-dma-pool"; + reg = <0x90001000 0x1000>; + no-map; + phandle = <0xcd>; #--> biggest phandle +3 + }; + + cm4tcmcode@7f8000 { + compatible = "shared-dma-pool"; + reg = <0x7f8000 0x8000>; + no-map; + phandle = <0xce>; #--> biggest phandle +4 + }; + + cm4sramcode@900000 { + compatible = "shared-dma-pool"; + reg = <0x900000 0x40000>; + no-map; + phandle = <0xcf>; #--> biggest phandle +5 + }; + + cm4reserved@8ff00000 { + compatible = "shared-dma-pool"; + reg = <0x8ff00000 0x100000>; + no-map; + phandle = <0xd0>; #--> biggest phandle +6 + }; + }; + + imx7d-cm4 { + compatible = "fsl,imx7d-cm4"; + mbox-names = "tx\0rx\0rxdb"; + mboxes = <0xbd 0x00 0x00 0xbd 0x01 0x00 0xbd 0x03 0x00>; #--> MU_A phandle (0xbd) + memory-region = <0xcb 0xcc 0xcd 0xce 0xcf 0xd0>; #--> All the previously defined phandles + syscon = <0x32>; #--> phandle for the reset-controller + clocks = <0x01 0x42>; + }; + + #Recompile the dts into a dtb + dtc -I dts -O dtb -f imx7d-m4.dts -o imx7d-m4.dtb + + #Copy the new dtb to /boot on the Colibri IMX7 board + #Start in U-boot and update the device-tree + setenv fdtfile imx7d-m4.dtb + saveenv + boot + +When the OS has finished booting with your new device tree you can enable +the drivers and start the M4 core. + +.. code-block:: console + + #Copy zephyr_openamp_rsc_table.elf to /lib/firmware on your board + $ modprobe imx_rproc + $ modprobe virtio_rpmsg_bus + $ modprobe rpmsg_tty + + #Request RPROC to load the M4 image + $ echo stop > /sys/class/remoteproc/remoteproc0/state + $ echo zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware + $ echo start > /sys/class/remoteproc/remoteproc0/state + + #dmesg will detail the boot process: + $ dmesg + [ 497.120499] remoteproc remoteproc0: stopped remote processor imx-rproc + [ 497.138938] remoteproc remoteproc0: powering up imx-rproc + [ 497.168735] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 1267076 + [ 497.184826] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node vdev0buffer0@90002000 + [ 497.221395] virtio_rpmsg_bus virtio0: rpmsg host is online + [ 497.233806] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x400 + [ 497.236666] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7) + [ 497.259822] remoteproc remoteproc0: remote processor imx-rproc is now up + [ 497.293913] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x401 + [ 497.308388] rpmsg_client_sample virtio0.rpmsg-client-sample.-1.1025: new channel: 0x401 -> 0x401! + [ 497.337969] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x402 + + $ ls /dev | grep ttyRPMSG + ttyRPMSG0 -> used for zephyr shell interface + ttyRPMSG1 -> used for sample interface + Debugging ========= diff --git a/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.dts b/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.dts index d06986a8afa298..070730c69d2c56 100644 --- a/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.dts +++ b/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.dts @@ -129,7 +129,6 @@ sw2 = &button2; sw3 = &button3; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.dts b/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.dts index ef145eabe54086..68b3755123b289 100644 --- a/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.dts +++ b/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.dts @@ -141,7 +141,6 @@ mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.dts b/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.dts index 404678ad95299f..d7a21c98b444e7 100644 --- a/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.dts +++ b/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.dts @@ -90,7 +90,6 @@ sw2 = &button2; sw3 = &button3; watchdog0 = &wdt0; - spi-flash0 = &mx25r64; }; }; diff --git a/boards/up-bridge-the-gap/up_squared/up_squared.dts b/boards/up-bridge-the-gap/up_squared/up_squared.dts index beb83af8b19966..2e8e763115f608 100644 --- a/boards/up-bridge-the-gap/up_squared/up_squared.dts +++ b/boards/up-bridge-the-gap/up_squared/up_squared.dts @@ -25,7 +25,7 @@ zephyr,sram = &dram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; + zephyr,bt-hci = &bt_hci_uart; zephyr,uart-pipe = &uart1; zephyr,bt-mon-uart = &uart1; }; @@ -49,3 +49,10 @@ }; }; }; + +&uart1 { + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + }; +}; diff --git a/boards/vcc-gnd/yd_esp32/Kconfig.defconfig b/boards/vcc-gnd/yd_esp32/Kconfig.defconfig index 9b7b408dbef2dd..2ca1ba1903658b 100644 --- a/boards/vcc-gnd/yd_esp32/Kconfig.defconfig +++ b/boards/vcc-gnd/yd_esp32/Kconfig.defconfig @@ -12,10 +12,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_YD_ESP32_ESP32_PROCPU if BOARD_YD_ESP32_ESP32_APPCPU diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts index 62b657c44d0770..a409ed6e90962f 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts @@ -35,6 +35,7 @@ zephyr,shell-uart = &uart0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; }; }; @@ -173,3 +174,7 @@ }; }; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/Kconfig.defconfig b/boards/waveshare/esp32s3_touch_lcd_1_28/Kconfig.defconfig index 33296a8e529bbc..06c61c850aa11d 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/Kconfig.defconfig +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/Kconfig.defconfig @@ -10,10 +10,6 @@ config HEAP_MEM_POOL_ADD_SIZE_BOARD default 40960 if BT default 4096 -choice BT_HCI_BUS_TYPE - default BT_ESP32 if BT -endchoice - endif # BOARD_ESP32S3_TOUCH_LCD_1_28_ESP32S3_PROCPU if BOARD_ESP32S3_TOUCH_LCD_1_28_ESP32S3_APPCPU diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts index c00b23ba147861..f6a62874fe50ae 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts @@ -30,6 +30,7 @@ zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,display = &gc9a01; + zephyr,bt-hci = &esp32_bt_hci; }; /* Buttons */ @@ -174,3 +175,7 @@ &wdt0 { status = "okay"; }; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/weact/mini_stm32h743/mini_stm32h743.dts b/boards/weact/mini_stm32h743/mini_stm32h743.dts index 3a6c1a055ca22a..9968b82d7d7b4f 100644 --- a/boards/weact/mini_stm32h743/mini_stm32h743.dts +++ b/boards/weact/mini_stm32h743/mini_stm32h743.dts @@ -80,7 +80,6 @@ aliases { led0 = &user_led; sw0 = &user_button; - spi-flash0 = &w25q64_spi; watchdog0 = &iwdg; sdhc0 = &sdmmc1; }; diff --git a/cmake/emu/qemu.cmake b/cmake/emu/qemu.cmake index 6103fc1cefc15f..0fd445f3c59397 100644 --- a/cmake/emu/qemu.cmake +++ b/cmake/emu/qemu.cmake @@ -100,7 +100,7 @@ endif() # Add a BT serial device when building for bluetooth, unless the # application explicitly opts out with NO_QEMU_SERIAL_BT_SERVER. if(CONFIG_BT) - if(CONFIG_BT_NO_DRIVER) + if(NOT CONFIG_BT_UART) set(NO_QEMU_SERIAL_BT_SERVER 1) endif() if(NOT NO_QEMU_SERIAL_BT_SERVER) diff --git a/cmake/llext-edk.cmake b/cmake/llext-edk.cmake index 9501133f3ab382..73692b8b380b8c 100644 --- a/cmake/llext-edk.cmake +++ b/cmake/llext-edk.cmake @@ -17,7 +17,6 @@ # - INTERFACE_INCLUDE_DIRECTORIES: List of include directories to copy headers # from. It should simply be the INTERFACE_INCLUDE_DIRECTORIES property of the # zephyr_interface target. -# - AUTOCONF_H: Name of the autoconf.h file, used to generate the imacros flag. # - llext_edk_file: Output file name for the tarball. # - llext_cflags: Additional flags to be added to the generated flags. # - ZEPHYR_BASE: Path to the zephyr base directory. @@ -31,6 +30,11 @@ cmake_minimum_required(VERSION 3.20.0) +if (CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) + message(FATAL_ERROR + "The LLEXT EDK is not compatible with CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID.") +endif() + set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name}) set(llext_edk_inc ${llext_edk}/include) @@ -89,7 +93,7 @@ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" llext_edk_name_sane ${llext_edk_name}) string(TOUPPER ${llext_edk_name_sane} llext_edk_name_sane) set(install_dir_var "${llext_edk_name_sane}_INSTALL_DIR") -separate_arguments(LLEXT_CFLAGS NATIVE_COMMAND ${llext_cflags}) +separate_arguments(llext_cflags NATIVE_COMMAND ${llext_cflags}) set(make_relative FALSE) foreach(flag ${llext_cflags}) @@ -112,16 +116,13 @@ foreach(flag ${llext_cflags}) list(APPEND new_cflags ${flag}) endif() endforeach() -set(LLEXT_CFLAGS ${new_cflags}) - -cmake_path(CONVERT "${INTERFACE_INCLUDE_DIRECTORIES}" TO_CMAKE_PATH_LIST include_dirs) +set(llext_cflags ${new_cflags}) -set(autoconf_h_edk ${llext_edk_inc}/${AUTOCONF_H}) -cmake_path(RELATIVE_PATH AUTOCONF_H BASE_DIRECTORY ${PROJECT_BINARY_DIR} OUTPUT_VARIABLE autoconf_h_rel) list(APPEND base_flags_make ${llext_cflags} ${imacros_make}) list(APPEND base_flags_cmake ${llext_cflags} ${imacros_cmake}) +separate_arguments(include_dirs NATIVE_COMMAND ${INTERFACE_INCLUDE_DIRECTORIES}) file(MAKE_DIRECTORY ${llext_edk_inc}) foreach(dir ${include_dirs}) if (NOT EXISTS ${dir}) @@ -173,7 +174,7 @@ list(JOIN imacros_gen_make " " imacros_gen_str) file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_GENERATED_IMACROS_CFLAGS = ${imacros_gen_str}") # Generate flags for CMake -list(APPEND all_flags_cmake ${base_flags_cmake} ${imacros_gen_make} ${all_inc_flags_cmake}) +list(APPEND all_flags_cmake ${base_flags_cmake} ${imacros_gen_cmake} ${all_inc_flags_cmake}) file(WRITE ${llext_edk}/cmake.cflags "set(LLEXT_CFLAGS ${all_flags_cmake})") file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_ALL_INCLUDE_CFLAGS ${all_inc_flags_cmake})") diff --git a/cmake/modules/basic_settings.cmake b/cmake/modules/basic_settings.cmake index 54bbffe79390a4..ed947a4fb090bd 100644 --- a/cmake/modules/basic_settings.cmake +++ b/cmake/modules/basic_settings.cmake @@ -23,7 +23,7 @@ include_guard(GLOBAL) if(SYSBUILD) add_custom_target(sysbuild_cache) - file(STRINGS "${SYSBUILD_CACHE}" sysbuild_cache_strings) + file(STRINGS "${SYSBUILD_CACHE}" sysbuild_cache_strings ENCODING UTF-8) foreach(str ${sysbuild_cache_strings}) # Using a regex for matching whole 'VAR_NAME:TYPE=VALUE' will strip semi-colons # thus resulting in lists to become strings. diff --git a/cmake/modules/boards.cmake b/cmake/modules/boards.cmake index ec9b6579146c04..d2c0666f2c576c 100644 --- a/cmake/modules/boards.cmake +++ b/cmake/modules/boards.cmake @@ -136,7 +136,7 @@ foreach(root ${BOARD_ROOT}) message(WARNING "BOARD_ROOT element without a 'boards' subdirectory: ${root} Hints: - - if your board directory is '/foo/bar/boards//my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory + - if your board directory is '/foo/bar/boards/my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory - if in doubt, use absolute paths") endif() endforeach() diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 2c1e1c6635542b..9fe387e2388159 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -5431,6 +5431,23 @@ function(add_llext_target target_name) COMMAND_EXPAND_LISTS ) + # LLEXT ELF processing for importing via SLID + # + # This command must be executed as last step of the packaging process, + # to ensure that the ELF processed for binary generation contains SLIDs. + # If executed too early, it is possible that some tools executed to modify + # the ELF file (e.g., strip) undo the work performed here. + if (CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) + set(slid_inject_cmd + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/llext_inject_slids.py + --elf-file ${llext_pkg_output} + -vvv + ) + else() + set(slid_inject_cmd ${CMAKE_COMMAND} -E true) + endif() + # Type-specific packaging of the built binary file into an .llext file if(CONFIG_LLEXT_TYPE_ELF_OBJECT) @@ -5438,6 +5455,7 @@ function(add_llext_target target_name) add_custom_command( OUTPUT ${llext_pkg_output} COMMAND ${CMAKE_COMMAND} -E copy ${llext_pkg_input} ${llext_pkg_output} + COMMAND ${slid_inject_cmd} DEPENDS ${llext_proc_target} ${llext_pkg_input} ) @@ -5453,6 +5471,7 @@ function(add_llext_target target_name) $${llext_pkg_input} $${llext_pkg_output} $ + COMMAND ${slid_inject_cmd} DEPENDS ${llext_proc_target} ${llext_pkg_input} ) @@ -5467,6 +5486,7 @@ function(add_llext_target target_name) $${llext_pkg_input} $${llext_pkg_output} $ + COMMAND ${slid_inject_cmd} DEPENDS ${llext_proc_target} ${llext_pkg_input} ) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 56b73c716a280c..3f374db5aea1d5 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -26,13 +26,10 @@ file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) if(HWMv1) # Support multiple SOC_ROOT file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}/soc) - set(kconfig_soc_root ${BOARD_ROOT}) + set(kconfig_soc_root ${SOC_ROOT}) list(REMOVE_ITEM kconfig_soc_root ${ZEPHYR_BASE}) set(soc_defconfig_file ${KCONFIG_BINARY_DIR}/soc/Kconfig.defconfig) - # This loads Zephyr base SoC root defconfigs - file(WRITE ${soc_defconfig_file} "osource \"soc/soc_legacy/$(ARCH)/*/Kconfig.defconfig\"\n") - set(OPERATION WRITE) foreach(root ${kconfig_soc_root}) file(APPEND ${soc_defconfig_file} @@ -401,7 +398,7 @@ if(CREATE_NEW_DOTCONFIG) endif() # Read out the list of 'Kconfig' sources that were used by the engine. -file(STRINGS ${PARSED_KCONFIG_SOURCES_TXT} PARSED_KCONFIG_SOURCES_LIST) +file(STRINGS ${PARSED_KCONFIG_SOURCES_TXT} PARSED_KCONFIG_SOURCES_LIST ENCODING UTF-8) # Force CMAKE configure when the Kconfig sources or configuration files changes. foreach(kconfig_input diff --git a/cmake/modules/soc_v1.cmake b/cmake/modules/soc_v1.cmake index 1bba9536c0c217..e2004f322550d5 100644 --- a/cmake/modules/soc_v1.cmake +++ b/cmake/modules/soc_v1.cmake @@ -60,9 +60,6 @@ if(HWMv1) if(EXISTS ${root}/soc/${ARCH}/${SOC_PATH}) set(SOC_DIR ${root}/soc) break() - elseif(EXISTS ${root}/soc/soc_legacy/${ARCH}/${SOC_PATH}) - set(SOC_DIR ${root}/soc/soc_legacy) - break() endif() endforeach() diff --git a/cmake/toolchain/armclang/Kconfig b/cmake/toolchain/armclang/Kconfig index 27be295057ca96..70b9b2bd152031 100644 --- a/cmake/toolchain/armclang/Kconfig +++ b/cmake/toolchain/armclang/Kconfig @@ -16,7 +16,7 @@ choice LIBC_IMPLEMENTATION config ARMCLANG_STD_LIBC bool "ARM Compiler C library" select COMMON_LIBC_STRNLEN - select COMMON_LIBC_TIME if POSIX_CLOCK + select COMMON_LIBC_TIME if POSIX_TIMERS help Use the full Arm Compiler runtime libraries. A reduced Zephyr minimal libc will be used for library functionality diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 5cfce578a4a9e8..e72b7ac229861f 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -174,7 +174,7 @@ add_doc_target( -d ${DOCS_DOCTREE_DIR} -w ${DOCS_BUILD_DIR}/latex.log -t ${DOC_TAG} - -t svgconvert + -t convertimages ${SPHINXOPTS} ${SPHINXOPTS_EXTRA} ${DOCS_SRC_DIR} diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index dbd6227d972cb8..4637aca7ae9d1c 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -163,7 +163,7 @@ def init_vnd2ref_target(self): def main(): args = parse_args() setup_logging(args.verbose) - bindings = load_bindings(args.dts_roots) + bindings = load_bindings(args.dts_roots, args.dts_folders) base_binding = load_base_binding() vnd_lookup = VndLookup(args.vendor_prefixes, bindings) dump_content(bindings, base_binding, vnd_lookup, args.out_dir, @@ -180,6 +180,8 @@ def parse_args(): parser.add_argument('--dts-root', dest='dts_roots', action='append', help='''additional DTS root directory as it would be set in DTS_ROOTS''') + parser.add_argument('--dts-folder', dest='dts_folders', action='append', default=[], + help='additional DTS folders containing binding files') parser.add_argument('--turbo-mode', action='store_true', help='Enable turbo mode (dummy references)') parser.add_argument('out_dir', help='output files are generated here') @@ -196,7 +198,7 @@ def setup_logging(verbose): logging.basicConfig(format='%(filename)s:%(levelname)s: %(message)s', level=log_level) -def load_bindings(dts_roots): +def load_bindings(dts_roots, dts_folders): # Get a list of edtlib.Binding objects from searching 'dts_roots'. if not dts_roots: @@ -208,6 +210,9 @@ def load_bindings(dts_roots): recursive=True)) binding_files.extend(glob.glob(f'{dts_root}/dts/bindings/**/*.yaml', recursive=True)) + for folders in dts_folders: + binding_files.extend(glob.glob(f'{folders}/*.yml', recursive=False)) + binding_files.extend(glob.glob(f'{folders}/*.yaml', recursive=False)) bindings = edtlib.bindings_from_paths(binding_files, ignore_errors=True) @@ -322,7 +327,9 @@ def write_bindings_rst(vnd_lookup, out_dir): .. rst-class:: rst-columns ''', string_io) - for vnd in vnd_lookup.vnd2bindings: + for vnd, bindings in vnd_lookup.vnd2bindings.items(): + if len(bindings) == 0: + continue print(f'- :ref:`{vnd_lookup.target(vnd)}`', file=string_io) print_block('''\ @@ -358,6 +365,9 @@ def write_bindings_rst(vnd_lookup, out_dir): title += f' ({vnd})' underline = '=' * len(title) + if len(bindings) == 0: + continue + print_block(f'''\ .. _{vnd_lookup.target(vnd)}: diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index aa4bd4fdebfa03..8b2d5e65626d21 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -143,6 +143,7 @@ ('guides/west/workspaces', 'develop/west/workspaces'), ('guides/west/zephyr-cmds', 'develop/west/zephyr-cmds'), ('guides/zephyr_cmake_package', 'build/zephyr_cmake_package'), + ('hardware/peripherals/sensor', 'hardware/peripherals/sensor/index'), ('reference/api/api_lifecycle', 'develop/api/api_lifecycle'), ('reference/api/index', 'develop/api/index'), ('reference/api/overview', 'develop/api/overview'), diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 44b87653cc3fe1..e76ad997fb5194 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -386,8 +386,8 @@ device. :ref:`bluetooth-hci-uart-sample` * - zephyr,bt-mon-uart - Sets UART device used for the Bluetooth monitor logging - * - zephyr,bt-uart - - Sets UART device used by Bluetooth + * - zephyr,bt-hci + - Selects the HCI device used by the Bluetooth host stack * - zephyr,canbus - Sets the default CAN controller * - zephyr,ccm diff --git a/doc/build/dts/macros.bnf b/doc/build/dts/macros.bnf index 88ed70f2ba9506..f5e676f8f44a33 100644 --- a/doc/build/dts/macros.bnf +++ b/doc/build/dts/macros.bnf @@ -35,6 +35,7 @@ node-macro =/ %s"DT_N" path-id %s"_REG_IDX_" DIGIT %s"_VAL_" ( %s"ADDRESS" / %s"SIZE") node-macro =/ %s"DT_N" path-id %s"_REG_NAME_" dt-name %s"_VAL_" ( %s"ADDRESS" / %s"SIZE") +node-macro =/ %s"DT_N" path-id %s"_REG_NAME_" dt-name "_EXISTS" ; The interrupts property is also special. node-macro =/ %s"DT_N" path-id %s"_IRQ_NUM" node-macro =/ %s"DT_N" path-id %s"_IRQ_LEVEL" @@ -88,6 +89,11 @@ node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD_STATUS_OKAY" node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD_STATUS_OKAY_SEP" node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD_STATUS_OKAY_VARGS" node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS" +; These are used internally by DT_FOREACH_NODELABEL and +; DT_FOREACH_NODELABEL_VARGS, which iterate over a node's node labels. +node-macro =/ %s"DT_N" path-id %s"_FOREACH_NODELABEL" [ %s"_VARGS" ] +; These are used internally by DT_NUM_NODELABELS +node-macro =/ %s"DT_N" path-id %s"_NODELABEL_NUM" ; The node's zero-based index in the list of it's parent's child nodes. node-macro =/ %s"DT_N" path-id %s"_CHILD_IDX" ; The node's status macro; dt-name in this case is something like "okay" diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index b938e233f975b3..05308589d53f61 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -198,6 +198,55 @@ configuration that gets modified when making changes in the :ref:`interactive configuration interfaces `. +Tracking Kconfig symbols +************************ + +It is possible to create Kconfig symbols which takes the default value of +another Kconfig symbol. + +This is valuable when you want a symbol specific to an application or subsystem +but do not want to rely directly on the common symbol. For example, you might +want to decouple the settings so they can be independently configured, or to +ensure you always have a locally named setting, even if the external setting name changes. +is later changed. + +For example, consider the common ``FOO_STRING`` setting where a subsystem wants +to have a ``SUB_FOO_STRING`` but still allow for customization. + +This can be done like this: + +.. code-block:: kconfig + + config FOO_STRING + string "Foo" + default "foo" + + config SUB_FOO_STRING + string "Sub-foo" + default FOO_STRING + +This ensures that the default value of ``SUB_FOO_STRING`` is identical to +``FOO_STRING`` while still allows users to configure both settings +independently. + +It is also possible to make ``SUB_FOO_STRING`` invisible and thereby keep the +two symbols in sync, unless the value of the tracking symbol is changed in a +:file:`defconfig` file. + +.. code-block:: kconfig + + config FOO_STRING + string "Foo" + default "foo" + + config SUB_FOO_STRING + string + default FOO_STRING + help + Hidden symbol which follows FOO_STRING + Can be changed through *.defconfig files. + + Configuring invisible Kconfig symbols ************************************* diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index 295b7767555de2..5166e1d44827a9 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -588,6 +588,8 @@ a Kconfig option, which would make ``my_sample`` conditionally build-only. ``west flash --domain my_sample``. As such, the ``BUILD_ONLY`` option only controls the default behavior of ``west flash``. +.. _sysbuild_application_configuration: + Zephyr application configuration ================================ diff --git a/doc/conf.py b/doc/conf.py index ff54dd2cc490ff..a86f09b054234c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -99,9 +99,13 @@ "zephyr.api_overview", ] -# Only use SVG converter when it is really needed, e.g. LaTeX. -if tags.has("svgconvert"): # pylint: disable=undefined-variable +# Only use image conversion when it is really needed, e.g. LaTeX build. +# Ensure "sphinxcontrib.rsvgconverter" is added before "sphinx.ext.imgconverter" +# as it's better at converting SVG with extended features (like the ones from +# draw.io) to PDF format). +if tags.has("convertimages"): # pylint: disable=undefined-variable extensions.append("sphinxcontrib.rsvgconverter") + extensions.append("sphinx.ext.imgconverter") templates_path = ["_templates"] diff --git a/doc/connectivity/bluetooth/api/audio/shell/bap.rst b/doc/connectivity/bluetooth/api/audio/shell/bap.rst index 6b2b75ecda4ed8..77a44dbd5d7ccc 100644 --- a/doc/connectivity/bluetooth/api/audio/shell/bap.rst +++ b/doc/connectivity/bluetooth/api/audio/shell/bap.rst @@ -54,7 +54,7 @@ Commands [pref_ctx ] [stream_ctx ] [program_info ] - [stream_lang ] + [lang ] [ccid_list ] [parental_rating ] [program_info_uri ] @@ -336,7 +336,7 @@ any stream previously configured. [pref_ctx ] [stream_ctx ] [program_info ] - [stream_lang ] + [lang ] [ccid_list ] [parental_rating ] [program_info_uri ] @@ -415,7 +415,7 @@ assigned numbers values. 00000000: 08 00 |.. | QoS: interval 10000 framing 0x00 phy 0x02 sdu 80 rtn 2 latency 10 pd 40000 - uart:~$ bap preset sink 32_2_1 config freq 10 meta stream_lang "eng" stream_ctx 4 + uart:~$ bap preset sink 32_2_1 config freq 10 meta lang "eng" stream_ctx 4 32_2_1 codec cfg id 0x06 cid 0x0000 vid 0x0000 count 16 data #0: type 0x01 value_len 1 diff --git a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst index b4193d5033472f..0d533109830adc 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst @@ -33,7 +33,7 @@ Transfer context ================ Both the transfer capabilities retrieval procedure and the BLOB transfer uses an instance of a -:c:type:`bt_mesh_blob_cli_inputs` to determine how to perform the transfer. The BLOB Transfer Client +:c:struct:`bt_mesh_blob_cli_inputs` to determine how to perform the transfer. The BLOB Transfer Client Inputs structure must at least be initialized with a list of targets, an application key and a time to live (TTL) value before it is used in a procedure: diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index c83377aef85cac..5140d2ae36d651 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -201,17 +201,17 @@ DFU. Depending on the availability of the Remote Provisioning Server model on th the device may either boot up unprovisioned after applying the new firmware or require to be re-provisioned. The complete list of available options is defined in :c:enum:`bt_mesh_dfu_effect`: -:c:enum:`BT_MESH_DFU_EFFECT_NONE` +:c:enumerator:`BT_MESH_DFU_EFFECT_NONE` The device stays provisioned after the new firmware is programmed. This effect is chosen if the composition data of the new firmware doesn't change. -:c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR` +:c:enumerator:`BT_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR` This effect is chosen when the composition data changes and the device doesn't support the remote provisioning. The new composition data takes place only after re-provisioning. -:c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE` +:c:enumerator:`BT_MESH_DFU_EFFECT_COMP_CHANGE` This effect is chosen when the composition data changes and the device supports the remote provisioning. In this case, the device stays provisioned and the new composition data takes place after re-provisioning using the Remote Provisioning models. -:c:enum:`BT_MESH_DFU_EFFECT_UNPROV` +:c:enumerator:`BT_MESH_DFU_EFFECT_UNPROV` This effect is chosen if the composition data in the new firmware changes, the device doesn't support the remote provisioning, and the new composition data takes effect after applying the firmware. @@ -219,7 +219,7 @@ re-provisioned. The complete list of available options is defined in :c:enum:`bt When the Target node receives the Firmware Update Firmware Metadata Check message, the Firmware Update Server model calls the :c:member:`bt_mesh_dfu_srv_cb.check` callback, the application can then process the metadata and provide the effect value. If the effect is -:c:enum:`BT_MESH_DFU_EFFECT_COMP_CHANGE`, the application must call functions +:c:enumerator:`BT_MESH_DFU_EFFECT_COMP_CHANGE`, the application must call functions :c:func:`bt_mesh_comp_change_prepare` and :c:func:`bt_mesh_models_metadata_change_prepare` to prepare the Composition Data Page and Models Metadata Page contents before applying the new firmware image. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata` for more diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst index 105bdecb86ccee..fdccbba639cce4 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst @@ -45,7 +45,7 @@ firmware image metadata. The Firmware Update Server performs the transfer check :c:member:`check ` callback. The result of the transfer check is a pass/fail status return and the expected -:c:type:`bt_mesh_dfu_effect`. The DFU effect return parameter will be communicated back to the +:c:enum:`bt_mesh_dfu_effect`. The DFU effect return parameter will be communicated back to the Distributor, and should indicate what effect the firmware update will have on the mesh state of the device. diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 8aab68e54caa59..b340166fbff867 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -521,7 +521,7 @@ engine. Data caches depends on one of the SenML data formats :kconfig:option:`CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT` or -:kconfig:option:`CONFIG_LWM2M_RW_SENML_JSON_SUPPORT` and needs :kconfig:option:`CONFIG_POSIX_CLOCK` +:kconfig:option:`CONFIG_LWM2M_RW_SENML_JSON_SUPPORT` and needs :kconfig:option:`CONFIG_POSIX_TIMERS` so it can request a timestamp from the system and :kconfig:option:`CONFIG_RING_BUFFER` for ring buffer. diff --git a/doc/connectivity/networking/api/protocols.rst b/doc/connectivity/networking/api/protocols.rst index 57aeaae8d021a3..f4f3b1f88c1af1 100644 --- a/doc/connectivity/networking/api/protocols.rst +++ b/doc/connectivity/networking/api/protocols.rst @@ -15,4 +15,5 @@ Protocols lwm2m mqtt mqtt_sn + ptp tftp diff --git a/doc/connectivity/networking/api/ptp.rst b/doc/connectivity/networking/api/ptp.rst new file mode 100644 index 00000000000000..8b0d8384393a71 --- /dev/null +++ b/doc/connectivity/networking/api/ptp.rst @@ -0,0 +1,140 @@ +.. _ptp_interface: + +Precision Time Protocol (PTP) +############################# + +.. contents:: + :local: + :depth: 2 + +Overview +******** + +PTP is a network protocol implemented in the application layer, used to synchronize +clocks in a computer network. It's accurate up to less than a microsecond. +The stack supports the protocol and procedures as defined in the `IEEE 1588-2019 standard`_ +(IEEE Standard for a Precision Clock Synchronization Protocol +for Networked Measurement and Control Systems). It has multiple profiles, +and can be implemented on top of L2 (Ethernet) or L3 (UDP/IPv4 or UDP/IPv6). +Its accuracy is achieved by using hardware timestamping of the protocol packets. + +Zephyr's implementation of PTP stack consist following items: + +* PTP stack thread that handles incoming messages and events +* Integration with ptp_clock driver +* PTP stack initialization executed during system init + +The implementation automatically creates PTP Ports (each PTP Port coresponds to unique interface). + +Supported features +****************** + +Implementation of the stack doesn't support all features specified in the standard. +In the table below all supported features are listed. + +.. csv-table:: Supported features + :header: Feature, Supported + :widths: 50,10 + + Ordinary Clock, yes + Boundary Clock, yes + Transparent Clock, + Management Node, + End to end delay mechanism, yes + Peer to peer delay mechanism, + Multicast operation mode, + Hybrid operation mode, + Unicast operation mode, + Non-volatile storage, + UDP IPv4 transport protocol, yes + UDP IPv6 transport protocol, yes + IEEE 802.3 (Ethernet) transport protocol, + Hardware timestamping, yes + Software timestamping, + TIME_RECEIVER_ONLY PTP Instance, yes + TIME_TRANSMITTER_ONLY PTP Instance, + +Supported Management messages +***************************** + +Based on Table 59 from section 15.5.2.3 of the IEEE 1588-2019 following management TLVs +are supported: + +.. csv-table:: Supported management message's IDs + :header: Management_ID, Management_ID name, Allowed acctions + :widths: 10,40,25 + + 0x0000, NULL_PTP_MANAGEMENT, GET SET COMMAND + 0x0001, CLOCK_DESCRIPTION, GET + 0x0002, USER_DESCRIPTION, GET + 0x0003, SAVE_IN_NON_VOLATILE_STORAGE, - + 0x0004, RESET_NON_VOLATILE_STORAGE, - + 0x0005, INITIALIZE, - + 0x0006, FAULT_LOG, - + 0x0007, FAULT_LOG_RESET, - + 0x2000, DEFAULT_DATA_SET, GET + 0x2001, CURRENT_DATA_SET, GET + 0x2002, PARENT_DATA_SET, GET + 0x2003, TIME_PROPERTIES_DATA_SET, GET + 0x2004, PORT_DATA_SET, GET + 0x2005, PRIORITY1, GET SET + 0x2006, PRIORITY2, GET SET + 0x2007, DOMAIN, GET SET + 0x2008, TIME_RECEIVER_ONLY, GET SET + 0x2009, LOG_ANNOUNCE_INTERVAL, GET SET + 0x200A, ANNOUNCE_RECEIPT_TIMEOUT, GET SET + 0x200B, LOG_SYNC_INTERVAL, GET SET + 0x200C, VERSION_NUMBER, GET SET + 0x200D, ENABLE_PORT, COMMAND + 0x200E, DISABLE_PORT, COMMAND + 0x200F, TIME, GET SET + 0x2010, CLOCK_ACCURACY, GET SET + 0x2011, UTC_PROPERTIES, GET SET + 0x2012, TRACEBILITY_PROPERTIES, GET SET + 0x2013, TIMESCALE_PROPERTIES, GET SET + 0x2014, UNICAST_NEGOTIATION_ENABLE, - + 0x2015, PATH_TRACE_LIST, - + 0x2016, PATH_TRACE_ENABLE, - + 0x2017, GRANDMASTER_CLUSTER_TABLE, - + 0x2018, UNICAST_TIME_TRANSMITTER_TABLE, - + 0x2019, UNICAST_TIME_TRANSMITTER_MAX_TABLE_SIZE, - + 0x201A, ACCEPTABLE_TIME_TRANSMITTER_TABLE, - + 0x201B, ACCEPTABLE_TIME_TRANSMITTER_TABLE_ENABLED, - + 0x201C, ACCEPTABLE_TIME_TRANSMITTER_MAX_TABLE_SIZE, - + 0x201D, ALTERNATE_TIME_TRANSMITTER, - + 0x201E, ALTERNATE_TIME_OFFSET_ENABLE, - + 0x201F, ALTERNATE_TIME_OFFSET_NAME, - + 0x2020, ALTERNATE_TIME_OFFSET_MAX_KEY, - + 0x2021, ALTERNATE_TIME_OFFSET_PROPERTIES, - + 0x3000, EXTERNAL_PORT_CONFIGURATION_ENABLED, + 0x3001, TIME_TRANSMITTER_ONLY, - + 0x3002, HOLDOVER_UPGRADE_ENABLE, - + 0x3003, EXT_PORT_CONFIG_PORT_DATA_SET, - + 0x4000, TRANSPARENT_CLOCK_DEFAULT_DATA_SET, - + 0x4001, TRANSPARENT_CLOCK_PORT_DATA_SET, - + 0x4002, PRIMARY_DOMAIN, - + 0x6000, DELAY_MECHANISM, GET + 0x6001, LOG_MIN_PDELAY_REQ_INTERVAL, GET SET + +Enabling the stack +****************** + +The following configuration option must me enabled in :file:`prj.conf` file. + +- :kconfig:option:`CONFIG_PTP` + +Testing +******* + +The stack has been informally tested using the +`Linux ptp4l `_ daemons. +The :zephyr:code-sample:`PTP sample application ` from the Zephyr +source distribution can be used for testing. + +.. _IEEE 1588-2019 standard: + https://standards.ieee.org/ieee/1588/6825/ + +API Reference +************* + +.. doxygengroup:: ptp diff --git a/doc/connectivity/networking/api/tsn.rst b/doc/connectivity/networking/api/tsn.rst index c9d00cfcc5ce65..276be30e230e10 100644 --- a/doc/connectivity/networking/api/tsn.rst +++ b/doc/connectivity/networking/api/tsn.rst @@ -9,3 +9,4 @@ Time Sensitive Networking gptp.rst net_time.rst ptp_time.rst + ptp.rst diff --git a/doc/connectivity/networking/conn_mgr/main.rst b/doc/connectivity/networking/conn_mgr/main.rst index fd7a8bf87eec54..8788da9ceb82bf 100644 --- a/doc/connectivity/networking/conn_mgr/main.rst +++ b/doc/connectivity/networking/conn_mgr/main.rst @@ -73,6 +73,17 @@ Afterwards, ifaces can become ready or unready without firing additional events, When there are no longer any ready ifaces left, the :c:macro:`NET_EVENT_L4_DISCONNECTED` :ref:`network management ` event is triggered, and IP connectivity is said to be unready. +.. note:: + + Connection Manager also fires the following more specific ``CONNECTED`` / ``DISCONNECTED`` events: + + - :c:macro:`NET_EVENT_L4_IPV4_CONNECTED` + - :c:macro:`NET_EVENT_L4_IPV4_DISCONNECTED` + - :c:macro:`NET_EVENT_L4_IPV6_CONNECTED` + - :c:macro:`NET_EVENT_L4_IPV6_DISCONNECTED` + + These are similar to :c:macro:`NET_EVENT_L4_CONNECTED` and :c:macro:`NET_EVENT_L4_DISCONNECTED`, but specifically track whether IPv4- and IPv6-capable ifaces are ready. + .. _conn_mgr_monitoring_usage: Usage diff --git a/doc/connectivity/networking/net_config_guide.rst b/doc/connectivity/networking/net_config_guide.rst index 177ff434e8ae15..fd4f0ff402f181 100644 --- a/doc/connectivity/networking/net_config_guide.rst +++ b/doc/connectivity/networking/net_config_guide.rst @@ -87,7 +87,7 @@ Socket Options Maximum number of supported poll() entries. One needs to select proper value here depending on how many BSD sockets are polled in the system. -:kconfig:option:`CONFIG_POSIX_MAX_FDS` +:kconfig:option:`CONFIG_ZVFS_OPEN_MAX` Maximum number of open file descriptors, this includes files, sockets, special devices, etc. One needs to select proper value here depending on how many BSD sockets are created in the system. diff --git a/doc/contribute/contributor_expectations.rst b/doc/contribute/contributor_expectations.rst index cba1627a1b9be3..88fe625c005250 100644 --- a/doc/contribute/contributor_expectations.rst +++ b/doc/contribute/contributor_expectations.rst @@ -276,6 +276,9 @@ Reviewer Expectations #. PRs assigned to the reviewer as the area maintainer. #. All other PRs. +- Reviewers shall strive to advance the PR to a mergeable state with their + feedback and engagement with the PR author. + - Try to provide feedback on the entire PR in one shot. This provides the contributor an opportunity to address all comments in the next PR update. @@ -305,6 +308,11 @@ Reviewer Expectations the PR in question and following the contribution and style guidelines of the project. +- Reviewers shall not close a PR due to technical or structural disagreement. + If requested changes cannot be resolved within the review process, the + :ref:`pr_technical_escalation` path shall be used for any potential resolution + path, which may include closing the PR. + .. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md .. _Zephyr Release Plan: https://github.com/orgs/zephyrproject-rtos/projects/13 diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index 3991b19c47d239..f51eb59e44e494 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -105,27 +105,27 @@ as described below: .. code-block:: console sudo apt-get install --no-install-recommends doxygen graphviz librsvg2-bin \ - texlive-latex-base texlive-latex-extra latexmk texlive-fonts-recommended + texlive-latex-base texlive-latex-extra latexmk texlive-fonts-recommended imagemagick On Fedora Linux: .. code-block:: console sudo dnf install doxygen graphviz texlive-latex latexmk \ - texlive-collection-fontsrecommended librsvg2-tools + texlive-collection-fontsrecommended librsvg2-tools ImageMagick On Clear Linux: .. code-block:: console - sudo swupd bundle-add texlive graphviz + sudo swupd bundle-add texlive graphviz ImageMagick On Arch Linux: .. code-block:: console sudo pacman -S graphviz doxygen librsvg texlive-core texlive-bin \ - texlive-latexextra texlive-fontsextra + texlive-latexextra texlive-fontsextra imagemagick .. group-tab:: macOS @@ -139,7 +139,7 @@ as described below: .. code-block:: console - brew install doxygen graphviz mactex librsvg + brew install doxygen graphviz mactex librsvg imagemagick tlmgr install latexmk tlmgr install collection-fontsrecommended @@ -155,7 +155,7 @@ as described below: .. code-block:: console - choco install doxygen.install graphviz strawberryperl miktex rsvg-convert + choco install doxygen.install graphviz strawberryperl miktex rsvg-convert imagemagick .. note:: On Windows, the Sphinx executable ``sphinx-build.exe`` is placed in diff --git a/doc/contribute/external.rst b/doc/contribute/external.rst index c154bc3a698a81..312c3d2f416fba 100644 --- a/doc/contribute/external.rst +++ b/doc/contribute/external.rst @@ -39,7 +39,7 @@ have not been approved by the `Open Source Initiative (OSI)`_. See the https://www.zephyrproject.org/governance/ .. _Zephyr project charter: - https://www.zephyrproject.org/wp-content/uploads/sites/38/2020/09/CLEAN-LF-Zephyr-Charter-20200624-effective-20200901.pdf + https://www.zephyrproject.org/wp-content/uploads/sites/38/2023/08/LF-Zephyr-Charter-2023.08.21.pdf .. _Open Source Initiative (OSI): https://opensource.org/licenses/alphabetical diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 564deb07418964..5f31f6422e1662 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -148,6 +148,8 @@ For your commits, replace: You can automatically add the Signed-off-by: line to your commit body using ``git commit -s``. Use other commits in the zephyr git history as examples. +See :ref:`git_setup` for instructions on configuring user and email settings +in Git. Additional requirements: @@ -331,16 +333,10 @@ business days. You can find all `open pull requests`_ on GitHub and open `Zephyr Project Issues`_ in Github issues. - .. _Continuous Integration: +.. _git_setup: - -Tools and Git Setup -******************* - -.. _git-name-and-email: - -Name and email -============== +Git Setup +********* We need to know who you are, and how to contact you. To add this information to your Git installation, set the Git configuration @@ -355,93 +351,181 @@ address is ``z.developer@example.com``: git config --global user.name "Zephyr Developer" git config --global user.email "z.developer@example.com" -gitlint -========= -When you submit a pull request to the project, a series of checks are -performed to verify your commit messages meet the requirements. The same step -done during the CI process can be performed locally using the ``gitlint`` -command. +Pull Request Guidelines +*********************** +When opening a new Pull Request, adhere to the following guidelines to ensure +compliance with Zephyr standards and facilitate the review process. -Run ``gitlint`` locally in your tree and branch where your patches have been -committed: +If in doubt, it's advisible to explore existing Pull Requests within the Zephyr +repository. Use the search filters and labels to locate PRs related to changes +similar to the ones you are proposing. -.. code-block:: console +.. _commit-guidelines: - gitlint +Commit Message Guidelines +========================= -Note, gitlint only checks HEAD (the most recent commit), so you should run it -after each commit, or use the ``--commits`` option to specify a commit range -covering all the development patches to be submitted. +Changes are submitted as Git commits. Each commit has a *commit +message* describing the change. Acceptable commit messages look like +this: -twister -======= +.. code-block:: none -.. note:: - twister support on windows is limited and execution of tests is not - supported, only building. + [area]: [summary of change] -To verify that your changes did not break any tests or samples, please run the -``twister`` script locally before submitting your pull request to GitHub. + [Commit message body (must be non-empty)] -Twister allows limiting the scope of the tests built and run by pointing it to -the tests related to the code or the platform you have modified. For example, to -limit tests to a single platform and an area in the kernel:: + Signed-off-by: [Your Full Name] <[your.email@address]> - source zephyr-env.sh - west twister -p qemu_x86 -T tests/kernel/sched +You need to change text in square brackets (``[like this]``) above to +fit your commit. -Running tests on connected devices is also supported using the -``--device-testing`` options. Please consult with the :ref:`Twister -` documentation for more details. +Examples and more details follow. -To run the same tests the CI system runs, follow these steps from within your -local Zephyr source working directory: +Example +------- -.. code-block:: console +Here is an example of a good commit message. - source zephyr-env.sh - west twister --integration +.. code-block:: none -The above will execute the basic twister script, which will run various -tests using the QEMU emulator and other simulators supported in Zephyr. -It will also do some build tests on various samples with advanced features that -can't run in a simulator or QEMU. + drivers: sensor: abcd1234: fix bus I/O error handling -We highly recommend you run these tests locally to avoid any CI failures -However, note that building and executing tests using twister requires -significant computing resources. When running locally and to get results in a -reasonable time, limit the scope to the areas and platforms you have modified. -In case of major changes to the kernel, build or configuration infrastructures -of Zephyr, it is advised to use twister for verifying majority the changes -before handing over to the dedicated CI resources provided by the Zephyr -project. + The abcd1234 sensor driver is failing to check the flags field in + the response packet from the device which signals that an error + occurred. This can lead to reading invalid data from the response + buffer. Fix it by checking the flag and adding an error path. -clang-format -============ + Signed-off-by: Zephyr Developer -The `clang-format tool `_ can -be helpful to quickly reformat large amounts of new source code to our -`Coding Style`_ standards together with the ``.clang-format`` configuration file -provided in the repository. ``clang-format`` is well integrated into most -editors, but you can also run it manually like this: +[area]: [summary of change] +--------------------------- -.. code-block:: bash +This line is called the commit's *title*. Titles must be: - clang-format -i my_source_file.c +* one line +* less than 72 characters long +* followed by a completely blank line -``clang-format`` is part of LLVM, which can be downloaded from the project -`releases page `. Note that if -you are a Linux user, ``clang-format`` will likely be available as a package in -your distribution repositories. +[area] + The ``[area]`` prefix usually identifies the area of code + being changed. It can also identify the change's wider + context if multiple areas are affected. + + Here are some examples: + + * ``doc: ...`` for documentation changes + * ``drivers: foo:`` for ``foo`` driver changes + * ``Bluetooth: Shell:`` for changes to the Bluetooth shell + * ``net: ethernet:`` for Ethernet-related networking changes + * ``dts:`` for treewide devicetree changes + * ``style:`` for code style changes + + If you're not sure what to use, try running ``git log FILE``, where + ``FILE`` is a file you are changing, and using previous commits that + changed the same file as inspiration. + +[summary of change] + The ``[summary of change]`` part should be a quick description of + what you've done. Here are some examples: + + * ``doc: update wiki references to new site`` + * ``drivers: sensor: sensor_shell: fix channel name collision`` + +Commit Message Body +------------------- + +.. warning:: + + An empty commit message body is not permitted. Even for trivial + changes, please include a descriptive commit message body. Your + pull request will fail CI checks if you do not. + +This part of the commit should explain what your change does, and why +it's needed. Be specific. A body that says ``"Fixes stuff"`` will be +rejected. Be sure to include the following as relevant: + +* **what** the change does, +* **why** you chose that approach, +* **what** assumptions were made, and +* **how** you know it works -- for example, which tests you ran. + +Each line in your commit message should usually be 75 characters or +less. Use newlines to wrap longer lines. Exceptions include lines +with long URLs, email addresses, etc. + +For examples of accepted commit messages, you can refer to the Zephyr GitHub +`changelog `__. + + +Signed-off-by: ... +------------------ + +.. tip:: + + You should have set your :ref:`git_setup` + already. Create your commit with ``git commit -s`` to add the + Signed-off-by: line automatically using this information. + +For open source licensing reasons, your commit must include a +Signed-off-by: line that looks like this: + +.. code-block:: none + + Signed-off-by: [Your Full Name] <[your.email@address]> + +For example, if your full name is ``Zephyr Developer`` and your email +address is ``z.developer@example.com``: + +.. code-block:: none + + Signed-off-by: Zephyr Developer + +This means that you have personally made sure your change complies +with the :ref:`DCO`. For this reason, you must use your legal name. +Pseudonyms or "hacker aliases" are not permitted. + +Your name and the email address you use must match the name and email +in the Git commit's ``Author:`` field. + +See the :ref:`contributor-expectations` for a more complete discussion of +contributor and reviewer expectations. + +Adding links +------------ + +.. _GitHub references: + https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls + +Do not include `GitHub references`_ in the commit message directly, as it can +lose meaning in case the repository is forked, for example. Instead, if the +change addresses a specific GitHub issue, include in the Pull Request message a +line of the form: + +.. code-block:: none + + Fixes #[issue number] + +Where ``[issue number]`` is the relevant GitHub issue's number. For +example: + +.. code-block:: none + + Fixes: #1234 + +You can point to other relevant information that can be found on the web using +:code:`Link:` tags. This includes, for example: GitHub issues, datasheets, +reference manuals, etc. + +.. code-block:: none + + Link: https://github.com/zephyrproject-rtos/zephyr/issues/ .. _coding_style: Coding Style -************ - -Use these coding guidelines to ensure that your development complies with the -project's style and naming conventions. +============ .. _Linux kernel coding style: https://kernel.org/doc/html/latest/process/coding-style.html @@ -462,8 +546,8 @@ exceptions: * Avoid using non-ASCII symbols in code, unless it significantly improves clarity, avoid emojis in any case. -When there are differences between the guidelines above and the formatting -generated by code formatting tools, the guidelines above take precedence. +Use these coding guidelines to ensure that your development complies with the +project's style and naming conventions. The Linux kernel GPL-licensed tool ``checkpatch`` is used to check coding style conformity. @@ -506,8 +590,102 @@ before pushing on zephyr repo. To do this, make the file If you want to override checkpatch verdict and push you branch despite reported issues, you can add option --no-verify to the git push command. -A more complete alternative to this is using check_compliance.py script from -ci-tools repo. +A more complete alternative to this is using :ref:`check_compliance_py` script. + +clang-format +------------ + +The `clang-format tool `_ can +be helpful to quickly reformat large amounts of new source code to our +`Coding Style`_ standards together with the ``.clang-format`` configuration file +provided in the repository. ``clang-format`` is well integrated into most +editors, but you can also run it manually like this: + +.. code-block:: bash + + clang-format -i my_source_file.c + +``clang-format`` is part of LLVM, which can be downloaded from the project +`releases page `_. Note that if +you are a Linux user, ``clang-format`` will likely be available as a package in +your distribution repositories. + +When there are differences between the `Coding Style`_ guidelines and the +formatting generated by code formatting tools, the `Coding Style`_ guidelines +take precedence. If there is ambiguity between formatting tools and the +guidelines, maintainers may decide which style should be adopted. + +.. _Continuous Integration: + +Continuous Integration (CI) +=========================== + +The Zephyr Project operates a Continuous Integration (CI) system that runs on +every Pull Request (PR) in order to verify several aspects of the PR: + +* Git commit formatting +* Coding Style +* Twister builds for multiple architectures and boards +* Documentation build to verify any doc changes + +CI is run on Github Actions and it uses the same tools described in the +`CI Tests`_ section. The CI results must be green indicating "All +checks have passed" before the Pull Request can be merged. CI is run when the +PR is created, and again every time the PR is modified with a commit. + +The current status of the CI run can always be found at the bottom of the +GitHub PR page, below the review status. Depending on the success or failure +of the run you will see: + +* "All checks have passed" +* "All checks have failed" + +In case of failure you can click on the "Details" link presented below the +failure message in order to navigate to ``Github Actions`` and inspect the +results. +Once you click on the link you will be taken to the ``Github actions`` summary +results page where a table with all the different builds will be shown. To see +what build or test failed click on the row that contains the failed (i.e. +non-green) build. + +.. _CI Tests: + +Running CI Tests Locally +======================== + +.. _check_compliance_py: + +check_compliance.py +------------------- + +The ``check_compliance.py`` script serves as a valuable tool for assessing code +compliance with Zephyr's established guidelines and best practices. The script +acts as wrapper for a suite of tools that performs various checks, including +linters and formatters. + +Developers are encouraged to run the script locally to validate their changes +before opening a new Pull Request: + +.. code-block:: bash + + ./scripts/ci/check_compliance.py -c upstream/main.. + +twister +------- + +.. note:: + twister is only fully supported on Linux; on Windows and MacOS the execution + of tests is not supported, only building. + +If you think your change may break some test, you can submit your PR as a draft +and let the project CI automatically run the :ref:`twister_script` for you. + +If a test fails, you can check from the CI run logs how to rerun it locally, +for example: + +.. code-block:: bash + + west twister -p native_sim -s tests/drivers/build_all/sensor/sensors.generic_test .. _static_analysis: @@ -560,8 +738,6 @@ it after completing the steps above on scan service website. Any issues closed without a fix or without ignoring the entry in the scan service will be automatically reopened if the issue continues to be present in the code. -.. _Contribution Tools: - .. _Contribution workflow: Contribution Workflow @@ -687,13 +863,7 @@ workflow here: and use the same process described above to work on this new topic branch. #. If reviewers do request changes to your patch, you can interactively rebase - commit(s) to fix review issues. In your development repo:: - - git fetch --all - git rebase --ignore-whitespace upstream/main - - The ``--ignore-whitespace`` option stops ``git apply`` (called by rebase) - from changing any whitespace. Continuing:: + commit(s) to fix review issues. In your development repo:: git rebase -i ^ @@ -715,6 +885,17 @@ workflow here: By force pushing your update, your original pull request will be updated with your changes so you won't need to resubmit the pull request. +#. After pushing the requested change, check on the PR page if there is a + merge conflict. If so, rebase your local branch:: + + git fetch --all + git rebase --ignore-whitespace upstream/main + + The ``--ignore-whitespace`` option stops ``git apply`` (called by rebase) + from changing any whitespace. Resolve the conflicts and push again:: + + git push --force origin fix_comment_typo + .. note:: While amending commits and force pushing is a common review model outside GitHub, and the one recommended by Zephyr, it's not the main model supported by GitHub. Forced pushes can cause unexpected behavior, @@ -729,151 +910,41 @@ workflow here: Additional information about the CI system can be found in `Continuous Integration`_. -.. _commit-guidelines: - -Commit Message Guidelines -************************* - -Changes are submitted as Git commits. Each commit has a *commit -message* describing the change. Acceptable commit messages look like -this: - -.. code-block:: none - - [area]: [summary of change] - - [Commit message body (must be non-empty)] - - Signed-off-by: [Your Full Name] <[your.email@address]> - -You need to change text in square brackets (``[like this]``) above to -fit your commit. - -Examples and more details follow. - -Example -======= - -Here is an example of a good commit message. - -.. code-block:: none - - drivers: sensor: abcd1234: fix bus I/O error handling - - The abcd1234 sensor driver is failing to check the flags field in - the response packet from the device which signals that an error - occurred. This can lead to reading invalid data from the response - buffer. Fix it by checking the flag and adding an error path. +.. _contribution_tips: - Signed-off-by: Zephyr Developer +Contribution Tips +================= -[area]: [summary of change] -=========================== +The following is a list of tips to improve and accelerate the review process of +Pull Requests. If you follow them, chances are your pull request will get the +attention needed and it will be ready for merge sooner than later: -This line is called the commit's *title*. Titles must be: +.. _git-rebase: + https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---keep-base -* one line -* less than 72 characters long -* followed by a completely blank line +#. When pushing follow-up changes, use the ``--keep-base`` option of + `git-rebase`_ -[area] - The ``[area]`` prefix usually identifies the area of code - being changed. It can also identify the change's wider - context if multiple areas are affected. +#. On the PR page, check if the change can still be merged with no merge + conflicts - Here are some examples: +#. Make sure title of PR explains what is being fixed or added - * ``doc: ...`` for documentation changes - * ``drivers: foo:`` for ``foo`` driver changes - * ``Bluetooth: Shell:`` for changes to the Bluetooth shell - * ``net: ethernet:`` for Ethernet-related networking changes - * ``dts:`` for treewide devicetree changes - * ``style:`` for code style changes +#. Make sure your PR has a body with more details about the content of your + submission - If you're not sure what to use, try running ``git log FILE``, where - ``FILE`` is a file you are changing, and using previous commits that - changed the same file as inspiration. +#. Make sure you reference the issue you are fixing in the body of the PR -[summary of change] - The ``[summary of change]`` part should be a quick description of - what you've done. Here are some examples: +#. Watch early CI results immediately after submissions and fix issues as they + are discovered - * ``doc: update wiki references to new site`` - * ``drivers: sensor: sensor_shell: fix channel name collision`` +#. Revisit PR after 1-2 hours to see the status of all CI checks, make sure all + is green -Commit Message Body -=================== +#. If you get request for changes and submit a change to address them, make + sure you click the "Re-request review" button on the GitHub UI to notify + those who asked for the changes -.. warning:: - - An empty commit message body is not permitted. Even for trivial - changes, please include a descriptive commit message body. Your - pull request will fail CI checks if you do not. - -This part of the commit should explain what your change does, and why -it's needed. Be specific. A body that says ``"Fixes stuff"`` will be -rejected. Be sure to include the following as relevant: - -* **what** the change does, -* **why** you chose that approach, -* **what** assumptions were made, and -* **how** you know it works -- for example, which tests you ran. - -Each line in your commit message should usually be 75 characters or -less. Use newlines to wrap longer lines. Exceptions include lines -with long URLs, email addresses, etc. - -For examples of accepted commit messages, you can refer to the Zephyr GitHub -`changelog `__. - -If the change addresses a GitHub issue, include a line of the form: - -.. code-block:: none - - Fixes #[issue number] - -Where ``[issue number]`` is the relevant GitHub issue's number. For -example: - -.. code-block:: none - - Fixes: #1234 - -Signed-off-by: ... -================== - -.. tip:: - - You should have set your :ref:`git-name-and-email` - already. Create your commit with ``git commit -s`` to add the - Signed-off-by: line automatically using this information. - -For open source licensing reasons, your commit must include a -Signed-off-by: line that looks like this: - -.. code-block:: none - - Signed-off-by: [Your Full Name] <[your.email@address]> - -For example, if your full name is ``Zephyr Developer`` and your email -address is ``z.developer@example.com``: - -.. code-block:: none - - Signed-off-by: Zephyr Developer - -This means that you have personally made sure your change complies -with the :ref:`DCO`. For this reason, you must use your legal name. -Pseudonyms or "hacker aliases" are not permitted. - -Your name and the email address you use must match the name and email -in the Git commit's ``Author:`` field. - -Other Commit Expectations -========================= - -See the :ref:`contributor-expectations` for a more complete discussion of -contributor and reviewer expectations. Submitting Proposals ==================== @@ -930,38 +1001,6 @@ For example, a copy of an externally maintained import in a module repository:: commit: 08ded7f21529c39e5133688ffb93a9d0c94e5c6e Purpose: Introduction of TinyCrypt - -Continuous Integration (CI) -*************************** - -The Zephyr Project operates a Continuous Integration (CI) system that runs on -every Pull Request (PR) in order to verify several aspects of the PR: - -* Git commit formatting -* Coding Style -* Twister builds for multiple architectures and boards -* Documentation build to verify any doc changes - -CI is run on Github Actions and it uses the same tools described in the -`Contribution Tools`_ section. The CI results must be green indicating "All -checks have passed" before the Pull Request can be merged. CI is run when the -PR is created, and again every time the PR is modified with a commit. - -The current status of the CI run can always be found at the bottom of the -GitHub PR page, below the review status. Depending on the success or failure -of the run you will see: - -* "All checks have passed" -* "All checks have failed" - -In case of failure you can click on the "Details" link presented below the -failure message in order to navigate to ``Github Actions`` and inspect the -results. -Once you click on the link you will be taken to the ``Github actions`` summary -results page where a table with all the different builds will be shown. To see -what build or test failed click on the row that contains the failed (i.e. -non-green) build. - Contributions to External Modules ********************************** diff --git a/doc/develop/api/terminology.rst b/doc/develop/api/terminology.rst index dacf937727237d..593ce5929f45ba 100644 --- a/doc/develop/api/terminology.rst +++ b/doc/develop/api/terminology.rst @@ -184,7 +184,7 @@ Explanation Be aware that **async** is orthogonal to context-switching. Some APIs may provide completion information through a callback, but may suspend while waiting for the resource necessary to initiate the operation; an -example is :c:func:`spi_transceive_async`. +example is :c:func:`spi_transceive_signal`. If a function is both **no-wait** and **async** then selecting the no-wait path only guarantees that the function will not sleep. It does diff --git a/doc/develop/flash_debug/probes.rst b/doc/develop/flash_debug/probes.rst index 0e237a6fcf63f5..652db3be5ea289 100644 --- a/doc/develop/flash_debug/probes.rst +++ b/doc/develop/flash_debug/probes.rst @@ -23,33 +23,42 @@ flash programmer. This eliminates the need to purchase an external debug probe and provides a variety of debug host tool options. Several hardware vendors have their own branded onboard debug probe -implementations: NXP LPC boards have `LPC-Link2 <#lpclink2-jlink-onboard-debug-probe>`_, -NXP Kinetis (former Freescale) boards have `OpenSDA <#opensda-daplink-onboard-debug-probe>`_, -and ST boards have `ST-LINK <#stlink-v21-onboard-debug-probe>`_. Each onboard debug probe -microcontroller can support one or more types of firmware that communicate with -their respective debug host tools. For example, an OpenSDA microcontroller can -be programmed with DAPLink firmware to communicate with pyOCD or OpenOCD debug -host tools, or with J-Link firmware to communicate with J-Link debug host -tools. - - -+------------------------------------------+------------------------------------------------------------------------------------+ -|| *Debug Probes & Host Tools* | Host Tools | -+| *Compatibility Chart* +--------------------+--------------------+---------------------+--------------------+ -| | **J-Link Debug** | **OpenOCD** | **pyOCD** | **NXP S32DS** | -+----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+ -| | **LPC-Link2 J-Link** | ✓ | | | | -| +-------------------------+--------------------+--------------------+---------------------+--------------------+ -| | **OpenSDA DAPLink** | | ✓ | ✓ | | -| +-------------------------+--------------------+--------------------+---------------------+--------------------+ -| Debug Probes | **OpenSDA J-Link** | ✓ | | | | -| +-------------------------+--------------------+--------------------+---------------------+--------------------+ -| | **J-Link External** | ✓ | ✓ | | | -| +-------------------------+--------------------+--------------------+---------------------+--------------------+ -| | **ST-LINK/V2-1** | ✓ | ✓ | *some STM32 boards* | | -| +-------------------------+--------------------+--------------------+---------------------+--------------------+ -| | **NXP S32 Debug Probe** | | | | ✓ | -+----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+ +implementations: NXP boards may use +`OpenSDA <#opensda-daplink-onboard-debug-probe>`_, +`LPC-Link2 <#lpclink2-jlink-onboard-debug-probe>`_, or +`MCU-Link <#mcu-link-cmsis-onboard-debug-probe>`_, probes depending on +the microcontroller the debug probe firmware runs on. +ST boards have the `ST-LINK probe <#stlink-v21-onboard-debug-probe>`_. Each +onboard debug probe microcontroller can support one or more types of firmware +that communicate with their respective debug host tools. For example, an +OpenSDA microcontroller can be programmed with DAPLink firmware to communicate +with pyOCD or OpenOCD debug host tools, or with J-Link firmware to communicate +with J-Link debug host tools. + + ++------------------------------------------+---------------------------------------------------------------------------------------------------------+ +|| *Debug Probes & Host Tools* | Host Tools | ++| *Compatibility Chart* +--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **J-Link Debug** | **OpenOCD** | **pyOCD** | **NXP S32DS** | **NXP LinkServer** | ++----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **J-Link External** | ✓ | ✓ | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **LPC-Link2 CMSIS-DAP** | | | | | ✓ | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **LPC-Link2 J-Link** | ✓ | | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **MCU-Link CMSIS-DAP** | | | | | ✓ | +| Debug Probes +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **MCU-Link J-Link** | ✓ | | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **NXP S32 Debug Probe** | | | | ✓ | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **OpenSDA DAPLink** | | ✓ | ✓ | | ✓ | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **OpenSDA J-Link** | ✓ | | | | | +| +-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ +| | **ST-LINK/V2-1** | ✓ | ✓ | *some STM32 boards* | | | ++----------------+-------------------------+--------------------+--------------------+---------------------+--------------------+--------------------+ Some supported boards in Zephyr do not include an onboard debug probe and @@ -60,15 +69,49 @@ onboard debug probe may have limitations, such as lack of support for advanced debuggers or high-speed tracing. You may need to adjust jumpers to prevent the onboard debug probe from interfering with the external debug probe. +.. _nxp-onboard-debug-probes: + +NXP Onboard Debug Probes +************************ + +NXP boards may have one of several onboard debug probes. These probes include +the :ref:`mcu-link-onboard-debug-probe`, :ref:`lpc-link2-onboard-debug-probe` +and :ref:`opensda-onboard-debug-probe`. Each of these probes is implemented +as a secondary microcontroller present on the evaluation board. The specific +debug probe type present on a given board can be determined based on the +debug microcontroller SOC: + +- LPC55S69: :ref:`mcu-link-onboard-debug-probe` +- LPC4322: :ref:`lpc-link2-onboard-debug-probe` +- MK20: :ref:`opensda-onboard-debug-probe` + +For example, the :ref:`frdm_k64f` board has an MK20 debug microcontroller, +so this board uses the :ref:`opensda-onboard-debug-probe`. + +.. _mcu-link-onboard-debug-probe: + +MCU-Link Onboard Debug Probe +**************************** + +The MCU-Link onboard debug probe uses an LPC55S69 SOC. This probe supports +the following firmwares: + +- :ref:`mcu-link-cmsis-onboard-debug-probe` (default firmware) +- :ref:`mcu-link-jlink-onboard-debug-probe` + +This probe is programmed using the MCU-Link host tools, which are installed +with the :ref:`linkserver-debug-host-tools`. NXP recommends using NXP's +`MCUXpresso Installer`_ to install the Linkserver tools. + .. _mcu-link-cmsis-onboard-debug-probe: MCU-Link CMSIS-DAP Onboard Debug Probe -*************************************** +====================================== -The CMSIS-DAP debug probes allow debugging from any compatible toolchain, -including IAR EWARM, Keil MDK, NXP’s MCUXpresso IDE and -MCUXpresso extension for VS Code. In addition to debug probe functionality, the -MCU-Link probes may also provide: +This is the default firmware installed on MCU-Link debug probes. The CMSIS-DAP +debug probes allow debugging from any compatible toolchain, including IAR +EWARM, Keil MDK, NXP’s MCUXpresso IDE and MCUXpresso extension for VS Code. In +addition to debug probe functionality, the MCU-Link probes may also provide: 1. SWO trace end point: this virtual device is used by MCUXpresso to retrieve SWO trace data. See the MCUXpresso IDE documentation for more information. @@ -81,13 +124,13 @@ This debug probe is compatible with the following debug host tools: - :ref:`linkserver-debug-host-tools` -This probe is realized by programming the MCU-Link microcontroller with the -CMSIS-DAP MCU-Link firmware, which is already installed by default. NXP -recommends using NXP's `MCUXpresso Installer`_, which installs both the MCU-Link -host tools plus the :ref:`linkserver-debug-host-tools`. +Once the MCU-Link host tools are installed, the following steps are +required to program the CMSIS-DAP firmware: 1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. + jumper then connecting to the USB debug port on the board. This jumper may + also be referred to as the ISP jumper, and will be connected to ``PIO0_5`` + on the LPC55S69. #. Run the ``program_CMSIS`` script, found in the installed MCU-Link ``scripts`` folder. @@ -97,31 +140,48 @@ host tools plus the :ref:`linkserver-debug-host-tools`. .. _mcu-link-jlink-onboard-debug-probe: MCU-Link JLink Onboard Debug Probe -************************************ - -The MCU-Link J-Link is an onboard debug probe and usb-to-serial adapter -supported on many NXP development boards. +================================== -This debug probe is compatible with the following debug host tools: +This debug probe firmware provides a JLink compatible debug interface, +as well as a USB-Serial adapter. It is compatible with the following debug host +tools: - :ref:`jlink-debug-host-tools` These probes do not have JLink firmware installed by default, and must be -updated. NXP recommends using NXP's `MCUXpresso Installer`_, which installs both -the :ref:`jlink-debug-host-tools` plus the MCU-Link host tools. +updated. Once the MCU-Link host tools are installed, the following steps are +required to program the JLink firmware: 1. Put the MCU-Link microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. + jumper then connecting to the USB debug port on the board. This jumper may + also be referred to as the ISP jumper, and will be connected to ``PIO0_5`` + on the LPC55S69. #. Run the ``program_JLINK`` script, found in the installed MCU-Link ``scripts`` folder. #. Remove the DFU jumper and power cycle the board. +.. _lpc-link2-onboard-debug-probe: + +LPC-LINK2 Onboard Debug Probe +***************************** + +The LPC-LINK2 onboard debug probe uses an LPC4322 SOC. This probe supports +the following firmwares: + +- :ref:`lpclink2-cmsis-onboard-debug-probe` +- :ref:`lpclink2-jlink-onboard-debug-probe` +- :ref:`lpclink2-daplink-onboard-debug-probe` (default firmware) + +This probe is programmed using the LPCScrypt host tools, which are installed +with the :ref:`linkserver-debug-host-tools`. NXP recommends using NXP's +`MCUXpresso Installer`_ to install the Linkserver tools. + .. _lpclink2-cmsis-onboard-debug-probe: LPC-LINK2 CMSIS DAP Onboard Debug Probe -*************************************** +======================================= The CMSIS-DAP debug probes allow debugging from any compatible toolchain, including IAR EWARM, Keil MDK, as well as NXP’s MCUXpresso IDE and @@ -134,57 +194,83 @@ provide: 2. Virtual COM (VCOM) port / UART bridge connected to the target processor 3. LPCSIO bridge that provides communication to I2C and SPI slave devices -This probe is realized by programming the LPC-Link2 microcontroller with the CMSIS-DAP -LPC-Link2 firmware. Download and install `LPCScrypt`_ to get the firmware and -programming scripts. +This debug probe firmware is compatible with the following debug host tools: -.. note:: Verify the firmware supports your board by visiting `Firmware for LPCXpresso`_ +- :ref:`linkserver-debug-host-tools` + +After installing the LPCScrypt host tools, the firmware may be updated to +use CMSIS-DAP firmware with the following steps: 1. Put the LPC-Link2 microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. + jumper, then then connecting to the USB debug port on the board. This + jumper is connected to ``P2_6`` on the LPC4322 SOC. -#. Run the ``program_CMSIS`` script. +#. Run the ``program_CMSIS`` script, found in the installed LPCScrypt ``scripts`` + folder. #. Remove the DFU jumper and power cycle the board. .. _lpclink2-jlink-onboard-debug-probe: LPC-Link2 J-Link Onboard Debug Probe -************************************ +==================================== -The LPC-Link2 J-Link is an onboard debug probe and usb-to-serial adapter -supported on many NXP LPC and i.MX RT development boards. +.. note:: On some boards, the J-Link probe firmware will no longer power the + board via the USB debug port. On these boards, an alternative method + of powering the board must be used when this firmware is programmed. -This debug probe is compatible with the following debug host tools: +This debug probe firmware provides a JLink compatible debug interface, +as well as a USB-Serial adapter. It is compatible with the following debug host +tools: - :ref:`jlink-debug-host-tools` -This probe is realized by programming the LPC-Link2 microcontroller with J-Link -LPC-Link2 firmware. Download and install `LPCScrypt`_ to get the firmware and -programming scripts. +After installing the LPCScrypt host tools, the firmware may be updated to +use CMSIS-DAP firmware with the following steps: .. note:: Verify the firmware supports your board by visiting `Firmware for LPCXpresso`_ 1. Put the LPC-Link2 microcontroller into DFU boot mode by attaching the DFU - jumper, then powering up the board. + jumper, then then connecting to the USB debug port on the board. This + jumper is connected to ``P2_6`` on the LPC4322 SOC. -#. Run the ``program_JLINK`` script. +#. Run the ``program_JLINK`` script, found in the installed LPCScrypt ``scripts`` + folder. #. Remove the DFU jumper and power cycle the board. +.. _lpclink2-daplink-onboard-debug-probe: + +LPC-Link2 DAPLink Onboard Debug Probe +===================================== + +The LPC-Link2 DAPLink firmware is the default firmware shipped on LPC-Link2 +based boards, but is not the recommended firmware. Users should update to +the :ref:`lpclink2-cmsis-onboard-debug-probe` firmware following the +instructions provided above. For details on programming the DAPLink firmware, +see `NXP AN13206`_. + +.. _opensda-onboard-debug-probe: + +OpenSDA Onboard Debug Probe +*************************** + +The OpenSDA onboard debug probe is based on the NXP MK20 SOC. It features +drag and drop programming supports, and supports the following debug firmwares: + +- :ref:`opensda-daplink-onboard-debug-probe` (default firmware) +- :ref:`opensda-jlink-onboard-debug-probe` + .. _opensda-daplink-onboard-debug-probe: OpenSDA DAPLink Onboard Debug Probe -*********************************** - -The OpenSDA DAPLink is an onboard debug probe and usb-to-serial adapter -supported on many NXP Kinetis and i.MX RT development boards. It also includes -drag-and-drop flash programming support. +=================================== -This debug probe is compatible with the following debug host tools: +This debug probe firmware is compatible with the following debug host tools: - :ref:`pyocd-debug-host-tools` - :ref:`openocd-debug-host-tools` +- :ref:`linkserver-debug-host-tools` This probe is realized by programming the OpenSDA microcontroller with DAPLink OpenSDA firmware. NXP provides `OpenSDA DAPLink Board-Specific Firmwares`_. @@ -199,7 +285,10 @@ As with all OpenSDA debug probes, the steps for programming the firmware are: microcontroller of your Zephyr application. #. After you power on the board, release the reset button. A USB mass storage - device called **BOOTLOADER** or **MAINTENANCE** will enumerate. + device called **BOOTLOADER** or **MAINTENANCE** will enumerate. If the + enumerated device is named **BOOTLOADER**, please first update the booloader + to the latest revision by following the instructions for a + `DAPLink Bootloader Update`_. #. Copy the OpenSDA firmware binary to the USB mass storage device. @@ -211,10 +300,7 @@ As with all OpenSDA debug probes, the steps for programming the firmware are: .. _opensda-jlink-onboard-debug-probe: OpenSDA J-Link Onboard Debug Probe -********************************** - -The OpenSDA J-Link is an onboard debug probe and usb-to-serial adapter -supported on many NXP Kinetis and i.MX RT development boards. +================================== This debug probe is compatible with the following debug host tools: @@ -232,12 +318,15 @@ Install the debug host tools before you program the firmware. As with all OpenSDA debug probes, the steps for programming the firmware are: 1. Put the OpenSDA microcontroller into bootloader mode by holding the reset - button while you power on the board. Note that "bootloader mode" in this - context applies to the OpenSDA microcontroller itself, not the target - microcontroller of your Zephyr application. + button while you plug a USB into the board's USB debug port. Note that + "bootloader mode" in this context applies to the OpenSDA microcontroller + itself, not the target microcontroller of your Zephyr application. #. After you power on the board, release the reset button. A USB mass storage - device called **BOOTLOADER** or **MAINTENANCE** will enumerate. + device called **BOOTLOADER** or **MAINTENANCE** will enumerate. If the + enumerated device is named **BOOTLOADER**, please first update the booloader + to the latest revision by following the instructions for a + `DAPLink Bootloader Update`_. #. Copy the OpenSDA firmware binary to the USB mass storage device. @@ -421,3 +510,9 @@ the firmware. .. _NXP S32 Debug Probe: https://www.nxp.com/design/software/automotive-software-and-tools/s32-debug-probe:S32-DP + +.. _NXP AN13206: + https://www.nxp.com/docs/en/application-note/AN13206.pdf + +.. _DAPLink Bootloader Update: + https://os.mbed.com/blog/entry/DAPLink-bootloader-update/ diff --git a/doc/develop/languages/cpp/index.rst b/doc/develop/languages/cpp/index.rst index 492872d7e9ca47..d075a47319b29e 100644 --- a/doc/develop/languages/cpp/index.rst +++ b/doc/develop/languages/cpp/index.rst @@ -121,5 +121,133 @@ library can select, from its config, compatible C++ standard library unless the Kconfig symbol for a specific C++ standard library is selected. +Header files and incompatibilities between C and C++ +**************************************************** + +To interact with each other, C and C++ must share code through header +files: data structures, macros, static functions,... While C and C++ +have a large overlap, they're different languages with `known +incompatibilities`_. C is not just a C++ subset. Standard levels (e.g.: +"C+11") add another level of complexity as new features are often +inspired by and copied from the other language but many years later and +with subtle differences. Making things more complex, compilers often +offer early prototypes of features before they become +standardized. Standards can have ambiguities interpreted differently by +different compilers. Compilers can have bugs and these may need +workarounds. To help with this, many projects restrict themselves to a +limited number of toolchains. Zephyr does not. + +These compatibility issues affect header files dis-proportionally. Not +just because they have to be compatible between C and C++, but also +because they end up being compiled in a surprisingly high number of other +source files due to *indirect* inclusion and the `lack of structure and +headers organization`_ that is typical in real-world projects. So, header +files are exposed to a much larger variety of toolchains and project +configurations. +Adding more constraints, the Zephyr project has demanding policies +with respect to code style, compiler warnings, static analyzers and +standard compliance (e.g.: MISRA). + +Put together, all these constraints can make writing header files very +challenging. The purpose of this section is to document some best "header +practices" and lessons learned in a Zephyr-specific context. While a lot +of the information here is not Zephyr-specific, this section is not a +substitute for knowledge of C/C++ standards, textbooks and other +references. + +Testing +------- + +Fortunately, the Zephyr project has an extensive test and CI +infrastructure that provides coverage baselines, catches issues early, +enforces policies and maintains such combinatorial explosions under some +control. The ``tests/lib/cpp/cxx/`` are very useful in this context +because their ``testcase.yaml`` configuration lets ``twister`` iterate +quickly over a range of ``-std`` parameters: ``-std=c++98``, +``-std=c++11``, etc. + +Keep in mind unused macros are not compiled. + +Designated initializers +----------------------- + +Initialization macros are common in header files as they help reduce +boilerplate code. C99 added initialization of ``struct`` and ``union`` +types by "designated" member names instead of a list of *bare* +expressions. Some GCC versions support designated initializers even in +their C90 mode. + +When used at a simple level, designated initializers are less +error-prone, more readable and more flexible. On the other hand, C99 +allowed a surprisingly large and lax set of possibilities: designated +initializers can be out of order, duplicated, "nested" (``.a.x =``), +various other braces can be omitted, designated initializers and not can +be mixed, etc. + +Twenty years later, C++20 added designated initializers to C++ but in +much more restricted way; partly because a C++ ``struct`` is actually a +``class``. As described in the C++ proposal number P0329 (which compares +with C) or in any complete C++ reference, a mix is not allowed and +initializers must be in order (gaps are allowed). + +Interestingly, the new restrictions in C++20 can cause ``gcc -std=c++20`` +to fail to compile code that successfully compiles with +``gcc -std=c++17``. For example, ``gcc -std=c++17`` and older allow the +C-style mix of initializers and bare expressions. This fails to compile +with using ``gcc -std=c++20`` *with the same GCC version*. + +Recommendation: to maximize compatibility across different C and C++ +toolchains and standards, designated initializers in Zephyr header files +should follow all C++20 rules and restrictions. Non-designated, pre-C99 +initialization offers more compatibility and is also allowed but +designated initialization is the more readable and preferred code +style. In any case, both styles must never be mixed in the same +initializer. + +Warning: successful compilation is not the end of the incompatibility +story. For instance, the *evaluation order* of initializer expressions is +unspecified in C99! It is the (expected) left-to-right order in +C++20. Other standard revisions may vary. In doubt, do not rely on +evaluation order (here and elsewhere). + +Anonymous unions +---------------- + +Anonymous unions (a.k.a. "unnamed" unions) seem to have been part of C++ +from its very beginning. They were not officially added to C until C11. +As usual, there are differences between C and C++. For instance, C +supports anonymous unions only as a member of an enclosing ``struct`` or +``union``, empty lists ``{ }`` have always been allowed in C++ but they +require C23, etc. + +When initializing anonymous members, the expression can be enclosed in +braces or not. It can be either designated or bare. For maximum +portability, when initializing *anonymous unions*: + +- Do *not* enclose *designated* initializers with braces. This is + required by C++20 and above which perceive such braces as mixing bare + expressions with (other) designated initializers and fails to compile. + +- Do enclose *bare* expressions with braces. This is required by C. + Maybe because C is laxer and allows many initialization possibilities + and variations, so it may need such braces to disambiguate? Note C + does allow omitting most braces in initializer expressions - but not + in this particular case of initializing anonymous unions with bare + expressions. + +Some pre-C11 GCC versions support some form of anonymous unions. They +unfortunately require enclosing their designated initializers with +braces which conflicts with this recommendation. This can be solved +with an ``#ifdef __STDC_VERSION__`` as demonstrated in Zephyr commit +`c15f029a7108 +`_ and +the corresponding code review. + + .. _`C++ Standard Library`: https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library .. _`Standard Template Library (STL)`: https://en.wikipedia.org/wiki/Standard_Template_Library +.. _`known incompatibilities`: https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B +.. _`lack of structure and headers organization`: + https://github.com/zephyrproject-rtos/zephyr/issues/41543 +.. _`gcc commit [C++ PATCH] P0329R4: Designated Initialization`: + https://gcc.gnu.org/pipermail/gcc-patches/2017-November/487584.html diff --git a/doc/develop/optimizations/tools.rst b/doc/develop/optimizations/tools.rst index f892209250960f..630696c9f1b426 100644 --- a/doc/develop/optimizations/tools.rst +++ b/doc/develop/optimizations/tools.rst @@ -229,32 +229,32 @@ as in the following example. Pahole will generate something similar to the output below in the console:: - /* Used at: zephyr/isr_tables.c */ - /* <80> ../include/sw_isr_table.h:30 */ - struct _isr_table_entry { - void * arg; /* 0 4 */ - void (*isr)(void *); /* 4 4 */ + /* Used at: [...]/build/zephyr/kobject_hash.c */ + /* <375> [...]/zephyr/include/zephyr/sys/dlist.h:37 */ + union { + struct _dnode * head; /* 0 4 */ + struct _dnode * next; /* 0 4 */ + }; + /* Used at: [...]/build/zephyr/kobject_hash.c */ + /* <397> [...]/zephyr/include/zephyr/sys/dlist.h:36 */ + struct _dnode { + union { + struct _dnode * head; /* 0 4 */ + struct _dnode * next; /* 0 4 */ + }; /* 0 4 */ + union { + struct _dnode * tail; /* 4 4 */ + struct _dnode * prev; /* 4 4 */ + }; /* 4 4 */ /* size: 8, cachelines: 1, members: 2 */ /* last cacheline: 8 bytes */ }; - /* Used at: zephyr/isr_tables.c */ - /* ../include/arch/arm/aarch32/cortex_m/mpu/arm_mpu_v7m.h:134 */ - struct arm_mpu_region_attr { - uint32_t rasr; /* 0 4 */ - - /* size: 4, cachelines: 1, members: 1 */ - /* last cacheline: 4 bytes */ - }; - /* Used at: zephyr/isr_tables.c */ - /* <112> ../include/arch/arm/aarch32/cortex_m/mpu/arm_mpu.h:24 */ - struct arm_mpu_region { - uint32_t base; /* 0 4 */ - const char * name; /* 4 4 */ - arm_mpu_region_attr_t attr; /* 8 4 */ - - /* size: 12, cachelines: 1, members: 3 */ - /* last cacheline: 12 bytes */ + /* Used at: [...]/build/zephyr/kobject_hash.c */ + /* <3b7> [...]/zephyr/include/zephyr/sys/dlist.h:41 */ + union { + struct _dnode * tail; /* 0 4 */ + struct _dnode * prev; /* 0 4 */ }; ... ... diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 3be0132b05cd7d..4773a3e3466e2d 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -1082,6 +1082,10 @@ can be used multiple times and all given fixtures will be appended as a list. An given fixtures will be assigned to all boards, this means that all boards set by current twister command can run those testcases which request the same fixtures. +Some fixtures allow for configuration strings to be appended, separated from the +fixture name by a ``:``. Only the fixture name is matched against the fixtures +requested by testcases. + Notes +++++ diff --git a/doc/develop/test/ztest.rst b/doc/develop/test/ztest.rst index 124fd415c2306f..e8bf8f43f07159 100644 --- a/doc/develop/test/ztest.rst +++ b/doc/develop/test/ztest.rst @@ -351,6 +351,20 @@ efforts into the specific module in question. This will speed up testing since only the module will have to be compiled in, and the tested functions will be called directly. +Examples of unit tests can be found in the :zephyr_file:`tests/unit/` folder. +In order to declare the unit tests present in a source folder, you need to add +the relevant source files to the ``testbinary`` target from the CMake +:zephyr_file:`unittest ` component. See a minimal +example below: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.20.0) + + project(app) + find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE}) + target_sources(testbinary PRIVATE main.c) + Since you won't be including basic kernel data structures that most code depends on, you have to provide function stubs in the test. Ztest provides some helpers for mocking functions, as demonstrated below. @@ -361,7 +375,7 @@ interaction with an object occurred, and if required, to assert the order of that interaction. Best practices for declaring the test suite -=========================================== +******************************************* *twister* and other validation tools need to obtain the list of subcases that a Zephyr *ztest* test image will expose. @@ -443,9 +457,9 @@ Configuration Static configuration of Ztress contains: - - :c:macro:`ZTRESS_MAX_THREADS` - number of supported threads. - - :c:macro:`ZTRESS_STACK_SIZE` - Stack size of created threads. - - :c:macro:`ZTRESS_REPORT_PROGRESS_MS` - Test progress report interval. + - :kconfig:option:`CONFIG_ZTRESS_MAX_THREADS` - number of supported threads. + - :kconfig:option:`CONFIG_ZTRESS_STACK_SIZE` - Stack size of created threads. + - :kconfig:option:`CONFIG_ZTRESS_REPORT_PROGRESS_MS` - Test progress report interval. API reference ************* diff --git a/doc/develop/tools/clion.rst b/doc/develop/tools/clion.rst index d72e2ed28d6a2d..2bb5cb56995bc7 100644 --- a/doc/develop/tools/clion.rst +++ b/doc/develop/tools/clion.rst @@ -58,10 +58,12 @@ not happen, go to :menuselection:`Settings --> Build, Execution, Deployment --> #. Click :menuselection:`Add environment --> From file` and select ``..\.venv\Scripts\activate.bat``. - .. figure:: img/clion_toolchain_mingw.webp - :width: 600px - :align: center - :alt: MinGW toolchain with environment script + .. only:: html + + .. figure:: img/clion_toolchain_mingw.webp + :width: 600px + :align: center + :alt: MinGW toolchain with environment script Click :guilabel:`Apply` to save the changes. @@ -72,10 +74,12 @@ not happen, go to :menuselection:`Settings --> Build, Execution, Deployment --> -DBOARD=nrf52840dk/nrf52840 - .. figure:: img/clion_cmakeprofile.webp - :width: 600px - :align: center - :alt: CMake profile + .. only:: html + + .. figure:: img/clion_cmakeprofile.webp + :width: 600px + :align: center + :alt: CMake profile #. Click :guilabel:`Apply` to save the changes. @@ -166,17 +170,21 @@ your setup is different, make sure to adjust the configuration settings accordin * - :guilabel:`TCP/IP port` - Auto - .. figure:: img/clion_gdbserverconfig.webp - :width: 500px - :align: center - :alt: Embedded GDB server configuration + .. only:: html + + .. figure:: img/clion_gdbserverconfig.webp + :width: 500px + :align: center + :alt: Embedded GDB server configuration #. Click :guilabel:`Next` to set the Segger J-Link parameters. - .. figure:: img/clion_segger_settings.webp - :width: 500px - :align: center - :alt: Segger J-Link parameters + .. only:: html + + .. figure:: img/clion_segger_settings.webp + :width: 500px + :align: center + :alt: Segger J-Link parameters #. Click :guilabel:`Create` when ready. @@ -193,10 +201,12 @@ Start debugging Zephyr tasks are listed in the :guilabel:`Threads & Variables` pane. You can switch between them and inspect the variables for each task. - .. figure:: img/clion_debug_threads.webp - :width: 800px - :align: center - :alt: Viewing Zephyr tasks during a debug session + .. only:: html + + .. figure:: img/clion_debug_threads.webp + :width: 800px + :align: center + :alt: Viewing Zephyr tasks during a debug session Refer to `CLion web help`_ for detailed description of the IDE debug capabilities. diff --git a/doc/develop/tools/index.rst b/doc/develop/tools/index.rst index 91fda588e93856..304a9bb811d0ba 100644 --- a/doc/develop/tools/index.rst +++ b/doc/develop/tools/index.rst @@ -8,3 +8,4 @@ Tools and IDEs clion.rst coccinelle.rst + vscode.rst diff --git a/doc/develop/tools/vscode.rst b/doc/develop/tools/vscode.rst new file mode 100644 index 00000000000000..76229ddda7e944 --- /dev/null +++ b/doc/develop/tools/vscode.rst @@ -0,0 +1,76 @@ +.. _vscode_ide: + +VS Code +####### + +`Visual Studio Code`_ is a popular cross-platform IDE that supports C projects and has a rich set of +extensions. + +This guide describes the process of setting up VS Code for Zephyr's +:zephyr:code-sample:`blinky` sample in VS Code. + +The instructions have been tested on Linux. In terms of the CLion workflow, the steps would be the +same for macOS and Windows, but make sure to adjust the paths if needed. + +Get VS Code +*********** + +`Download VS Code`_ and install it. + +Install the required extensions through the `Extensions` marketplace in the left panel. +Search for the `C/C++ Extension Pack`_ and install it. + +Initialize a new workspace +************************** + +This guide gives details on how to configure the :zephyr:code-sample:`blinky` +sample application, but the instructions would be similar for any Zephyr project and :ref:`workspace +layout `. + +Before you start, make sure you have a working Zephyr development environment, as per the +instructions in the :ref:`getting_started`. + +Open the project in VS Code +************************** + +#. In VS Code, select :menuselection:`File --> Open Folder` from the main menu. + +#. Navigate to your Zephyr workspace (i.e.the :file:`zephyrproject` folder in your HOME directory if + you have followed the Getting Started instructions), then select + :file:`zephyr/samples/basic/blinky` or another sample project folder. + +#. If prompted, enable workspace trust. + +Generate compile commands +************************* + +#The setup showcased in this document relies on the `compile_commands.json` file generated by CMake +to provide code navigation and linting capabilities. To generate this file, you need to enable the +generation of this file through the following configuration: + +#. Open your projects' CMakeLists.txt file and add the following line. + In our case, we will add it to the :file:`samples/basic/blinky/CMakeLists.txt` file. + ``set(CMAKE_EXPORT_COMPILE_COMMANDS ON)`` + +#. Build the project to generate the `compile_commands.json` file: + ``west build -b native_posix_64 samples/basic/blinky`` + +Configure linting +***************** + +You'll now need to point to the generated `compile_commands.json` file to enable linting in VS Code. + +#. Go to the :menuselection:`File --> Preferences --> Settings` in the VS Code top menu. + +#. Search for the parameter :guilabel:`C_Cpp.default.compileCommands` and copy this path: + ``build/compile_commands.json``. + + Linting errors in the code should now be resolved, and you should be able to navigate through the + code. + +.. _Visual Studio Code: https://code.visualstudio.com/ +.. _Download VS Code: https://code.visualstudio.com/Download +.. _VS Code documentation: https://code.visualstudio.com/docs +.. _C/C++ Extension Pack: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools-extension-pack +.. _C/C++ Extension documentation: https://code.visualstudio.com/docs/languages/cpp +.. _CMake Extension documentation: https://code.visualstudio.com/docs/cpp/cmake-linux diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index eac559d238debf..d0c9fcec713456 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -169,7 +169,7 @@ PendSV exception return sequence restores the new thread's caller-saved register return address, as part of unstacking the exception stack frame. The implementation of the context-switch mechanism is present in -:file:`arch/arm/core/swap_helper.S`. +:file:`arch/arm/core/cortex_m/swap_helper.S`. Stack limit checking (Arm v8-M) ------------------------------- @@ -262,7 +262,7 @@ interrupt. If the ZLI feature is enabled in Mainline Cortex-M builds (see * Regular HW interrupts are assigned priority levels lower than SVC. The priority level configuration in Cortex-M is implemented in -:file:`include/arch/arm/exception.h`. +:file:`include/zephyr/arch/arm/cortex_m/exception.h`. Locking and unlocking IRQs -------------------------- @@ -337,7 +337,7 @@ CPU Idling The Cortex-M architecture port implements both k_cpu_idle() and k_cpu_atomic_idle(). The implementation is present in -:file:`arch/arm/core/cpu_idle.S`. +:file:`arch/arm/core/cortex_m/cpu_idle.c`. In both implementations, the processor will attempt to put the core to low power mode. @@ -444,7 +444,7 @@ are programmed during system boot. ``zephyr,memory-attr`` defining the MPU permissions for the memory region. See the next section for more details. -The above MPU regions are defined in :file:`soc/arm/common/cortex_m/arm_mpu_regions.c`. +The above MPU regions are defined in :file:`arch/arm/core/mpu/arm_mpu_regions.c`. Alternative MPU configurations are allowed by enabling :kconfig:option:`CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS`. When enabled, this option signifies that the Cortex-M SoC will define and configure its own fixed MPU regions in the SoC definition. @@ -618,7 +618,7 @@ Linking Cortex-M applications ***************************** Most Cortex-M platforms make use of the default Cortex-M -GCC linker script in :file:`include/arch/arm/cortex-m/scripts/linked.ld`, +GCC linker script in :file:`include/zephyr/arch/arm/cortex_m/scripts/linker.ld`, although it is possible for platforms to use a custom linker script as well. diff --git a/doc/hardware/peripherals/can/shell.rst b/doc/hardware/peripherals/can/shell.rst index ed36379c55ffe6..0457203438d7e9 100644 --- a/doc/hardware/peripherals/can/shell.rst +++ b/doc/hardware/peripherals/can/shell.rst @@ -101,7 +101,7 @@ stopping the processing of CAN frames. .. note:: The CAN controller mode and timing can only be changed while the CAN controller is stopped, which is the initial setting upon boot-up. The initial CAN controller mode is set to ``normal`` and the - initial timing is set according to the ``bus-speed``, ``sample-point``, ``bus-speed-data``, and + initial timing is set according to the ``bitrate``, ``sample-point``, ``bitrate-data``, and ``sample-point-data`` :ref:`devicetree` properties. Timing diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index cd75fee037105a..9889ca9ac2cb45 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -51,7 +51,7 @@ Peripherals reset.rst retained_mem.rst sdhc.rst - sensor.rst + sensor/index.rst spi.rst smbus.rst uart.rst diff --git a/doc/hardware/peripherals/sensor.rst b/doc/hardware/peripherals/sensor/index.rst similarity index 98% rename from doc/hardware/peripherals/sensor.rst rename to doc/hardware/peripherals/sensor/index.rst index 5c7817b627bbb1..ec3cf2028faa91 100644 --- a/doc/hardware/peripherals/sensor.rst +++ b/doc/hardware/peripherals/sensor/index.rst @@ -57,7 +57,7 @@ measures ambient temperature and atmospheric pressure. Note that :c:func:`sensor_sample_fetch` is only called once, as it reads and compensates data for both channels. -.. literalinclude:: ../../../samples/sensor/bme280/src/main.c +.. literalinclude:: ../../../../samples/sensor/bme280/src/main.c :language: c :lines: 12- :linenos: @@ -217,7 +217,7 @@ interest of saving power. Since the application has direct access to the kernel config symbols, no trigger is registered when triggering was disabled by the driver's configuration. -.. literalinclude:: ../../../samples/sensor/mcp9808/src/main.c +.. literalinclude:: ../../../../samples/sensor/mcp9808/src/main.c :language: c :lines: 12- :linenos: diff --git a/doc/kernel/data_structures/dlist.rst b/doc/kernel/data_structures/dlist.rst index f045c939193e27..7366d37f4f9b77 100644 --- a/doc/kernel/data_structures/dlist.rst +++ b/doc/kernel/data_structures/dlist.rst @@ -11,9 +11,9 @@ the head, tail or any internal node). To do this, the list stores two pointers per node, and thus has somewhat higher runtime code and memory space needs. -A :c:struct:`sys_dlist_t` struct may be instantiated by the user in any +A :c:type:`sys_dlist_t` struct may be instantiated by the user in any accessible memory. It must be initialized with :c:func:`sys_dlist_init` -or :c:macro:`SYS_DLIST_STATIC_INIT` before use. The :c:struct:`sys_dnode_t` struct +or :c:macro:`SYS_DLIST_STATIC_INIT` before use. The :c:type:`sys_dnode_t` struct is expected to be provided by the user for any nodes added to the list (typically embedded within the struct to be tracked, as described above). It must be initialized in zeroed/bss memory or with @@ -50,8 +50,8 @@ implementation that has zero overhead vs. the normal list processing). Double-linked List Internals ---------------------------- -Internally, the dlist implementation is minimal: the :c:struct:`sys_dlist_t` -struct contains "head" and "tail" pointer fields, the :c:struct:`sys_dnode_t` +Internally, the dlist implementation is minimal: the :c:type:`sys_dlist_t` +struct contains "head" and "tail" pointer fields, the :c:type:`sys_dnode_t` contains "prev" and "next" pointers, and no other data is stored. But in practice the two structs are internally identical, and the list struct is inserted as a node into the list itself. This allows for a diff --git a/doc/kernel/data_structures/index.rst b/doc/kernel/data_structures/index.rst index ccdc2349225fe0..f7e7c5ad354226 100644 --- a/doc/kernel/data_structures/index.rst +++ b/doc/kernel/data_structures/index.rst @@ -34,3 +34,5 @@ needed will be provided by the user. spsc_pbuf.rst rbtree.rst ring_buffers.rst + mpsc_lockfree.rst + spsc_lockfree.rst diff --git a/doc/kernel/data_structures/mpsc_lockfree.rst b/doc/kernel/data_structures/mpsc_lockfree.rst new file mode 100644 index 00000000000000..6b919125166b3e --- /dev/null +++ b/doc/kernel/data_structures/mpsc_lockfree.rst @@ -0,0 +1,14 @@ +.. _mpsc_lockfree: + +Multi Producer Single Consumer Lock Free Queue +============================================== + +A :dfn:`Multi Producer Single Consumer Lock Free Queue (MPSC)` is an lockfree +intrusive queue based on atomic pointer swaps as described by Dmitry Vyukov +at `1024cores `_. + + +API Reference +************* + +.. doxygengroup:: mpsc_lockfree diff --git a/doc/kernel/data_structures/ring_buffers.rst b/doc/kernel/data_structures/ring_buffers.rst index d077cf1f21fb7d..409b1c2bdc6240 100644 --- a/doc/kernel/data_structures/ring_buffers.rst +++ b/doc/kernel/data_structures/ring_buffers.rst @@ -198,7 +198,7 @@ Implementation Defining a Ring Buffer ====================== -A ring buffer is defined using a variable of type :c:type:`ring_buf`. +A ring buffer is defined using a variable of type :c:struct:`ring_buf`. It must then be initialized by calling :c:func:`ring_buf_init` or :c:func:`ring_buf_item_init`. diff --git a/doc/kernel/data_structures/slist.rst b/doc/kernel/data_structures/slist.rst index c1eb062ff83dfd..cfffe802895ee4 100644 --- a/doc/kernel/data_structures/slist.rst +++ b/doc/kernel/data_structures/slist.rst @@ -3,7 +3,7 @@ Single-linked List ================== -Zephyr provides a :c:struct:`sys_slist_t` type for storing simple +Zephyr provides a :c:type:`sys_slist_t` type for storing simple singly-linked list data (i.e. data where each list element stores a pointer to the next element, but not the previous one). This supports constant-time access to the first (head) and last (tail) elements of @@ -12,7 +12,7 @@ constant time removal of the head. Removal of subsequent nodes requires access to the "previous" pointer and thus can only be performed in linear time by searching the list. -The :c:struct:`sys_slist_t` struct may be instantiated by the user in any +The :c:type:`sys_slist_t` struct may be instantiated by the user in any accessible memory. It should be initialized with either :c:func:`sys_slist_init` or by static assignment from SYS_SLIST_STATIC_INIT before use. Its interior fields are opaque and should not be accessed @@ -21,15 +21,15 @@ by user code. The end nodes of a list may be retrieved with :c:func:`sys_slist_peek_head` and :c:func:`sys_slist_peek_tail`, which will return NULL if the list is empty, otherwise a pointer to a -:c:struct:`sys_snode_t` struct. +:c:type:`sys_snode_t` struct. -The :c:struct:`sys_snode_t` struct represents the data to be inserted. In +The :c:type:`sys_snode_t` struct represents the data to be inserted. In general, it is expected to be allocated/controlled by the user, usually embedded within a struct which is to be added to the list. The container struct pointer may be retrieved from a list node using :c:macro:`SYS_SLIST_CONTAINER`, passing it the struct name of the containing struct and the field name of the node. Internally, the -:c:struct:`sys_snode_t` struct contains only a next pointer, which may be +:c:type:`sys_snode_t` struct contains only a next pointer, which may be accessed with :c:func:`sys_slist_peek_next`. Lists may be modified by adding a single node at the head or tail with @@ -66,8 +66,8 @@ Single-linked List Internals ---------------------------- The slist code is designed to be minimal and conventional. -Internally, a :c:struct:`sys_slist_t` struct is nothing more than a pair of -"head" and "tail" pointer fields. And a :c:struct:`sys_snode_t` stores only a +Internally, a :c:type:`sys_slist_t` struct is nothing more than a pair of +"head" and "tail" pointer fields. And a :c:type:`sys_snode_t` stores only a single "next" pointer. .. figure:: slist.png @@ -101,7 +101,7 @@ Only one such variant, sflist, exists in Zephyr at the moment. Flagged List ------------ -The :c:struct:`sys_sflist_t` is implemented using the described genlist +The :c:type:`sys_sflist_t` is implemented using the described genlist template API. With the exception of symbol naming ("sflist" instead of "slist") and the additional API described next, it operates in all ways identically to the slist API. diff --git a/doc/kernel/data_structures/spsc_lockfree.rst b/doc/kernel/data_structures/spsc_lockfree.rst new file mode 100644 index 00000000000000..dcd9939112c384 --- /dev/null +++ b/doc/kernel/data_structures/spsc_lockfree.rst @@ -0,0 +1,12 @@ +.. _spsc_lockfree: + +Single Producer Single Consumer Lock Free Queue +=============================================== + +A :dfn:`Single Producer Single Consumer Lock Free Queue (MPSC)` is a lock free +atomic ring buffer based queue. + +API Reference +************* + +.. doxygengroup:: spsc_lockfree diff --git a/doc/kernel/memory_management/demand_paging.rst b/doc/kernel/memory_management/demand_paging.rst index e870c8740e2510..54eb12baac0a7f 100644 --- a/doc/kernel/memory_management/demand_paging.rst +++ b/doc/kernel/memory_management/demand_paging.rst @@ -50,32 +50,32 @@ Page Frame A page frame is a page-sized physical memory region in RAM. It is a container where a data page may be placed. It is always referred to by physical address. Zephyr has a convention of using ``uintptr_t`` for physical - addresses. For every page frame, a ``struct z_page_frame`` is instantiated to + addresses. For every page frame, a ``struct k_mem_page_frame`` is instantiated to store metadata. Flags for each page frame: - * ``Z_PAGE_FRAME_FREE`` indicates a page frame is unused and on the list of + * ``K_MEM_PAGE_FRAME_FREE`` indicates a page frame is unused and on the list of free page frames. When this flag is set, none of the other flags are meaningful and they must not be modified. - * ``Z_PAGE_FRAME_PINNED`` indicates a page frame is pinned in memory + * ``K_MEM_PAGE_FRAME_PINNED`` indicates a page frame is pinned in memory and should never be paged out. - * ``Z_PAGE_FRAME_RESERVED`` indicates a physical page reserved by hardware + * ``K_MEM_PAGE_FRAME_RESERVED`` indicates a physical page reserved by hardware and should not be used at all. - * ``Z_PAGE_FRAME_MAPPED`` is set when a physical page is mapped to + * ``K_MEM_PAGE_FRAME_MAPPED`` is set when a physical page is mapped to virtual memory address. - * ``Z_PAGE_FRAME_BUSY`` indicates a page frame is currently involved in + * ``K_MEM_PAGE_FRAME_BUSY`` indicates a page frame is currently involved in a page-in/out operation. - * ``Z_PAGE_FRAME_BACKED`` indicates a page frame has a clean copy + * ``K_MEM_PAGE_FRAME_BACKED`` indicates a page frame has a clean copy in the backing store. -Z_SCRATCH_PAGE +K_MEM_SCRATCH_PAGE The virtual address of a special page provided to the backing store to: - * Copy a data page from ``Z_SCRATCH_PAGE`` to the specified location; or, - * Copy a data page from the provided location to ``Z_SCRATCH_PAGE``. + * Copy a data page from ``k_MEM_SCRATCH_PAGE`` to the specified location; or, + * Copy a data page from the provided location to ``K_MEM_SCRATCH_PAGE``. This is used as an intermediate page for page in/out operations. This scratch needs to be mapped read/write for backing store code to access. However the data page itself may only be mapped as read-only in virtual @@ -163,10 +163,10 @@ which must be implemented: * :c:func:`k_mem_paging_backing_store_page_in()` copies a data page from the backing store location associated with the provided - ``location`` token to the page pointed by ``Z_SCRATCH_PAGE``. + ``location`` token to the page pointed by ``K_MEM_SCRATCH_PAGE``. * :c:func:`k_mem_paging_backing_store_page_out()` copies a data page - from ``Z_SCRATCH_PAGE`` to the backing store location associated + from ``K_MEM_SCRATCH_PAGE`` to the backing store location associated with the provided ``location`` token. * :c:func:`k_mem_paging_backing_store_page_finalize()` is invoked after diff --git a/doc/kernel/memory_management/shared_multi_heap.rst b/doc/kernel/memory_management/shared_multi_heap.rst index 89458ecb927c6b..cc5101ae1fbfe8 100644 --- a/doc/kernel/memory_management/shared_multi_heap.rst +++ b/doc/kernel/memory_management/shared_multi_heap.rst @@ -18,7 +18,7 @@ This framework is commonly used as follow: the pool with :c:func:`shared_multi_heap_add()`, possibly gathering the needed information for the regions from the DT. -2. Each memory region encoded in a :c:type:`shared_multi_heap_region` +2. Each memory region encoded in a :c:struct:`shared_multi_heap_region` structure. This structure is also carrying an opaque and user-defined integer value that is used to define the region capabilities (for example: cacheability, cpu affinity, etc...) @@ -76,7 +76,7 @@ Adding new attributes ********************* The API does not enforce any attributes, but at least it defines the two most -common ones: :c:enum:`SMH_REG_ATTR_CACHEABLE` and :c:enum:`SMH_REG_ATTR_NON_CACHEABLE` +common ones: :c:enumerator:`SMH_REG_ATTR_CACHEABLE` and :c:enumerator:`SMH_REG_ATTR_NON_CACHEABLE`. .. doxygengroup:: shared_multi_heap :project: Zephyr diff --git a/doc/kernel/memory_management/virtual_memory.rst b/doc/kernel/memory_management/virtual_memory.rst index dbc95fb7b5279e..4e2f11e90c7b3e 100644 --- a/doc/kernel/memory_management/virtual_memory.rst +++ b/doc/kernel/memory_management/virtual_memory.rst @@ -73,15 +73,15 @@ below. .. code-block:: none :emphasize-lines: 1, 3, 9, 22, 24 - +--------------+ <- Z_VIRT_RAM_START + +--------------+ <- K_MEM_VIRT_RAM_START | Undefined VM | <- architecture specific reserved area - +--------------+ <- Z_KERNEL_VIRT_START + +--------------+ <- K_MEM_KERNEL_VIRT_START | Mapping for | | main kernel | | image | | | | | - +--------------+ <- Z_FREE_VM_START + +--------------+ <- K_MEM_VM_FREE_START | | | Unused, | | Available VM | @@ -95,27 +95,27 @@ below. +--------------+ | Mapping | +--------------+ <- memory mappings start here - | Reserved | <- special purpose virtual page(s) of size Z_VM_RESERVED - +--------------+ <- Z_VIRT_RAM_END + | Reserved | <- special purpose virtual page(s) of size K_MEM_VM_RESERVED + +--------------+ <- K_MEM_VIRT_RAM_END -* ``Z_VIRT_RAM_START`` is the beginning of the virtual memory address space. +* ``K_MEM_VIRT_RAM_START`` is the beginning of the virtual memory address space. This needs to be page aligned. Currently, it is the same as :kconfig:option:`CONFIG_KERNEL_VM_BASE`. -* ``Z_VIRT_RAM_SIZE`` is the size of the virtual memory address space. +* ``K_MEM_VIRT_RAM_SIZE`` is the size of the virtual memory address space. This needs to be page aligned. Currently, it is the same as :kconfig:option:`CONFIG_KERNEL_VM_SIZE`. -* ``Z_VIRT_RAM_END`` is simply (``Z_VIRT_RAM_START`` + ``Z_VIRT_RAM_SIZE``). +* ``K_MEM_VIRT_RAM_END`` is simply (``K_MEM_VIRT_RAM_START`` + ``K_MEM_VIRT_RAM_SIZE``). -* ``Z_KERNEL_VIRT_START`` is the same as ``z_mapped_start`` specified in the linker +* ``K_MEM_KERNEL_VIRT_START`` is the same as ``z_mapped_start`` specified in the linker script. This is the virtual address of the beginning of the kernel image at boot time. -* ``Z_KERNEL_VIRT_END`` is the same as ``z_mapped_end`` specified in the linker +* ``K_MEM_KERNEL_VIRT_END`` is the same as ``z_mapped_end`` specified in the linker script. This is the virtual address of the end of the kernel image at boot time. -* ``Z_FREE_VM_START`` is the beginning of the virtual address space where addresses +* ``K_MEM_VM_FREE_START`` is the beginning of the virtual address space where addresses can be allocated for memory mapping. This depends on whether :kconfig:option:`CONFIG_ARCH_MAPS_ALL_RAM` is enabled. @@ -123,10 +123,10 @@ below. memory address space, and it is the same as (:kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` + :kconfig:option:`CONFIG_SRAM_SIZE`). - * If it is disabled, ``Z_FREE_VM_START`` is the same ``Z_KERNEL_VIRT_END`` which + * If it is disabled, ``K_MEM_VM_FREE_START`` is the same ``K_MEM_KERNEL_VIRT_END`` which is the end of the kernel image. -* ``Z_VM_RESERVED`` is an area reserved to support kernel functions. For example, +* ``K_MEM_VM_RESERVED`` is an area reserved to support kernel functions. For example, some addresses are reserved to support demand paging. @@ -176,7 +176,7 @@ mappings must be aligned on page size and have finer access control. * The requested size must be multiple of page size. * The address returned is inside the virtual address space between - ``Z_FREE_VM_START`` and ``Z_VIRT_RAM_END``. + ``K_MEM_VM_FREE_START`` and ``K_MEM_VIRT_RAM_END``. * The mapped region is not guaranteed to be physically contiguous in memory. diff --git a/doc/kernel/services/data_passing/pipes.rst b/doc/kernel/services/data_passing/pipes.rst index bdeec48f0117ba..c4cb571fc07ee8 100644 --- a/doc/kernel/services/data_passing/pipes.rst +++ b/doc/kernel/services/data_passing/pipes.rst @@ -231,7 +231,7 @@ Configuration Options Related configuration options: -* CONFIG_PIPES +* :kconfig:option:`CONFIG_PIPES` API Reference ************* diff --git a/doc/kernel/services/polling.rst b/doc/kernel/services/polling.rst index 46e586badb6e99..685a3023d5eb73 100644 --- a/doc/kernel/services/polling.rst +++ b/doc/kernel/services/polling.rst @@ -78,14 +78,15 @@ Poll events can be initialized using either the runtime initializers :c:macro:`K_POLL_EVENT_INITIALIZER()` or :c:func:`k_poll_event_init`, or the static initializer :c:macro:`K_POLL_EVENT_STATIC_INITIALIZER()`. An object that matches the **type** specified must be passed to the initializers. The -**mode** *must* be set to :c:macro:`K_POLL_MODE_NOTIFY_ONLY`. The state *must* -be set to :c:macro:`K_POLL_STATE_NOT_READY` (the initializers take care of -this). The user **tag** is optional and completely opaque to the API: it is +**mode** *must* be set to :c:enumerator:`K_POLL_MODE_NOTIFY_ONLY`. The state +*must* be set to :c:macro:`K_POLL_STATE_NOT_READY` (the initializers take care +of this). The user **tag** is optional and completely opaque to the API: it is there to help a user to group similar events together. Being optional, it is passed to the static initializer, but not the runtime ones for performance reasons. If using runtime initializers, the user must set it separately in the :c:struct:`k_poll_event` data structure. If an event in the array is to be -ignored, most likely temporarily, its type can be set to K_POLL_TYPE_IGNORE. +ignored, most likely temporarily, its type can be set to +:c:macro:`K_POLL_TYPE_IGNORE`. .. code-block:: c diff --git a/doc/kernel/services/smp/smp.rst b/doc/kernel/services/smp/smp.rst index ca1e0149ad55e6..4b178432bd5597 100644 --- a/doc/kernel/services/smp/smp.rst +++ b/doc/kernel/services/smp/smp.rst @@ -180,13 +180,17 @@ handle the newly-runnable load. So where possible, Zephyr SMP architectures should implement an interprocessor interrupt. The current framework is very simple: the -architecture provides a :c:func:`arch_sched_ipi` call, which when invoked -will flag an interrupt on all CPUs (except the current one, though -that is allowed behavior) which will then invoke the :c:func:`z_sched_ipi` -function implemented in the scheduler. The expectation is that these -APIs will evolve over time to encompass more functionality -(e.g. cross-CPU calls), and that the scheduler-specific calls here -will be implemented in terms of a more general framework. +architecture provides at least a :c:func:`arch_sched_broadcast_ipi` call, +which when invoked will flag an interrupt on all CPUs (except the current one, +though that is allowed behavior). If the architecture supports directed IPIs +(see :kconfig:option:`CONFIG_ARCH_HAS_DIRECTED_IPIS`), then the +architecture also provides a :c:func:`arch_sched_directed_ipi` call, which +when invoked will flag an interrupt on the specified CPUs. When an interrupt is +flagged on the CPUs, the :c:func:`z_sched_ipi` function implmented in the +scheduler will get invoked on those CPUs. The expectation is that these +APIs will evolve over time to encompass more functionality (e.g. cross-CPU +calls), and that the scheduler-specific calls here will be implemented in +terms of a more general framework. Note that not all SMP architectures will have a usable IPI mechanism (either missing, or just undocumented/unimplemented). In those cases diff --git a/doc/kernel/services/threads/workqueue.rst b/doc/kernel/services/threads/workqueue.rst index b221e1163b7cd9..18c1cf0e31a632 100644 --- a/doc/kernel/services/threads/workqueue.rst +++ b/doc/kernel/services/threads/workqueue.rst @@ -71,7 +71,7 @@ itself. The work item also maintains information about its status. A work item must be initialized before it can be used. This records the work item's handler function and marks it as not pending. -A work item may be **queued** (:c:macro:`K_WORK_QUEUED`) by submitting it to a +A work item may be **queued** (:c:enumerator:`K_WORK_QUEUED`) by submitting it to a workqueue by an ISR or a thread. Submitting a work item appends the work item to the workqueue's queue. Once the workqueue's thread has processed all of the preceding work items in its queue the thread will remove the next work @@ -80,11 +80,11 @@ the scheduling priority of the workqueue's thread, and the work required by other items in the queue, a queued work item may be processed quickly or it may remain in the queue for an extended period of time. -A delayable work item may be **scheduled** (:c:macro:`K_WORK_DELAYED`) to a +A delayable work item may be **scheduled** (:c:enumerator:`K_WORK_DELAYED`) to a workqueue; see `Delayable Work`_. -A work item will be **running** (:c:macro:`K_WORK_RUNNING`) when it is running -on a work queue, and may also be **canceling** (:c:macro:`K_WORK_CANCELING`) +A work item will be **running** (:c:enumerator:`K_WORK_RUNNING`) when it is running +on a work queue, and may also be **canceling** (:c:enumerator:`K_WORK_CANCELING`) if it started running before a thread has requested that it be cancelled. A work item can be in multiple states; for example it can be: @@ -248,7 +248,7 @@ The following code defines and initializes a workqueue: In addition the queue identity and certain behavior related to thread rescheduling can be controlled by the optional final parameter; see -:c:struct:`k_work_queue_start()` for details. +:c:func:`k_work_queue_start()` for details. The following API can be used to interact with a workqueue: @@ -416,7 +416,7 @@ be a flag indicating that work needs to be done, or a shared object that is filled by an ISR or thread and read by the work handler. For simple flags :ref:`atomic_v2` may be sufficient. In other cases spin -locks (:c:struct:`k_spinlock_t`) or thread-aware locks (:c:struct:`k_sem`, +locks (:c:struct:`k_spinlock`) or thread-aware locks (:c:struct:`k_sem`, :c:struct:`k_mutex` , ...) may be used to ensure data races don't occur. If the selected lock mechanism can :ref:`api_term_sleep` then allowing the diff --git a/doc/kernel/services/timing/clocks.rst b/doc/kernel/services/timing/clocks.rst index 0517d601f27677..4d88606938ee8d 100644 --- a/doc/kernel/services/timing/clocks.rst +++ b/doc/kernel/services/timing/clocks.rst @@ -98,7 +98,7 @@ For example: * The kernel :c:struct:`k_work_delayable` API provides a timeout parameter indicating when a work queue item will be added to the system queue. -All these values are specified using a :c:struct:`k_timeout_t` value. This is +All these values are specified using a :c:type:`k_timeout_t` value. This is an opaque struct type that must be initialized using one of a family of kernel timeout macros. The most common, :c:macro:`K_MSEC`, defines a time in milliseconds after the current time. @@ -123,7 +123,7 @@ described above: :c:macro:`K_NSEC()`, :c:macro:`K_USEC`, :c:macro:`K_TICKS` and :c:macro:`K_CYC()` specify timeout values that will expire after specified numbers of nanoseconds, microseconds, ticks and cycles, respectively. -Precision of :c:struct:`k_timeout_t` values is configurable, with the default +Precision of :c:type:`k_timeout_t` values is configurable, with the default being 32 bits. Large uptime counts in non-tick units will experience complicated rollover semantics, so it is expected that timing-sensitive applications with long uptimes will be configured to @@ -141,16 +141,16 @@ Timing Internals Timeout Queue ------------- -All Zephyr :c:struct:`k_timeout_t` events specified using the API above are +All Zephyr :c:type:`k_timeout_t` events specified using the API above are managed in a single, global queue of events. Each event is stored in a double-linked list, with an attendant delta count in ticks from the previous event. The action to take on an event is specified as a callback function pointer provided by the subsystem requesting the event, along with a :c:struct:`_timeout` tracking struct that is expected to be embedded within subsystem-defined data structures (for -example: a :c:struct:`wait_q` struct, or a :c:struct:`k_tid_t` thread struct). +example: a :c:struct:`wait_q` struct, or a :c:type:`k_tid_t` thread struct). -Note that all variant units passed via a :c:struct:`k_timeout_t` are converted +Note that all variant units passed via a :c:type:`k_timeout_t` are converted to ticks once on insertion into the list. There no multiple-conversion steps internal to the kernel, so precision is guaranteed at the tick level no matter how many events exist or how diff --git a/doc/kernel/services/timing/timers.rst b/doc/kernel/services/timing/timers.rst index 9b1e424921de4a..7fd3e2e46010de 100644 --- a/doc/kernel/services/timing/timers.rst +++ b/doc/kernel/services/timing/timers.rst @@ -22,11 +22,11 @@ is referenced by its memory address. A timer has the following key properties: * A **duration** specifying the time interval before the timer - expires for the first time. This is a ``k_timeout_t`` value that + expires for the first time. This is a :c:type:`k_timeout_t` value that may be initialized via different units. * A **period** specifying the time interval between all timer - expirations after the first one, also a ``k_timeout_t``. It must be + expirations after the first one, also a :c:type:`k_timeout_t`. It must be non-negative. A period of ``K_NO_WAIT`` (i.e. zero) or ``K_FOREVER`` means that the timer is a one-shot timer that stops after a single expiration. (For example then, if a timer is started diff --git a/doc/project/index.rst b/doc/project/index.rst index 372e4816ddc29e..dda70ca575f229 100644 --- a/doc/project/index.rst +++ b/doc/project/index.rst @@ -7,7 +7,9 @@ Project and Governance .. toctree:: :maxdepth: 1 + tsc project_roles.rst + working_groups release_process proposals code_flow diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index a57a7b46def4b6..3e106e888f2234 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -3,8 +3,8 @@ TSC Project Roles ***************** -Main Roles -########## +Project Roles +############# TSC projects generally will involve *Maintainers*, *Collaborators*, and *Contributors*: @@ -159,6 +159,7 @@ Assignees are set either automatically based on the code being changed or set by the other Maintainers, the Release Engineering team can set an assignee when the latter is not possible. +* Responsibility to drive the pull request to a mergeable state * Right to dismiss stale and unrelated reviews or reviews not following :ref:`expectations ` from reviewers and seek reviews from additional maintainers, developers and contributors @@ -166,7 +167,6 @@ the latter is not possible. requested are addressed * Responsibility to re-assign a pull request if they are the original submitter of the code -* Responsibility to drive the pull request to a mergeable state * Solicit approvals from maintainers of the subsystems affected * Responsibility to drive the :ref:`pr_technical_escalation` process diff --git a/doc/project/tsc.rst b/doc/project/tsc.rst new file mode 100644 index 00000000000000..f183bde9f060c1 --- /dev/null +++ b/doc/project/tsc.rst @@ -0,0 +1,242 @@ +Technical Steering Committee (TSC) +********************************** + +TSC Member Role +############### + +The TSC role and its responsibilities is defined in the `Zephyr project charter`_. + +Membership +++++++++++ + +A TSC member plays a pivotal role in shaping the technical direction of the +Zephyr Project. TSC members work collaboratively with other TSC members, +contributors, and stakeholders to ensure the project's success and +sustainability. + +By fulfilling the rights and responsibilities below, TSC members contribute to +the overall success and growth of the Zephyr Project, ensuring that it remains a +vibrant and thriving open-source community for years to come. + + +Rights +------ + +Decision Making + Participate in key decisions related to the project's technical direction, + including architectural changes, feature additions, and release planning. + +Voting + Exercise voting rights on important matters discussed within the TSC, + including feature proposals, code contributions, and community initiatives. + +Access + Gain access to relevant project repositories, documentation, and communication + channels to stay informed and contribute effectively. + +Leadership + Take on leadership roles within working groups or subcommittees dedicated to + specific technical areas or initiatives. + +Representation + Act as a representative of the broader Zephyr community, advocating for the + interests of contributors, users, and stakeholders. + +Responsibilities +---------------- +TSC members are expected to fulfill the following responsibilities, though it is +not mandatory to fulfill all: + +Technical Oversight + Provide guidance and oversight on technical matters, ensuring alignment with + project goals, standards, and best practices through active participation as + core members in working groups and committees. + +Code Review + Participate in code reviews to maintain code quality, consistency, and + compatibility with project standards. + +Community Engagement + Engage with the community through forums, mailing lists, conferences, and + other channels to foster collaboration, address concerns, and gather feedback. + +Documentation + Contribute to the development and maintenance of project documentation, + including technical guides, API references, and best practices. + +Release Management + Collaborate with the release manager and other stakeholders to plan and + coordinate project releases, ensuring timely delivery and quality assurance. + +Contributor Support + Support and mentor new contributors, helping them navigate the project's + codebase, processes, and community norms. + +Issue Triage + Assist in triaging and prioritizing issues reported by users and contributors, + facilitating timely resolution and communication. + +Compliance and Licensing + Ensure compliance with project licensing requirements and open-source best + practices, addressing any licensing-related issues that may arise. + +Conflict Resolution + Facilitate constructive discussions and resolution of technical disagreements + or conflicts within the community, promoting a healthy and inclusive + environment. + +Continuous Improvement + Continuously seek opportunities to improve project governance, processes, and + infrastructure, driving innovation and sustainability. + + +Appointed TSC Members ++++++++++++++++++++++ + +See `Zephyr project charter`_ for more details. + +- Appointed TSC members have no term limits besides the term of their employment + at the organization they represent or their organization's membership in the + Zephyr Project. +- Appointed TSC members can select an Alternate from the same organization. + +Elected TSC Members ++++++++++++++++++++ + +Per the `Zephyr project charter`_, TSC members can nominate representatives from +the technical community at the rate of no more than one per quarter. + +- Majority vote is required to confirm a candidate. +- Once elected, a TSC member serves for 2 years. +- Elected TSC members do not have the right to appoint an Alternate. +- To ensure continuity of the TSC, at the end of the 2 year term, the TSC is + required to reconfirm the membership of elected members. If the elected member + declines a new term or if the TSC fails to reconfirm the term, the seat will + be open for new nominations. +- If an elected TSC member resigns before the end of the 2 year term, their spot + will be open for new members outside of the quarterly nomination limit. The + elected member will serve a 2 year term. +- The TSC has the right to terminate elected members who become inactive and are + not fulfilling the responsibilities of TSC members as described in this + document. +- The number of elected members shall not exceed 20% of the total of appointed + members. +- Existing TSC members who were elected before May 2024 shall be re-confirmed + after completing the 2 year term since they were first elected. + +Suspensions ++++++++++++ + +As noted under Section 8b of the Project Charter, voting rights for a +representative who misses three consecutive meetings are subject to suspension +and suspended representatives do not count towards the quorum requirement. + +A representative’s suspension will end and voting rights be restored at the start +of the next attended meeting. The TSC enforces the suspension policy for voting +members who miss three consecutive TSC weekly meetings. + +Multi-day meetings (F2F events) are counted as "one" meeting. The TSC voted on +February 16, 2022 to discontinue default enforcement of the suspension policy. +The TSC voted on January 18, 2023 to re-enact default enforcement of the +suspension policy. + +Notice of suspension will be sent to representatives who miss three consecutive +meetings, noting that rights will be restored upon next attendance of a TSC +meeting. + +.. note:: + + As per Section 4b of the Project Charter, Platinum and Silver + Members may choose to opt out of a voting seat on the TSC. + + Members who opt out and then wish to reclaim their seat later will have their + voting rights restored at the start of the second consecutive meeting + attended following notification to the TSC Chair. + + +Voting +++++++ + +Voting in the Zephyr Project is defined under Section 8 of the Project Charter. + +Additional points of clarity / TSC interpretation have been added below. The +Governing Board may opt to update the Charter to include the below +refinements. Until then, additional clarifications (if/where needed) will be +discussed in the Process Working Group, and approved in the TSC. + +- TSC In-Meeting Voting For items requesting an in-meeting vote of the Zephyr + Technical Steering Committee (TSC), assuming quorum requirements have been + met, the default voting mechanism will be a verbal motion to determine if + there is general consensus. +- If there are no objections to a motion being brought forward, general + consensus is assumed and the motion passes. +- Should there be any objections raised, the vote will move to email, and be + executed using the Voting Guidelines outlined in Section 8 of the Project + Charter. +- Should a motion be deemed urgent by the TSC Chair, and assuming quorum + requirements have been met, the Chair may call for a roll call vote + in-meeting. + +Voting Options +-------------- + +- Voting Options are: + + - "Yes", + - "No" or + - "Abstain" + +Abstention +---------- + +Abstentions do not count in tallying the vote negatively or positively; when +members abstain, they are in effect attending only to contribute to a quorum. + +Abstentions do not impact the number of votes needed to decide a vote. + +Quorum +------ + +Quorum for TSC meetings shall require 60% of the voting representatives... (ref +8b of the Charter) + +Decisions +--------- + +Decisions by vote shall be based on a majority vote, provided that at least +sixty percent (60%) of the **TSC** representatives must be either +present or participating electronically or by written action in order to +conduct a valid vote. (ref 8c of the Charter) + +Example A: + + 40 eligible TSC voters. 3 abstain from a vote on a motion. 12 vote Yes. 11 vote + No. + + Quorum reached: 26 votes cast (quorum = 60% of 40 = 24) + Majority vote: 12 Yes vs. 11 No. Yes wins. + Motion adopted. + +Example B: + + 40 eligible TSC voters. 5 abstain from a vote on a motion. 12 vote Yes. 6 + vote No. Quorum reached? 23 votes cast (quorum = 60% of 40 = 24) + + Vote is not valid. Quorum not reached. + +Example C: + + 40 eligible TSC voters. 21 abstain from a vote on a motion. 2 vote Yes. 1 votes + No. Quorum reached? 24 votes cast (quorum = 60% of 40 = 24) + + Majority vote: 2 Yes vs. 1 No. Yes wins. + +Immutable Votes ++++++++++++++++ + +Votes are considered immutable once cast. A voter may not change their vote, +once cast, between the time a Motion is brought forth and the time at which +results are announced. + +.. _Zephyr project charter: + https://www.zephyrproject.org/wp-content/uploads/sites/38/2023/08/LF-Zephyr-Charter-2023.08.21.pdf diff --git a/doc/project/working_groups.rst b/doc/project/working_groups.rst new file mode 100644 index 00000000000000..900f2877384772 --- /dev/null +++ b/doc/project/working_groups.rst @@ -0,0 +1,118 @@ +TSC Working Groups +****************** + +Overview +######## + +The TSC, at its discretion, may establish working groups or subcommittees to +serve as focused teams dedicated to specific technical areas, initiatives, or +tasks. + +Membership +########## + +Working Group Membership Eligibility +++++++++++++++++++++++++++++++++++++ + +- Each Working group (WG) shall determine its own membership eligibility, in + consultation with the TSC. +- Each working group shall have a team of members who are actively involved + in its activities and decision-making processes. +- It is expected that WG membership shall be **open to all Zephyr project + Contributors**; however, working groups may impose restrictions such as the + number of participants from a single company. +- All TSC members are eligible to join a working group as members, part of + the responsibilities being a TSC member. +- The minimal number of members may vary depending on the complexity of the + tasks and the breadth of expertise required to address them effectively. +- A working group should aim to have at least five to seven members to + ensure diversity of perspectives, collaboration, and continuity. +- The structure of each working group within the Zephyr Project should be + designed to ensure effectiveness, productivity, and inclusivity. While the + optimal size of a working group can vary depending on the specific context and + scope of its activities. +- Participation in WG meetings and discussions is open to all project contributors. + +Working Group Chair / Co-chair +++++++++++++++++++++++++++++++ + +Each working group may elect a Chair and optionally a Co-Chair who is +responsible for leading meetings and representing the working group to the TSC. + +Working Group Chair / Co-Chair Elections +++++++++++++++++++++++++++++++++++++++++ + +- The Chair and Co-Chair shall be elected by the members of the working group +- Any member of the working group has the right to nominate themselves for the + chair/co-chair positions. +- The term for the chair/co-chair is one year +- If a chair/co-chair resigns from the position before the end of the term, a + vote is to be held to elect a new chair/co-chair. + +Working Group Voter Eligibility ++++++++++++++++++++++++++++++++ + +- Voting for a Chair or Co-Chair is open to the members of the working group. +- Only 1 working group member from each company may vote in the election. +- The Chair and Co-Chair shall be members of the working group. + +Working Group Election Confirmation +++++++++++++++++++++++++++++++++++++ + +- The elected Chair (and/or Co-Chair) is submitted to the TSC for confirmation. +- The TSC decides to accept the outcome or requests a new voting. + +Advisory role +############# + +- Working Groups are advisory in nature. They provide advice to the projects and + to the TSC. +- Working groups operate on a rough consensus basis. If the working group is + unable to reach consensus on what advice to offer, the working group Chair + shall raise the issue with the TSC or the relevant committee (Safety and + Security), where a formal vote can be taken, or advise the project that the + working group cannot reach consensus. +- Working groups shall keep track of discussions and record any votes, + decisions, or recommendations made and share results with the community and + the TSC. +- Working group meetings and offline discussions shall be captured in a + standalone document with all supporting details such as attendance, quorum, + actions to be taken, and next steps. +- Decisions made within a working group are non-binding and are only considered + ratified after communicating decisions and outcomes to the TSC. +- Lacking any objections from the TSC within 1 week after the communication or + report of any results, decisions of a working group are considered confirmed + and ratified. + +TSC Working Group Lifecycle +########################### + +Creation of a TSC working group ++++++++++++++++++++++++++++++++ + +In order to create a TSC working group, a TSC member shall make a proposal to +the TSC (via TSC email list) that shall cover at least the following: + +- TSC working group name. +- TSC working group purpose +- TSC working group expected deliverables +- TSC working group starting participants with at least one TSC member acting as + a sponsor. +- Optionally TSC working group definition of done + +Update of a TSC working group ++++++++++++++++++++++++++++++ + +The TSC can modify a TSC working group via a TSC decision. To request such a +modification, a request is made to the TSC email list. + +Conclusion of a TSC working group ++++++++++++++++++++++++++++++++++ + +The TSC decides the termination of the TSC working group in accordance with the +TSC decision procedure. The submission of a request to terminate the TSC working +group should cover: + +- TSC working group name +- TSC working group deliveries +- Motivation for termination of the TSC working group diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index 0fa08a6af9db09..b1f0b50443c285 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -59,6 +59,11 @@ Build System Kernel ****** +* All architectures are now required to define the new ``struct arch_esf``, which describes the members + of a stack frame. This new struct replaces the named struct ``z_arch_esf_t``. (:github:`73593`) + +* The named struct ``z_arch_esf_t`` is now deprecated. Use ``struct arch_esf`` instead. (:github:`73593`) + Boards ****** @@ -76,6 +81,8 @@ Boards * LiteX: Renamed the ``compatible`` of the LiteX VexRiscV interrupt controller node from ``vexriscv-intc0`` to :dtcompatible:`litex,vexriscv-intc0`. (:github:`73211`) +* `lairdconnect` boards are now `ezurio` boards. Laird Connectivity has rebranded to `Ezurio `_. + Modules ******* @@ -85,14 +92,26 @@ Mbed TLS * TLS 1.2, RSA, AES, DES, and all the hash algorithms except SHA-256 (SHA-224, SHA-384, SHA-512, MD5 and SHA-1) are not enabled by default anymore. Their respective Kconfig options now need to be explicitly enabled to be able to use them. -* The Kconfig options previously named `CONFIG_MBEDTLS_MAC_*_ENABLED` have been renamed. - The `_MAC` and `_ENABLED` parts have been removed from their names. + (:github:`72078`) +* The Kconfig options previously named ``CONFIG_MBEDTLS_MAC_*_ENABLED`` have been renamed. + The ``_MAC`` and ``_ENABLED`` parts have been removed from their names. (:github:`73267`) * The :kconfig:option:`CONFIG_MBEDTLS_HASH_ALL_ENABLED` Kconfig option has been fixed to actually enable all the available hash algorithms. Previously, it used to only enable the SHA-2 ones. -* The `CONFIG_MBEDTLS_HASH_SHA*_ENABLED` Kconfig options have been removed. They were duplicates - of other Kconfig options which are now named `CONFIG_MBEDTLS_SHA*`. -* The `CONFIG_MBEDTLS_MAC_ALL_ENABLED` Kconfig option has been removed. Its equivalent is the + (:github:`73267`) +* The ``CONFIG_MBEDTLS_HASH_SHA*_ENABLED`` Kconfig options have been removed. They were duplicates + of other Kconfig options which are now named ``CONFIG_MBEDTLS_SHA*``. (:github:`73267`) +* The ``CONFIG_MBEDTLS_MAC_ALL_ENABLED`` Kconfig option has been removed. Its equivalent is the combination of :kconfig:option:`CONFIG_MBEDTLS_HASH_ALL_ENABLED` and :kconfig:option:`CONFIG_MBEDTLS_CMAC`. + (:github:`73267`) +* The Kconfig options ``CONFIG_MBEDTLS_MAC_MD4_ENABLED``, ``CONFIG_MBEDTLS_CIPHER_ARC4_ENABLED`` + and ``CONFIG_MBEDTLS_CIPHER_BLOWFISH_ENABLED`` were removed because they are no more supported + in Mbed TLS. (:github:`73222`) +* When there is any PSA crypto provider available in the system + (i.e. :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT` is set), desired PSA crypto + features must be explicitly enabled using proper ``CONFIG_PSA_WANT_*``. (:github:`72243`) +* TLS/X509/PK/MD modules will use PSA crypto APIs instead of legacy ones as soon + as there is any PSA crypto provider available in the system + (i.e. :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT` is set). (:github:`72243`) MCUboot ======= @@ -217,6 +236,17 @@ Analog-to-Digital Converter (ADC) Bluetooth HCI ============= + * A new HCI driver API was introduced (:github:`72323`) and the old one deprecated. The new API + follows the normal Zephyr driver model, with devicetree nodes, etc. The host now + selects which driver instance to use as the controller by looking for a ``zephyr,bt-hci`` + chosen property. The devicetree bindings for all HCI drivers derive from a common + ``bt-hci.yaml`` base binding. + * As part of the new HCI driver API, the ``zephyr,bt-uart`` chosen property is no longer used, + rather the UART HCI drivers select their UART by looking for the parent devicetree node of the + HCI driver instance node. + * As part of the new HCI driver API, the ``zephyr,bt-hci-ipc`` chosen property is only used for + the controller side, whereas the HCI driver now relies on nodes with the compatible string + ``zephyr,bt-hci-ipc``. * The ``BT_HCI_VS_EXT`` Kconfig option was deleted and the feature is now included in the :kconfig:option:`BT_HCI_VS` Kconfig option. * The ``BT_HCI_VS_EVT`` Kconfig option was removed, since vendor event support is implicit if @@ -239,8 +269,9 @@ Controller Area Network (CAN) ============================= * Removed the following deprecated CAN controller devicetree properties. Out-of-tree boards using - these properties need to switch to using the ``bus-speed``, ``sample-point``, ``bus-speed-data``, - and ``sample-point-data`` devicetree properties for specifying the initial CAN bitrate: + these properties can switch to using the ``bitrate``, ``sample-point``, ``bitrate-data``, and + ``sample-point-data`` devicetree properties (or rely on :kconfig:option:`CAN_DEFAULT_BITRATE` and + :kconfig:option:`CAN_DEFAULT_BITRATE_DATA`) for specifying the initial CAN bitrate: * ``sjw`` * ``prop-seg`` @@ -251,6 +282,9 @@ Controller Area Network (CAN) * ``phase-seg1-data`` * ``phase-seg1-data`` + The ``bus-speed`` and ``bus-speed-data`` CAN controller devicetree properties have been + deprecated. + (:github:`68714`) * Support for manual bus-off recovery was reworked (:github:`69460`): @@ -317,6 +351,50 @@ Display }; }; + +* ST7789V based displays now use the MIPI DBI driver class. These displays + must now be declared within a MIPI DBI driver wrapper device, which will + manage interfacing with the display. (:github:`73750`) Note that the + `cmd-data-gpios` pin has changed polarity with this update, to align better + with the new `dc-gpios` name. For an example, see below: + + .. code-block:: devicetree + + /* Legacy ST7789V display definition */ + &spi0 { + st7789: st7789@0 { + compatible = "sitronix,st7789v"; + reg = <0>; + spi-max-frequency = <32000000>; + reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + cmd-data-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + ... + }; + }; + + /* New display definition with MIPI DBI device */ + + #include + + ... + + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + spi-dev = <&spi0>; + #address-cells = <1>; + #size-cells = <0>; + + st7789: st7789@0 { + compatible = "sitronix,st7789v"; + reg = <0>; + mipi-max-frequency = <32000000>; + mipi-mode = ; + ... + }; + }; + Enhanced Serial Peripheral Interface (eSPI) =========================================== @@ -328,6 +406,8 @@ Enhanced Serial Peripheral Interface (eSPI) ``ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS``, ``ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE`` and ``ESPI_VWIRE_SIGNAL_TARGET_GPIO_`` respectively to reflect the new terminology in eSPI 1.5 specification. (:github:`68492`) + The KConfig ``CONFIG_ESPI_SLAVE`` was renamed to ``CONFIG_ESPI_TARGET``, similarly + ``CONFIG_ESPI_SAF`` was renamed as ``CONFIG_ESPI_TAF`` (:github:`73887`) Flash ===== @@ -390,6 +470,23 @@ LED Strip Sensors ======= +* The ``chip`` devicetree property from the :dtcompatible:`sensirion,shtcx` sensor driver has been + removed. Chip variants are now selected using the matching compatible property (:github:`74033`). + For an example of the new shtc3 configuration, see below: + + .. code-block:: devicetree + + &i2c0 { + status = "okay"; + + shtc3: shtc3@70 { + compatible = "sensirion,shtc3", "sensirion,shtcx"; + reg = <0x70>; + measure-mode = "normal"; + clock-stretching; + }; + }; + Serial ====== @@ -451,9 +548,44 @@ Bluetooth Audio the :c:func:`bt_bap_stream_connect` shall now be called before :c:func:`bt_bap_stream_start`. (:github:`73032`) +* Renamed ``stream_lang`` to just ``lang`` to better fit with the assigned numbers document. + This affects the ``BT_AUDIO_METADATA_TYPE_LANG`` macro and the following functions: + + * :c:func:`bt_audio_codec_cap_meta_set_lang` + * :c:func:`bt_audio_codec_cap_meta_get_lang` + * :c:func:`bt_audio_codec_cfg_meta_set_lang` + * :c:func:`bt_audio_codec_cfg_meta_get_lang` + + (:github:`72584`) + +* Changed ``lang`` from ``uint32_t`` to ``uint8_t [3]``. This modifies the following functions: + + * :c:func:`bt_audio_codec_cap_meta_set_lang` + * :c:func:`bt_audio_codec_cap_meta_get_lang` + * :c:func:`bt_audio_codec_cfg_meta_set_lang` + * :c:func:`bt_audio_codec_cfg_meta_get_lang` + + The result of this is that string values such as ``"eng"`` and ``"deu"`` can now be used to set + new values, and to prevent unnecessary copies of data when getting the values. (:github:`72584`) + * All occurrences of ``set_sirk`` have been changed to just ``sirk`` as the ``s`` in ``sirk`` stands for set. (:github:`73413`) +* Added ``fallback_to_default`` parameter to :c:func:`bt_audio_codec_cfg_get_chan_allocation`. + To maintain existing behavior set the parameter to ``false``. (:github:`72090`) + +* Added ``fallback_to_default`` parameter to + :c:func:`bt_audio_codec_cap_get_supported_audio_chan_counts`. + To maintain existing behavior set the parameter to ``false``. (:github:`72090`) + +* Added ``fallback_to_default`` parameter to + :c:func:`bt_audio_codec_cap_get_max_codec_frames_per_sdu`. + To maintain existing behavior set the parameter to ``false``. (:github:`72090`) + +* Added ``fallback_to_default`` parameter to + :c:func:`bt_audio_codec_cfg_meta_get_pref_context`. + To maintain existing behavior set the parameter to ``false``. (:github:`72090`) + Bluetooth Classic ================= @@ -548,6 +680,12 @@ Networking to receive all the network packets. See details in https://www.man7.org/linux/man-pages/man7/packet.7.html documentation. (:github:`73338`) +* TCP now uses SHA-256 instead of MD5 for ISN generation. The crypto support for + this hash computation was also changed from Mbed TLS to PSA APIs. This was achieved + by making :kconfig:option:`CONFIG_NET_TCP_ISN_RFC6528` depend on + :kconfig:option:`PSA_WANT_ALG_SHA_256` instead of legacy ``CONFIG_MBEDTLS_*`` + features. (:github:`71827`) + Other Subsystems **************** @@ -576,6 +714,19 @@ Modem * The ``CONFIG_MODEM_CHAT_LOG_BUFFER`` Kconfig option was renamed to :kconfig:option:`CONFIG_MODEM_CHAT_LOG_BUFFER_SIZE`. (:github:`70405`) +.. _zephyr_3.7_posix_api_migration: + +POSIX API +========= + +* The :ref:`POSIX API Kconfig deprecations ` may require + changes to Kconfig files (``prj.conf``, etc), as outlined in the release notes. A more automated + approach is available via the provided migration script. Simply run the following: + + .. code-block:: bash + + $ python ${ZEPHYR_BASE}/scripts/utils/migrate_posix_kconfigs.py -r root_path + Shell ===== diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 159b75aaae92fb..0bd55cee3d8d68 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -31,8 +31,14 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html * CVE-2024-3077 `Zephyr project bug tracker GHSA-gmfv-4vfh-2mh8 `_ +* CVE-2024-3332 Under embargo until 2024-07-01 + * CVE-2024-4785: Under embargo until 2024-08-07 +* CVE-2024-5754: Under embargo until 2024-09-04 + +* CVE-2024-5931: Under embargo until 2024-09-10 + API Changes *********** @@ -62,9 +68,61 @@ Deprecated in this release Application developer will now need to set the advertised name themselves by updating the advertising data or the scan response data. +.. _zephyr_3.7_posix_api_deprecations: + + * POSIX API + + * Deprecated :c:macro:`PTHREAD_BARRIER_DEFINE` has been removed. + * Deprecated :c:macro:`EFD_IN_USE` and :c:macro:`EFD_FLAGS_SET` have been removed. + + * In efforts to use Kconfig options that map directly to the Options and Option Groups in + IEEE 1003.1-2017, the following Kconfig options have been deprecated (replaced by): + + * :kconfig:option:`CONFIG_EVENTFD_MAX` (:kconfig:option:`CONFIG_ZVFS_EVENTFD_MAX`) + * :kconfig:option:`CONFIG_FNMATCH` (:kconfig:option:`CONFIG_POSIX_C_LIB_EXT`) + * :kconfig:option:`CONFIG_GETENTROPY` (:kconfig:option:`CONFIG_POSIX_C_LIB_EXT`) + * :kconfig:option:`CONFIG_GETOPT` (:kconfig:option:`CONFIG_POSIX_C_LIB_EXT`) +  * :kconfig:option:`CONFIG_MAX_PTHREAD_COUNT` (:kconfig:option:`CONFIG_POSIX_THREAD_THREADS_MAX`) + * :kconfig:option:`CONFIG_MAX_PTHREAD_KEY_COUNT` (:kconfig:option:`CONFIG_POSIX_THREAD_KEYS_MAX`) + * :kconfig:option:`CONFIG_MAX_TIMER_COUNT` (:kconfig:option:`CONFIG_POSIX_TIMER_MAX`) + * :kconfig:option:`CONFIG_POSIX_LIMITS_RTSIG_MAX` (:kconfig:option:`CONFIG_POSIX_RTSIG_MAX`) + * :kconfig:option:`CONFIG_POSIX_CLOCK` (:kconfig:option:`CONFIG_POSIX_CLOCK_SELECTION`, + :kconfig:option:`CONFIG_POSIX_CPUTIME`, :kconfig:option:`CONFIG_POSIX_MONOTONIC_CLOCK`, + :kconfig:option:`CONFIG_POSIX_TIMERS`, and :kconfig:option:`CONFIG_POSIX_TIMEOUTS`) + * :kconfig:option:`CONFIG_POSIX_CONFSTR` (:kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS`) + * :kconfig:option:`CONFIG_POSIX_ENV` (:kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS`) + * :kconfig:option:`CONFIG_POSIX_FS` (:kconfig:option:`CONFIG_POSIX_FILE_SYSTEM`) + * :kconfig:option:`CONFIG_POSIX_MAX_FDS` (:kconfig:option:`CONFIG_POSIX_OPEN_MAX` and + :kconfig:option:`CONFIG_ZVFS_OPEN_MAX`) + * :kconfig:option:`CONFIG_POSIX_MAX_OPEN_FILES` (:kconfig:option:`CONFIG_POSIX_OPEN_MAX` and + :kconfig:option:`CONFIG_ZVFS_OPEN_MAX`) + * :kconfig:option:`CONFIG_POSIX_MQUEUE` (:kconfig:option:`CONFIG_POSIX_MESSAGE_PASSING`) + * :kconfig:option:`CONFIG_POSIX_PUTMSG` (:kconfig:option:`CONFIG_XOPEN_STREAMS`) + * :kconfig:option:`CONFIG_POSIX_SIGNAL` (:kconfig:option:`CONFIG_POSIX_SIGNALS`) + * :kconfig:option:`CONFIG_POSIX_SYSCONF` (:kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS`) + * :kconfig:option:`CONFIG_POSIX_SYSLOG` (:kconfig:option:`CONFIG_XSI_SYSTEM_LOGGING`) + * :kconfig:option:`CONFIG_POSIX_UNAME` (:kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS`) + * :kconfig:option:`CONFIG_PTHREAD` (:kconfig:option:`CONFIG_POSIX_THREADS`) + * :kconfig:option:`CONFIG_PTHREAD_BARRIER` (:kconfig:option:`CONFIG_POSIX_BARRIERS`) + * :kconfig:option:`CONFIG_PTHREAD_COND` (:kconfig:option:`CONFIG_POSIX_THREADS`) + * :kconfig:option:`CONFIG_PTHREAD_IPC` (:kconfig:option:`CONFIG_POSIX_THREADS`) + * :kconfig:option:`CONFIG_PTHREAD_KEY` (:kconfig:option:`CONFIG_POSIX_THREADS`) + * :kconfig:option:`CONFIG_PTHREAD_MUTEX` (:kconfig:option:`CONFIG_POSIX_THREADS`) + * :kconfig:option:`CONFIG_PTHREAD_RWLOCK` (:kconfig:option:`CONFIG_POSIX_READER_WRITER_LOCKS`) + * :kconfig:option:`CONFIG_PTHREAD_SPINLOCK` (:kconfig:option:`CONFIG_POSIX_SPIN_LOCKS`) + * :kconfig:option:`CONFIG_SEM_NAMELEN_MAX` (:kconfig:option:`CONFIG_POSIX_SEM_NAMELEN_MAX`) + * :kconfig:option:`CONFIG_SEM_VALUE_MAX` (:kconfig:option:`CONFIG_POSIX_SEM_VALUE_MAX`) + * :kconfig:option:`CONFIG_TIMER` (:kconfig:option:`CONFIG_POSIX_TIMERS`) + * :kconfig:option:`CONFIG_TIMER_DELAYTIMER_MAX` (:kconfig:option:`CONFIG_POSIX_DELAYTIMER_MAX`) + + Please see the :ref:`POSIX API migration guide `. + * SPI * Deprecated :c:func:`spi_is_ready` API function has been removed. + * Deprecated :c:func:`spi_transceive_async` API function has been removed. + * Deprecated :c:func:`spi_read_async` API function has been removed. + * Deprecated :c:func:`spi_write_async` API function has been removed. Architectures ************* @@ -136,17 +194,25 @@ Bluetooth or speakers. The audio data is compressed in a proper format for efficient use of the limited bandwidth. +* HCI Driver + + * Added support for Ambiq Apollo3 Blue series. + Boards & SoC Support ******************** * Added support for these SoC series: + * Added support for Ambiq Apollo3 Blue and Apollo3 Blue Plus SoC series. + * Made these changes in other SoC series: * ITE: Rename the Kconfig symbol for all ITE SoC variants. * Added support for these ARM boards: + * Added support for Ambiq Apollo3 boards: ``apollo3_evb``, ``apollo3p_evb``. + * Added support for these Xtensa boards: * Made these changes for ARM boards: @@ -176,6 +242,8 @@ Build system and Infrastructure choice to select the C Standard version. Additionally subsystems can select a minimum required C Standard version, with for example :kconfig:option:`CONFIG_REQUIRES_STD_C11`. + * Fixed issue with passing UTF-8 configs to applications using sysbuild. + Drivers and Sensors ******************* @@ -214,6 +282,8 @@ Drivers and Sensors * Updated the CAN timing functions to take the minimum supported bitrate into consideration when validating the bitrate. * Made the ``sample-point`` and ``sample-point-data`` devicetree properties optional. + * Renamed the ``bus_speed`` and ``bus_speed_data`` fields of :c:struct:`can_driver_config` to + ``bitrate`` and ``bitrate_data``. * Charger @@ -226,6 +296,8 @@ Drivers and Sensors * Counter + * Added support for Ambiq Apollo3 series. + * Crypto * Display @@ -236,8 +308,8 @@ Drivers and Sensors * eSPI - * Renamed eSPI virtual wire direction macros and enum values to match the new terminology in - eSPI 1.5 specification. + * Renamed eSPI virtual wire direction macros, enum values and KConfig to match the new + terminology in eSPI 1.5 specification. * Ethernet @@ -248,12 +320,18 @@ Drivers and Sensors * Flash + * Added support for Ambiq Apollo3 series. + * GNSS * GPIO + * Added support for Ambiq Apollo3 series. + * I2C + * Added support for Ambiq Apollo3 series. + * I2S * I3C @@ -316,6 +394,9 @@ Drivers and Sensors * SPI + * Added support for Ambiq Apollo3 series general IOM based SPI. + * Added support for Ambiq Apollo3 BLEIF based SPI, which is specific for internal HCI. + * USB * W1 @@ -324,6 +405,7 @@ Drivers and Sensors * Added :kconfig:option:`CONFIG_WDT_NPCX_WARNING_LEADING_TIME_MS` to set the leading warning time in milliseconds. Removed no longer used :kconfig:option:`CONFIG_WDT_NPCX_DELAY_CYCLES`. + * Added support for Ambiq Apollo3 series. * Wi-Fi @@ -373,6 +455,11 @@ Networking * Removed IPSP support. ``CONFIG_NET_L2_BT`` does not exist anymore. +* TCP: + + * ISN generation now uses SHA-256 instead of MD5. Moreover it now relies on PSA APIs + instead of legacy Mbed TLS functions for hash computation. + USB *** @@ -412,6 +499,11 @@ Libraries / Subsystems registered to set the device attributes that are sent to the hawkBit server. Use the :c:func:`hawkbit_set_custom_data_cb` function to register the callback. + * MCUmgr + + * Instructions for the deprecated mcumgr go tool have been removed, a list of alternative, + supported clients can be found on :ref:`mcumgr_tools_libraries`. + * Logging * By enabling :kconfig:option:`CONFIG_LOG_BACKEND_NET_USE_DHCPV4_OPTION`, the IP address of the @@ -427,6 +519,17 @@ Libraries / Subsystems * Mbed TLS was updated to 3.6.0. Release notes can be found at: https://github.com/Mbed-TLS/mbedtls/releases/tag/v3.6.0 + * When any PSA crypto provider is available in the system + (:kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT` is enabled), desired PSA features + must now be explicitly selected through ``CONFIG_PSA_WANT_xxx`` symbols. + * Choice symbols :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_LEGACY_RNG` and + :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` were added in order + to allow the user to specify how Mbed TLS PSA crypto core should generate random numbers. + The former option, which is the default, relies on legacy entropy and CTR_DRBG/HMAC_DRBG + modules, while the latter relies on CSPRNG drivers. + * :kconfig:option:`CONFIG_MBEDTLS_PSA_P256M_DRIVER_ENABLED` enables support + for the Mbed TLS's p256-m driver PSA crypto library. This is a Cortex-M SW + optimized implementation of secp256r1 curve. * Random diff --git a/doc/safety/index.rst b/doc/safety/index.rst index 1eb55d12a325ec..734f9a19ac4ae7 100644 --- a/doc/safety/index.rst +++ b/doc/safety/index.rst @@ -11,3 +11,4 @@ for ensuring safety is addressed within the Zephyr project. :glob: safety_overview.rst + safety_requirements.rst diff --git a/doc/safety/safety_overview.rst b/doc/safety/safety_overview.rst index 9a17434e6d0fb8..39a9da169df8eb 100644 --- a/doc/safety/safety_overview.rst +++ b/doc/safety/safety_overview.rst @@ -99,7 +99,7 @@ which need to be reached to achieve an auditable code base: 1. Basic software quality standards a. :ref:`coding_guidelines` (including: static code analysis, coding style, etc.) - b. Requirements and requirements tracing + b. :ref:`safety_requirements` and requirements tracing c. Test coverage 2. Software architecture design principles diff --git a/doc/safety/safety_requirements.rst b/doc/safety/safety_requirements.rst new file mode 100644 index 00000000000000..097c9063b4977a --- /dev/null +++ b/doc/safety/safety_requirements.rst @@ -0,0 +1,120 @@ +.. _safety_requirements: + +Safety Requirements +################### + +Introduction +************ + +The safety committee leads the effort to gather requirements that reflect the **actual** state of +the implementation, following the `route 3s `_ +approach of the project's safety effort. The goal is **NOT** to create new requirements to request +additional features for the project. + +The requirements are gathered in the separate repository: +`Requirement repository +`__ + +Guidelines +********** + +Below are the guidelines for the requirements repository and the expectations of the safety +committee when adding requirements to the repository. + +Scope +===== + +The scope of the requirements covers the KERNEL functionalities. + +Consistency +=========== + +Maintain consistency across all requirements. The language and choice of words shall be consistent. +(See: `Syntax`_) + +Levels of requirements in the repository +======================================== + +System Requirements + System requirements describe the behaviour of the Zephyr RTOS (= the system here). + They describe the functionality of the Zephyr RTOS from a very high-level perspective, + without going into details of the functionality itself. + The purpose of the system requirements is to get an overview of the currently implemented features + of the Zephyr RTOS. + In other words a person writing these requirements usually has some knowledge of the Zephyr RTOS + Project as the requirements are specific to an RTOS. + +Software Requirements + Software requirements refine the system-level requirements at a more granular level so + that each requirement can be tested. + These requirements define the specific actions the feature shall be able to execute and the + behavior of the feature. + +Requirement UID (Unique identifier) Handling +============================================ + +The tool used to manage requirements, `strictDoc `_, is +responsible for handling the Unique Identifier (UID) associated with each requirement. To manage +UIDs, follow these steps: + +#. Don't add a requirement UID and UID field for new requirements +#. After completing work on the new requirements execute: ``strictDoc manage auto-uid .`` +#. Establish links between the requirements with the new attributed UIDs if needed + +After doing this, the requirements are ready and a pull request can be created. +The CI in the PR will check if the requirements UIDs are valid or if there are duplicates in it. +If there are duplicates in the PR, these need to be resolved by rebasing and re-executing +the steps above. + +Requirement Types +================= + +* Functional +* Non-Functional + +Requirement title convention +============================ + +Use short and succinct requirement titles. + +Pull Request requirement repository +=================================== + +* Adhere to the :ref:`contribute_guidelines` of the Zephyr Project. + + * As long as they are applicable to the requirements repository. + +* Avoid creating large commits that contain both trivial and non-trivial changes. + +* Avoid moving and changing requirements in the same commit. + +Characteristics of a good requirement +===================================== + +* Unambiguous +* Verifiable (e.g. testable for functional requirements) +* Clear (concise, succinct, simple, precise) +* Correct +* Understandable +* Feasible (realistic, possible) +* Independent +* Atomic +* Necessary +* Implementation-free (abstract) + +Characteristics of a set of requirements +======================================== + +* Complete +* Consistent +* Non redundant + +Syntax +====== + +* Use of a recognized Requirements Syntax is recommended. + + * `EARS `_ is a good reference. Particularly if you are + unfamiliar with requirements writing. + + * Other formats are accepted as long as the characteristics of a requirement from above are met. diff --git a/doc/security/security-overview.rst b/doc/security/security-overview.rst index 6ed15fa55ba892..53c956cbe53b56 100644 --- a/doc/security/security-overview.rst +++ b/doc/security/security-overview.rst @@ -122,14 +122,12 @@ Security Functionality The security functionality in Zephyr hinges mainly on the inclusion of cryptographic algorithms, and on its monolithic system design. -The cryptographic features are provided through a set of cryptographic -libraries. Applications can choose TinyCrypt2 or Mbed TLS based on their -needs. TinyCrypt2 supports key cryptographic algorithms required by the -connectivity stacks. TinyCrypt2, however, only provides a limited set of -algorithms. Mbed TLS supports a wider range of algorithms, but at the -cost of additional requirements such as malloc support. Applications can -choose the solution that matches their individual requirements. Future -work may include APIs to abstract the underlying crypto library choice. +The cryptographic features are provided through PSA Crypto, with +mbedTLS as the underlying implementation. Applications leverage PSA +Crypto APIs, ensuring a standardized and secure approach to +cryptographic operations. mbedTLS, as the implementation of PSA +Crypto, supports a wide range of cryptographic algorithms, making it +suitable for various application requirements. APIs for vendor specific cryptographic IPs in both hardware and software are planned, including secure key storage in the form of secure access diff --git a/doc/security/standards/etsi-303645.rst b/doc/security/standards/etsi-303645.rst index 552756997e2510..ce78c96ab676e9 100644 --- a/doc/security/standards/etsi-303645.rst +++ b/doc/security/standards/etsi-303645.rst @@ -177,9 +177,13 @@ Provisions Assessment * - N/A - The provision is not applicable to Zephyr or it is product makers responsibility +.. raw:: latex + + \begin{landscape} + .. list-table:: ETSI 303645 provisions assessment using table B.1 :header-rows: 1 - :widths: 17 63 17 63 63 + :widths: 25 80 15 15 60 * - Provision - Description @@ -729,3 +733,7 @@ Provisions Assessment - M C - N/A - + +.. raw:: latex + + \end{landscape} diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 77f39e79ea1f28..f087886de34949 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1717,7 +1717,22 @@ This has been fixed in main for v3.7.0 - `PR 69396 fix for main `_ +CVE-2024-3332 +------------- + +Under embargo until 2024-07-01 + CVE-2024-4785 ------------- Under embargo until 2024-08-07 + +CVE-2024-5754 +------------- + +Under embargo until 2024-09-04 + +CVE-2024-5931 +------------- + +Under embargo until 2024-09-10 diff --git a/doc/services/crypto/index.rst b/doc/services/crypto/index.rst index 988366c2e62f97..2ac0f534208c14 100644 --- a/doc/services/crypto/index.rst +++ b/doc/services/crypto/index.rst @@ -13,6 +13,6 @@ The following crypto libraries have been included: .. toctree:: :maxdepth: 1 - tinycrypt.rst + psa_crypto.rst random/index.rst api/index.rst diff --git a/doc/services/crypto/psa_crypto.rst b/doc/services/crypto/psa_crypto.rst new file mode 100644 index 00000000000000..fe5360e9967186 --- /dev/null +++ b/doc/services/crypto/psa_crypto.rst @@ -0,0 +1,181 @@ +.. _psa_crypto: + +PSA Crypto +########## + +Overview +******** + +The PSA (Platform Security Architecture) Crypto API offers a portable +programming interface for cryptographic operations and key storage +across a wide range of hardware. It is designed to be user-friendly +while still providing access to the low-level primitives essential for +modern cryptography. + +It is created and maintained by Arm. Arm developed the PSA as a +comprehensive security framework to address the increasing security +needs of connected devices. + +In Zephyr, the PSA Crypto API is implemented using Mbed TLS, an +open-source cryptographic library that provides the underlying +cryptographic functions. + +Design Goals +************ + +The interface is suitable for a vast range of devices: from +special-purpose cryptographic processors that process data with a +built-in key, to constrained devices running custom application code, +such as microcontrollers, and multi-application devices, such as +servers. It follows the principle of cryptographic agility. + +Algorithm Flexibility + The PSA Crypto API supports a wide range of cryptographic algorithms, + allowing developers to switch between different cryptographic + methods as needed. This flexibility is crucial for maintaining + security as new algorithms emerge and existing ones become obsolete. + +Key Management + The PSA Crypto API includes robust key management features that + support the creation, storage, and use of cryptographic keys in a + secure and flexible manner. It uses opaque key identifiers, which + allows for easy key replacement and updates without exposing key + material. + +Implementation Independence + The PSA Crypto API abstracts the underlying cryptographic library, + meaning that the specific implementation can be changed without + affecting the application code. This abstraction supports + cryptographic agility by enabling the use of different cryptographic + libraries or hardware accelerators as needed. + +Future-Proofing + By adhering to cryptographic agility, PSA Crypto ensures that + applications can quickly adapt to new cryptographic standards and + practices, enhancing long-term security and compliance. + +Examples of Applications +************************ + +Network Security (TLS) + The API provides all of the cryptographic primitives needed to establish TLS connections. + +Secure Storage + The API provides all primitives related to storage encryption, block + or file-based, with master encryption keys stored inside a key store. + +Network Credentials + The API provides network credential management inside a key store, + for example, for X.509-based authentication or pre-shared keys on + enterprise networks. + +Device Pairing + The API provides support for key agreement protocols that are often + used for secure pairing of devices over wireless channels. For + example, the pairing of an NFC token or a Bluetooth device might use + key agreement protocols upon first use. + +Secure Boot + The API provides primitives for use during firmware integrity and + authenticity validation, during a secure or trusted boot process. + +Attestation + The API provides primitives used in attestation + activities. Attestation is the ability for a device to sign an array + of bytes with a device private key and return the result to the + caller. There are several use cases; ranging from attestation of the + device state, to the ability to generate a key pair and prove that it + has been generated inside a secure key store. The API provides access + to the algorithms commonly used for attestation. + +Factory Provisioning + Most IoT devices receive a unique identity during the factory + provisioning process, or once they have been deployed to the + field. This API provides the APIs necessary for populating a device + with keys that represent that identity. + +Usage considerations +******************** + +Always check for errors + Most functions in the PSA Crypto API can return errors. All functions + that can fail have the return type ``psa_status_t``. A few functions + cannot fail, and thus, return void or some other type. + + If an error occurs, unless otherwise specified, the content of the + output parameters is undefined and must not be used. + + Some common causes of errors include: + + * In implementations where the keys are stored and processed in a + separate environment from the application, all functions that need + to access the cryptography processing environment might fail due + to an error in the communication between the two environments. + + * If an algorithm is implemented with a hardware accelerator, which + is logically separate from the application processor, the + accelerator might fail, even when the application processor keeps + running normally. + + * Most functions might fail due to a lack of resources. However, + some implementations guarantee that certain functions always have + sufficient memory. + + * All functions that access persistent keys might fail due to a + storage failure. + + * All functions that require randomness might fail due to a lack of + entropy. Implementations are encouraged to seed the random + generator with sufficient entropy during the execution of + ``psa_crypto_init()``. However, some security standards require + periodic reseeding from a hardware random generator, which can + fail. + +Shared memory and concurrency + Some environments allow applications to be multithreaded, while + others do not. In some environments, applications can share memory + with a different security context. In environments with + multithreaded applications or shared memory, applications must be + written carefully to avoid data corruption or leakage. This + specification requires the application to obey certain constraints. + + In general, the PSA Crypto API allows either one writer or any number of + simultaneous readers, on any given object. In other words, if two or + more calls access the same object concurrently, then the behavior is + only well-defined if all the calls are only reading from the object + and do not modify it. Read accesses include reading memory by input + parameters and reading keystore content by using a key. For more + details, refer to `Concurrent calls + `_ + + If an application shares memory with another security context, it + can pass shared memory blocks as input buffers or output buffers, + but not as non-buffer parameters. For more details, refer to + `Stability of parameters `_. + +Cleaning up after use + To minimize impact if the system is compromised, it is recommended + that applications wipe all sensitive data from memory when it is no + longer used. That way, only data that is currently in use can be + leaked, and past data is not compromised. + + Wiping sensitive data includes: + + * Clearing temporary buffers in the stack or on the heap. + + * Aborting operations if they will not be finished. + + * Destroying keys that are no longer used. + +References +********** + +* `PSA Crypto`_ + +.. _PSA Crypto: + https://arm-software.github.io/psa-api/crypto/ + +* `Mbed TLS`_ + +.. _Mbed TLS: + https://www.trustedfirmware.org/projects/mbed-tls/ diff --git a/doc/services/crypto/tinycrypt.rst b/doc/services/crypto/tinycrypt.rst deleted file mode 100644 index 1757ac350e7f56..00000000000000 --- a/doc/services/crypto/tinycrypt.rst +++ /dev/null @@ -1,325 +0,0 @@ -.. _tinycrypt: - -TinyCrypt Cryptographic Library -############################### - -Overview -******** -The TinyCrypt Library provides an implementation for targeting constrained devices -with a minimal set of standard cryptography primitives, as listed below. To better -serve applications targeting constrained devices, TinyCrypt implementations differ -from the standard specifications (see the Important Remarks section for some -important differences). Certain cryptographic primitives depend on other -primitives, as mentioned in the list below. - -Aside from the Important Remarks section below, valuable information on the usage, -security and technicalities of each cryptographic primitive are found in the -corresponding header file. - -* SHA-256: - - * Type of primitive: Hash function. - * Standard Specification: NIST FIPS PUB 180-4. - * Requires: -- - -* HMAC-SHA256: - - * Type of primitive: Message authentication code. - * Standard Specification: RFC 2104. - * Requires: SHA-256 - -* HMAC-PRNG: - - * Type of primitive: Pseudo-random number generator. - * Standard Specification: NIST SP 800-90A. - * Requires: SHA-256 and HMAC-SHA256. - -* AES-128: - - * Type of primitive: Block cipher. - * Standard Specification: NIST FIPS PUB 197. - * Requires: -- - -* AES-CBC mode: - - * Type of primitive: Encryption mode of operation. - * Standard Specification: NIST SP 800-38A. - * Requires: AES-128. - -* AES-CTR mode: - - * Type of primitive: Encryption mode of operation. - * Standard Specification: NIST SP 800-38A. - * Requires: AES-128. - -* AES-CMAC mode: - - * Type of primitive: Message authentication code. - * Standard Specification: NIST SP 800-38B. - * Requires: AES-128. - -* AES-CCM mode: - - * Type of primitive: Authenticated encryption. - * Standard Specification: NIST SP 800-38C. - * Requires: AES-128. - -* ECC-DH: - - * Type of primitive: Key exchange. - * Standard Specification: RFC 6090. - * Requires: ECC auxiliary functions (ecc.h/c). - -* ECC-DSA: - - * Type of primitive: Digital signature. - * Standard Specification: RFC 6090. - * Requires: ECC auxiliary functions (ecc.h/c). - -Design Goals -************ - -* Minimize the code size of each cryptographic primitive. This means minimize - the size of a board-independent implementation, as presented in TinyCrypt. - Note that various applications may require further features, optimizations with - respect to other metrics and countermeasures for particular threats. These - peculiarities would increase the code size and thus are not considered here. - -* Minimize the dependencies among the cryptographic primitives. This means - that it is unnecessary to build and allocate object code for more primitives - than the ones strictly required by the intended application. In other words, - one can select and compile only the primitives required by the application. - - -Important Remarks -***************** - -The cryptographic implementations in TinyCrypt library have some limitations. -Some of these limitations are inherent to the cryptographic primitives -themselves, while others are specific to TinyCrypt. Some of these limitations -are discussed in-depth below. - -General Remarks -*************** - -* TinyCrypt does **not** intend to be fully side-channel resistant. Due to the - variety of side-channel attacks, many of them making certain boards - vulnerable. In this sense, instead of penalizing all library users with - side-channel countermeasures such as increasing the overall code size, - TinyCrypt only implements certain generic timing-attack countermeasures. - -Specific Remarks -**************** - -* SHA-256: - - * The number of bits_hashed in the state is not checked for overflow. Note - however that this will only be a problem if you intend to hash more than - 2^64 bits, which is an extremely large window. - -* HMAC: - - * The HMAC verification process is assumed to be performed by the application. - This compares the computed tag with some given tag. - Note that conventional memory-comparison methods (such as memcmp function) - might be vulnerable to timing attacks; thus be sure to use a constant-time - memory comparison function (such as compare_constant_time - function provided in lib/utils.c). - -* HMAC-PRNG: - - * Before using HMAC-PRNG, you *must* find an entropy source to produce a seed. - PRNGs only stretch the seed into a seemingly random output of arbitrary - length. The security of the output is exactly equal to the - unpredictability of the seed. - - * NIST SP 800-90A requires three items as seed material in the initialization - step: entropy seed, personalization and a nonce (which is not implemented). - TinyCrypt requires the personalization byte array and automatically creates - the entropy seed using a mandatory call to the re-seed function. - -* AES-128: - - * The current implementation does not support other key-lengths (such as 256 - bits). Note that if you need AES-256, it doesn't sound as though your - application is running in a constrained environment. AES-256 requires keys - twice the size as for AES-128, and the key schedule is 40% larger. - -* CTR mode: - - * The AES-CTR mode limits the size of a data message they encrypt to 2^32 - blocks. If you need to encrypt larger data sets, your application would - need to replace the key after 2^32 block encryptions. - -* CBC mode: - - * TinyCrypt CBC decryption assumes that the iv and the ciphertext are - contiguous (as produced by TinyCrypt CBC encryption). This allows for a - very efficient decryption algorithm that would not otherwise be possible. - -* CMAC mode: - - * AES128-CMAC mode of operation offers 64 bits of security against collision - attacks. Note however that an external attacker cannot generate the tags - him/herself without knowing the MAC key. In this sense, to attack the - collision property of AES128-CMAC, an external attacker would need the - cooperation of the legal user to produce an exponentially high number of - tags (e.g. 2^64) to finally be able to look for collisions and benefit - from them. As an extra precaution, the current implementation allows to at - most 2^48 calls to tc_cmac_update function before re-calling tc_cmac_setup - (allowing a new key to be set), as suggested in Appendix B of SP 800-38B. - -* CCM mode: - - * There are a few tradeoffs for the selection of the parameters of CCM mode. - In special, there is a tradeoff between the maximum number of invocations - of CCM under a given key and the maximum payload length for those - invocations. Both things are related to the parameter 'q' of CCM mode. The - maximum number of invocations of CCM under a given key is determined by - the nonce size, which is: 15-q bytes. The maximum payload length for those - invocations is defined as 2^(8q) bytes. - - To achieve minimal code size, TinyCrypt CCM implementation fixes q = 2, - which is a quite reasonable choice for constrained applications. The - implications of this choice are: - - The nonce size is: 13 bytes. - - The maximum payload length is: 2^16 bytes = 65 KB. - - The mac size parameter is an important parameter to estimate the security - against collision attacks (that aim at finding different messages that - produce the same authentication tag). TinyCrypt CCM implementation - accepts any even integer between 4 and 16, as suggested in SP 800-38C. - - * TinyCrypt CCM implementation accepts associated data of any length between - 0 and (2^16 - 2^8) = 65280 bytes. - - * TinyCrypt CCM implementation accepts: - - * Both non-empty payload and associated data (it encrypts and - authenticates the payload and only authenticates the associated data); - - * Non-empty payload and empty associated data (it encrypts and - authenticates the payload); - - * Non-empty associated data and empty payload (it degenerates to an - authentication-only mode on the associated data). - - * RFC-3610, which also specifies CCM, presents a few relevant security - suggestions, such as: it is recommended for most applications to use a - mac size greater than 8. Besides, it is emphasized that the usage of the - same nonce for two different messages which are encrypted with the same - key obviously destroys the security properties of CCM mode. - -* ECC-DH and ECC-DSA: - - * TinyCrypt ECC implementation is based on nano-ecc (see - https://github.com/iSECPartners/nano-ecc) which in turn is based on - micro-ecc (see https://github.com/kmackay/micro-ecc). In the original - nano and micro-ecc documentation, there is an important remark about the - way integers are represented: - - "Integer representation: To reduce code size, all large integers are - represented using little-endian words - so the least significant word is - first. You can use the 'ecc_bytes2native()' and 'ecc_native2bytes()' - functions to convert between the native integer representation and the - standardized octet representation." - -Examples of Applications -************************ -It is possible to do useful cryptography with only the given small set of -primitives. With this list of primitives it becomes feasible to support a range -of cryptography usages: - - * Measurement of code, data structures, and other digital artifacts (SHA256); - - * Generate commitments (SHA256); - - * Construct keys (HMAC-SHA256); - - * Extract entropy from strings containing some randomness (HMAC-SHA256); - - * Construct random mappings (HMAC-SHA256); - - * Construct nonces and challenges (HMAC-PRNG); - - * Authenticate using a shared secret (HMAC-SHA256); - - * Create an authenticated, replay-protected session (HMAC-SHA256 + HMAC-PRNG); - - * Authenticated encryption (AES-128 + AES-CCM); - - * Key-exchange (EC-DH); - - * Digital signature (EC-DSA); - -Test Vectors -************ - -The library provides a test program for each cryptographic primitive (see 'test' -folder). Besides illustrating how to use the primitives, these tests evaluate -the correctness of the implementations by checking the results against -well-known publicly validated test vectors. - -For the case of the HMAC-PRNG, due to the necessity of performing an extensive -battery test to produce meaningful conclusions, we suggest the user to evaluate -the unpredictability of the implementation by using the NIST Statistical Test -Suite (see References). - -For the case of the EC-DH and EC-DSA implementations, most of the test vectors -were obtained from the site of the NIST Cryptographic Algorithm Validation -Program (CAVP), see References. - -References -********** - -* `NIST FIPS PUB 180-4 (SHA-256)`_ - -.. _NIST FIPS PUB 180-4 (SHA-256): - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf - -* `NIST FIPS PUB 197 (AES-128)`_ - -.. _NIST FIPS PUB 197 (AES-128): - http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - -* `NIST SP800-90A (HMAC-PRNG)`_ - -.. _NIST SP800-90A (HMAC-PRNG): - http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf - -* `NIST SP 800-38A (AES-CBC and AES-CTR)`_ - -.. _NIST SP 800-38A (AES-CBC and AES-CTR): - http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - -* `NIST SP 800-38B (AES-CMAC)`_ - -.. _NIST SP 800-38B (AES-CMAC): - http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf - -* `NIST SP 800-38C (AES-CCM)`_ - -.. _NIST SP 800-38C (AES-CCM): - http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - -* `NIST Statistical Test Suite`_ - -.. _NIST Statistical Test Suite: - http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html - -* `NIST Cryptographic Algorithm Validation Program (CAVP) site`_ - -.. _NIST Cryptographic Algorithm Validation Program (CAVP) site: - http://csrc.nist.gov/groups/STM/cavp/ - -* `RFC 2104 (HMAC-SHA256)`_ - -.. _RFC 2104 (HMAC-SHA256): - https://www.ietf.org/rfc/rfc2104.txt - -* `RFC 6090 (ECC-DH and ECC-DSA)`_ - -.. _RFC 6090 (ECC-DH and ECC-DSA): - https://www.ietf.org/rfc/rfc6090.txt diff --git a/doc/services/device_mgmt/mcumgr.rst b/doc/services/device_mgmt/mcumgr.rst index 905307ab424aee..0f4f57e7954ee8 100644 --- a/doc/services/device_mgmt/mcumgr.rst +++ b/doc/services/device_mgmt/mcumgr.rst @@ -113,203 +113,6 @@ project. Note that a tick for a particular group indicates basic support for that group in the code, it is possible that not all commands/features of a group are supported by the implementation. -.. _mcumgr_cli: - -Command-line Tool -***************** - -MCUmgr provides a command-line tool, :file:`mcumgr`, for managing remote devices. -The tool is written in the Go programming language. - -.. note:: - This tool is provided for evaluation use only and is not recommended for - use in a production environment. It has known issues and will not respect - the MCUmgr protocol properly e.g. when an error is received, instead of - aborting will, in some circumstances, sit in an endless loop of sending the - same command over and over again. A universal replacement for this tool is - currently in development and once released, support for the go tool will be - dropped entirely. It is recommended that usage of tools listed above in the - :ref:`mcumgr_tools_libraries` section are used instead of the go client. - -To install the tool: - -.. tabs:: - - .. group-tab:: go version < 1.18 - - .. code-block:: console - - go get github.com/apache/mynewt-mcumgr-cli/mcumgr - - .. group-tab:: go version >= 1.18 - - .. code-block:: console - - go install github.com/apache/mynewt-mcumgr-cli/mcumgr@latest - -Configuring the transport -************************* - -There are two command-line options that are responsible for setting and configuring -the transport layer to use when communicating with managed device: - -* ``--conntype`` is used to choose the transport used, and -* ``--connstring`` is used to pass a comma separated list of options in the - ``key=value`` format, where each valid ``key`` depends on the particular - ``conntype``. - -Valid transports for ``--conntype`` are ``serial``, ``ble`` and ``udp``. Each -transport expects a different set of key/value options: - -.. tabs:: - - .. group-tab:: serial - - ``--connstring`` accepts the following ``key`` values: - - .. list-table:: - :width: 100% - :widths: 10 60 - - * - ``dev`` - - the device name for the OS ``mcumgr`` is running on (eg, ``/dev/ttyUSB0``, ``/dev/tty.usbserial``, ``COM1``, etc). - * - ``baud`` - - the communication speed; must match the baudrate of the server. - * - ``mtu`` - - aka Maximum Transmission Unit, the maximum protocol packet size. - - .. group-tab:: ble - - ``--connstring`` accepts the following ``key`` values: - - .. list-table:: - :width: 100% - :widths: 10 60 - - * - ``ctlr_name`` - - an OS specific string for the controller name. - * - ``own_addr_type`` - - can be one of ``public``, ``random``, ``rpa_pub``, ``rpa_rnd``, where ``random`` is the default. - * - ``peer_name`` - - the name the peer BLE device advertises, this should match the configuration specified with :kconfig:option:`CONFIG_BT_DEVICE_NAME`. - * - ``peer_id`` - - the peer BLE device address or UUID. Only required when ``peer_name`` was not given. The format depends on the OS where ``mcumgr`` is run, it is a 6 bytes hexadecimal string separated by colons on Linux, or a 128-bit UUID on macOS. - * - ``conn_timeout`` - - a float number representing the connection timeout in seconds. - - .. group-tab:: udp - - ``--connstring`` takes the form ``[addr]:port`` where: - - .. list-table:: - :width: 100% - :widths: 10 60 - - * - ``addr`` - - can be a DNS name (if it can be resolved to the device IP), IPv4 addr (app must be - built with :kconfig:option:`CONFIG_MCUMGR_TRANSPORT_UDP_IPV4`), or IPv6 addr (app must be built with :kconfig:option:`CONFIG_MCUMGR_TRANSPORT_UDP_IPV6`) - * - ``port`` - - any valid UDP port. - -Saving the connection config -**************************** - -The transport configuration can be managed with the ``conn`` sub-command and -later used with ``--conn`` (or ``-c``) parameter to skip typing both ``--conntype`` -and ``--connstring``. For example a new config for a serial device that would -require typing ``mcumgr --conntype serial --connstring dev=/dev/ttyACM0,baud=115200,mtu=512`` -can be saved with:: - - mcumgr conn add acm0 type="serial" connstring="dev=/dev/ttyACM0,baud=115200,mtu=512" - -Accessing this port can now be done with:: - - mcumgr -c acm0 - -.. _general_options: - -General options -*************** - -Some options work for every ``mcumgr`` command and might be helpful to debug and fix -issues with the communication, among them the following deserve special mention: - -.. list-table:: - :width: 100% - :widths: 10 60 - - * - ``-l `` - - Configures the log level, which can be one of ``critical``, ``error``, - ``warn``, ``info`` or ``debug``, from less to most verbose. When there are - communication issues, ``-lDEBUG`` might be useful to dump the packets for - later inspection. - * - ``-t `` - - Changes the timeout waiting for a response from the default of 10s to a - given value. Some commands might take a long time of processing, eg, the - erase before an image upload, and might need incrementing the timeout to - a larger value. - * - ``-r `` - - Changes the number of retries on timeout from the default of 1 to a given - value. - -List of Commands -**************** - -Not all commands defined by ``mcumgr`` (and SMP protocol) are currently supported -on Zephyr. The ones that are supported are described in the following table: - -.. tip:: Running ``mcumgr`` with no parameters, or ``-h`` will display the list - of commands. - -.. list-table:: - :widths: 10 30 - :header-rows: 1 - - * - Command - - Description - * - ``echo`` - - Send data to a device and display the echoed back data. This command is - part of the ``OS`` group, which must be enabled by setting - :kconfig:option:`CONFIG_MCUMGR_GRP_OS`. The ``echo`` command itself can be - enabled by setting :kconfig:option:`CONFIG_MCUMGR_GRP_OS_ECHO`. - * - ``fs`` - - Access files on a device. More info in :ref:`fs_mgmt`. - * - ``image`` - - Manage images on a device. More info in :ref:`image_mgmt`. - * - ``reset`` - - Perform a soft reset of a device. This command is part of the ``OS`` - group, which must be enabled by setting :kconfig:option:`CONFIG_MCUMGR_GRP_OS`. - The ``reset`` command itself is always enabled and the time taken for a - reset to happen can be set with :kconfig:option:`CONFIG_MCUMGR_GRP_OS_RESET_MS` (in ms). - * - ``shell`` - - Execute a command in the remote shell. This option is disabled by default - and can be enabled with :kconfig:option:`CONFIG_MCUMGR_GRP_SHELL` = ``y``. - To know more about the shell in Zephyr check :ref:`shell_api`. - * - ``stat`` - - Read statistics from a device. More info in :ref:`stats_mgmt`. - * - ``taskstat`` - - Read task statistics from a device. This command is part of the ``OS`` - group, which must be enabled by setting :kconfig:option:`CONFIG_MCUMGR_GRP_OS`. - The ``taskstat`` command itself can be enabled by setting - :kconfig:option:`CONFIG_MCUMGR_GRP_OS_TASKSTAT`. :kconfig:option:`CONFIG_THREAD_MONITOR` also - needs to be enabled otherwise a ``-8`` (``MGMT_ERR_ENOTSUP``) will be - returned. - -.. tip:: - - ``taskstat`` has a few options that might require tweaking. The - :kconfig:option:`CONFIG_THREAD_NAME` must be set to display the task names, otherwise - the priority is displayed. Since the ``taskstat`` packets are large, they - might need increasing the :kconfig:option:`CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE` option. - -.. warning:: - - To display the correct stack size in the ``taskstat`` command, the - :kconfig:option:`CONFIG_THREAD_STACK_INFO` option must be set. - To display the correct stack usage in the ``taskstat`` command, both - :kconfig:option:`CONFIG_THREAD_STACK_INFO` and :kconfig:option:`CONFIG_INIT_STACKS` options - must be set. - .. _mcumgr_jlink_ob_virtual_msd: J-Link Virtual MSD Interaction Note @@ -325,343 +128,6 @@ management commands for updating firmware). This issue can be resolved by disabling MSD functionality on the J-Link device, follow the instructions on :ref:`nordic_segger_msd` to disable MSD support. -.. _image_mgmt: - -Image Management -**************** - -The image management provided by ``mcumgr`` is based on the image format defined -by MCUboot. For more details on the internals see `MCUboot design`_ and :ref:`west-sign`. - -To list available images in a device:: - - mcumgr image list - -This should result in an output similar to this:: - - $ mcumgr -c acm0 image list - Images: - image=0 slot=0 - version: 1.0.0 - bootable: true - flags: active confirmed - hash: 86dca73a3439112b310b5e033d811ec2df728d2264265f2046fced5a9ed00cc7 - Split status: N/A (0) - -Where ``image`` is the number of the image pair in a multi-image system, and slot -is the number of the slot where the image is stored, ``0`` for primary and ``1`` for -secondary. This image being ``active`` and ``confirmed`` means it will run again on -next reset. Also relevant is the ``hash``, which is used by other commands to -refer to this specific image when performing operations. - -An image can be manually erased using:: - - mcumgr image erase - -The behavior of ``erase`` is defined by the server (``MCUmgr`` in the device). -The current implementation is limited to erasing the image in the secondary -partition. - -To upload a new image:: - - mcumgr image upload [-n] [-e] [-u] [-w] - -* ``-n``: This option allows uploading a new image to a specific set of images - in a multi-image system, and is currently only supported by MCUboot when the - CONFIG\ _MCUBOOT_SERIAL option is enabled. - -* ``-e``: This option avoids performing a full erase of the partition before - starting a new upload. - -.. tip:: - - The ``-e`` option should always be passed in because the ``upload`` command - already checks if an erase is required, respecting the - :kconfig:option:`CONFIG_IMG_ERASE_PROGRESSIVELY` setting. - -.. tip:: - - If the ``upload`` command times out while waiting for a response from the - device, ``-t`` might be used to increase the wait time to something larger - than the default of 10s. See general_options_. - -.. warning:: - - ``mcumgr`` does not understand .hex files, when uploading a new image always - use the .bin file. - -* ``-u``: This option allows upgrading only to newer image version. - -* ``-w``: This option allows setting the maximum size for the window of outstanding chunks in transit. - It is set to 5 by default. - - .. tip:: - - If the option is set to a value lower than the default one, for example ``-w 1``, less chunks are transmitted on the window, - resulting in lower risk of errors. Conversely, setting a value higher than 5 increases risk of errors and may impact performance. - -After an image upload is finished, a new ``image list`` would now have an output -like this:: - - $ mcumgr -c acm0 image upload -e build/zephyr/zephyr.signed.bin - 35.69 KiB / 92.92 KiB [==========>---------------] 38.41% 2.97 KiB/s 00m19 - -Now listing the images again:: - - $ mcumgr -c acm0 image list - Images: - image=0 slot=0 - version: 1.0.0 - bootable: true - flags: active confirmed - hash: 86dca73a3439112b310b5e033d811ec2df728d2264265f2046fced5a9ed00cc7 - image=0 slot=1 - version: 1.1.0 - bootable: true - flags: - hash: e8cf0dcef3ec8addee07e8c4d5dc89e64ba3fae46a2c5267fc4efbea4ca0e9f4 - Split status: N/A (0) - -To test a new upgrade image the ``test`` command is used:: - - mcumgr image test - -This command should mark a ``test`` upgrade, which means that after the next -reboot the bootloader will execute the upgrade and jump into the new image. If no -other image operations are executed on the newly running image, it will ``revert`` -back to the image that was previously running on the device on the subsequent reset. -When a ``test`` is requested, ``flags`` will be updated with ``pending`` to inform -that a new image will be run after a reset:: - - $ mcumgr -c acm0 image test e8cf0dcef3ec8addee07e8c4d5dc89e64ba3fae46a2c5267fc4efbea4ca0e9f4 - Images: - image=0 slot=0 - version: 1.0.0 - bootable: true - flags: active confirmed - hash: 86dca73a3439112b310b5e033d811ec2df728d2264265f2046fced5a9ed00cc7 - image=0 slot=1 - version: 1.1.0 - bootable: true - flags: pending - hash: e8cf0dcef3ec8addee07e8c4d5dc89e64ba3fae46a2c5267fc4efbea4ca0e9f4 - Split status: N/A (0) - -After a reset the output with change to:: - - $ mcumgr -c acm0 image list - Images: - image=0 slot=0 - version: 1.1.0 - bootable: true - flags: active - hash: e8cf0dcef3ec8addee07e8c4d5dc89e64ba3fae46a2c5267fc4efbea4ca0e9f4 - image=0 slot=1 - version: 1.0.0 - bootable: true - flags: confirmed - hash: 86dca73a3439112b310b5e033d811ec2df728d2264265f2046fced5a9ed00cc7 - Split status: N/A (0) - -.. tip:: - - It's important to mention that an upgrade only ever happens if the image is - valid. The first thing MCUboot does when an upgrade is requested is to - validate the image, using the SHA-256 and/or the signature (depending on - the configuration). So before uploading an image, one way to be sure it is - valid is to run ``imgtool verify -k ``, - where ``-k image confirm "" - -The ``confirm`` command can also be run passing in a ``hash`` so that instead of -doing a ``test``/``revert`` procedure, the image in the secondary partition is -directly upgraded to, eg:: - - mcumgr image confirm - -.. tip:: - - The whole ``test``/``revert`` cycle does not need to be done using only the - ``mcumgr`` command-line tool. A better alternative is to perform a ``test`` - and allow the new running image to self-confirm after any checks by calling - :c:func:`boot_write_img_confirmed`. - -.. tip:: - - Building with :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR` enables better error - messages when failures happen (but increases the application size). - -.. _stats_mgmt: - -Statistics Management -********************* - -Statistics are used for troubleshooting, maintenance, and usage monitoring; it -consists basically of user-defined counters which are tightly connected to -``mcumgr`` and can be used to track any information for easy retrieval. The -available sub-commands are:: - - mcumgr stat list - mcumgr stat - -Statistics are organized in sections (also called groups), and each section can -be individually queried. Defining new statistics sections is done by using macros -available under :file:`zephyr/stats/stats.h`. Each section consists of multiple -variables (or counters), all with the same size (16, 32 or 64 bits). - -To create a new section ``my_stats``:: - - STATS_SECT_START(my_stats) - STATS_SECT_ENTRY(my_stat_counter1) - STATS_SECT_ENTRY(my_stat_counter2) - STATS_SECT_ENTRY(my_stat_counter3) - STATS_SECT_END; - - STATS_SECT_DECL(my_stats) my_stats; - -Each entry can be declared with :c:macro:`STATS_SECT_ENTRY` (or the equivalent -:c:macro:`STATS_SECT_ENTRY32`), :c:macro:`STATS_SECT_ENTRY16` or -:c:macro:`STATS_SECT_ENTRY64`. -All statistics in a section must be declared with the same size. - -The statistics counters can either have names or not, depending on the setting -of the :kconfig:option:`CONFIG_STATS_NAMES` option. Using names requires an extra -declaration step:: - - STATS_NAME_START(my_stats) - STATS_NAME(my_stats, my_stat_counter1) - STATS_NAME(my_stats, my_stat_counter2) - STATS_NAME(my_stats, my_stat_counter3) - STATS_NAME_END(my_stats); - -.. tip:: - - Disabling :kconfig:option:`CONFIG_STATS_NAMES` will free resources. When this option - is disabled the ``STATS_NAME*`` macros output nothing, so adding them in the - code does not increase the binary size. - -.. tip:: - - :kconfig:option:`CONFIG_MCUMGR_GRP_STAT_MAX_NAME_LEN` sets the maximum length of a section - name that can can be accepted as parameter for showing the section data, and - might require tweaking for long section names. - -The final steps to use a statistics section is to initialize and register it:: - - rc = STATS_INIT_AND_REG(my_stats, STATS_SIZE_32, "my_stats"); - assert (rc == 0); - -In the running code a statistics counter can be incremented by 1 using -:c:macro:`STATS_INC`, by N using :c:macro:`STATS_INCN` or reset with -:c:macro:`STATS_CLEAR`. - -Let's suppose we want to increment those counters by ``1``, ``2`` and ``3`` -every second. To get a list of stats:: - - $ mcumgr --conn acm0 stat list - stat groups: - my_stats - -To get the current value of the counters in ``my_stats``:: - - $ mcumgr --conn acm0 stat my_stats - stat group: my_stats - 13 my_stat_counter1 - 26 my_stat_counter2 - 39 my_stat_counter3 - - $ mcumgr --conn acm0 stat my_stats - stat group: my_stats - 16 my_stat_counter1 - 32 my_stat_counter2 - 48 my_stat_counter3 - -When :kconfig:option:`CONFIG_STATS_NAMES` is disabled the output will look like this:: - - $ mcumgr --conn acm0 stat my_stats - stat group: my_stats - 8 s0 - 16 s1 - 24 s2 - -.. _fs_mgmt: - -Filesystem Management -********************* - -The filesystem module is disabled by default due to security concerns: -because of a lack of access control by default, every file in the FS will be -accessible, including secrets, etc. To enable it -:kconfig:option:`CONFIG_MCUMGR_GRP_FS` must be set (``y``). Once enabled the -following sub-commands can be used:: - - mcumgr fs download - mcumgr fs upload - -Using the ``fs`` command, requires :kconfig:option:`CONFIG_FILE_SYSTEM` to be enabled, -and that some particular filesystem is enabled and properly mounted by the running -application, eg for littlefs this would mean enabling -:kconfig:option:`CONFIG_FILE_SYSTEM_LITTLEFS`, defining a storage partition :ref:`flash_map_api` -and mounting the filesystem in the startup (:c:func:`fs_mount`). - -Uploading a new file to a littlefs storage, mounted under ``/lfs``, can be done with:: - - $ mcumgr -c acm0 fs upload foo.txt /lfs/foo.txt - 25 - Done - -Where ``25`` is the size of the file. - -For downloading a file, let's first use the ``fs`` command -(:kconfig:option:`CONFIG_FILE_SYSTEM_SHELL` must be enabled) in a remote shell to create -a new file:: - - uart:~$ fs write /lfs/bar.txt 41 42 43 44 31 32 33 34 0a - uart:~$ fs read /lfs/bar.txt - File size: 9 - 00000000 41 42 43 44 31 32 33 34 0A ABCD1234. - -Now it can be downloaded using:: - - $ mcumgr -c acm0 fs download /lfs/bar.txt bar.txt - 0 - 9 - Done - $ cat bar.txt - ABCD1234 - -Where ``0`` is the return code, and ``9`` is the size of the file. - -.. warning:: - - The commands might exhaust the system workqueue, if its size is not large - enough, so increasing :kconfig:option:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` might be - required for correct behavior. - -The size of the stack allocated buffer used to store the blocks, while transferring -a file can be adjusted with :kconfig:option:`CONFIG_MCUMGR_GRP_FS_DL_CHUNK_SIZE`; this allows -saving RAM resources. - -.. tip:: - - :kconfig:option:`CONFIG_MCUMGR_GRP_FS_PATH_LEN` sets the maximum PATH accepted for a file - name. It might require tweaking for longer file names. - -.. note:: - To add security to the filesystem management group, callbacks for MCUmgr - hooks can be registered by a user application when the upload/download - functions are ran which allows the application to control if access to a - file is allowed or denied. See the :ref:`mcumgr_callbacks` section for - details. - Bootloader Integration ********************** diff --git a/doc/services/device_mgmt/mcumgr_callbacks.rst b/doc/services/device_mgmt/mcumgr_callbacks.rst index 7333f273f2b0b8..0ed8b580c757c0 100644 --- a/doc/services/device_mgmt/mcumgr_callbacks.rst +++ b/doc/services/device_mgmt/mcumgr_callbacks.rst @@ -192,7 +192,7 @@ the file should be allowed or not, note that this requires that :kconfig:option:`CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK` be enabled to receive this callback. Two types of errors can be returned, the ``rc`` parameter can be set to an -:c:enumerator:`mcumgr_err_t` error code and :c:enumerator:`MGMT_CB_ERROR_RC` +:c:enum:`mcumgr_err_t` error code and :c:enumerator:`MGMT_CB_ERROR_RC` can be returned, or a group error code (introduced with version 2 of the MCUmgr protocol) can be set by setting the ``group`` value to the group and ``rc`` value to the group error code and returning :c:enumerator:`MGMT_CB_ERROR_ERR`. @@ -330,4 +330,3 @@ API Reference ************* .. doxygengroup:: mcumgr_callback_api - :inner: diff --git a/doc/services/device_mgmt/mcumgr_handlers.rst b/doc/services/device_mgmt/mcumgr_handlers.rst index e189ea887d4735..18fc5e65366cba 100644 --- a/doc/services/device_mgmt/mcumgr_handlers.rst +++ b/doc/services/device_mgmt/mcumgr_handlers.rst @@ -52,8 +52,8 @@ responses (which have unique error codes per group as opposed to the legacy SMP responses that return a :c:enum:`mcumgr_err_t` - there should always be an OK error code with the value 0 and an unknown error code with the value 1. The above example then adds an error code of ``not wanted`` with value 2. In addition, the group ID is set to be -:c:enum:`MGMT_GROUP_ID_PERUSER`, which is the start group ID for user-defined groups, note that -group IDs need to be unique so other custom groups should use different values, a central index +:c:enumerator:`MGMT_GROUP_ID_PERUSER`, which is the start group ID for user-defined groups, note +that group IDs need to be unique so other custom groups should use different values, a central index header file (as upstream Zephyr has) can be used to distribute group IDs more easily. Initial header _mgmt_callbacks.h @@ -70,7 +70,7 @@ file would look similar to: This sets up a single event which application (or module) code can register for to receive a callback when the function handler is executed, which allows the flow of the handler to be changed (i.e. to return an error instead of continuing). The event group ID is set to -:c:enum:`MGMT_EVT_GRP_USER_CUSTOM_START`, which is the start event ID for user-defined groups, +:c:enumerator:`MGMT_EVT_GRP_USER_CUSTOM_START`, which is the start event ID for user-defined groups, note that event IDs need to be unique so other custom groups should use different values, a central index header file (as upstream Zephyr has) can be used to distribute event IDs more easily. diff --git a/doc/services/device_mgmt/smp_groups/smp_group_0.rst b/doc/services/device_mgmt/smp_groups/smp_group_0.rst index 7fb91463e336f6..eb3b90b3a1d7fe 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_0.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_0.rst @@ -563,7 +563,7 @@ System reset request header fields: +--------+--------------+----------------+ Normally the command sends an empty CBOR map as data, but if a previous reset -attempt has responded with "rc" equal to :c:enum:`MGMT_ERR_EBUSY` then the +attempt has responded with "rc" equal to :c:enumerator:`MGMT_ERR_EBUSY` then the following map may be sent to force a reset: .. code-block:: none diff --git a/doc/services/device_mgmt/smp_groups/smp_group_1.rst b/doc/services/device_mgmt/smp_groups/smp_group_1.rst index 2a1d1f2708632b..744835fad25b13 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_1.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_1.rst @@ -204,7 +204,7 @@ where: | | using SMP version 1 or for SMP errors when using SMP version 2. | +------------------+-------------------------------------------------------------------------+ | "rsn" | optional string that clarifies reason for an error; specifically useful | - | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + | | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`. | +------------------+-------------------------------------------------------------------------+ .. note:: @@ -407,7 +407,7 @@ where: | | using SMP version 1 or for SMP errors when using SMP version 2. | +------------------+-------------------------------------------------------------------------+ | "rsn" | optional string that clarifies reason for an error; specifically useful | - | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + | | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`. | +------------------+-------------------------------------------------------------------------+ The "off" field is only included in responses to successfully processed requests; @@ -509,10 +509,10 @@ where: | | using SMP version 1 or for SMP errors when using SMP version 2. | +------------------+-------------------------------------------------------------------------+ | "rsn" | optional string that clarifies reason for an error; specifically useful | - | | when ``rc`` is :c:enum:`MGMT_ERR_EUNKNOWN`. | + | | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`. | +------------------+-------------------------------------------------------------------------+ .. note:: Response from Zephyr running device may have "rc" value of - :c:enum:`MGMT_ERR_EBADSTATE`, which means that the secondary + :c:enumerator:`MGMT_ERR_EBADSTATE`, which means that the secondary image has been marked for next boot already and may not be erased. diff --git a/doc/services/device_mgmt/smp_groups/smp_group_3.rst b/doc/services/device_mgmt/smp_groups/smp_group_3.rst index 0636e72e3f6497..b5fd66d3d60334 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_3.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_3.rst @@ -542,5 +542,5 @@ There is a settings access MCUmgr callback available (see :ref:`mcumgr_callbacks callbacks) which allows for applications/modules to know when settings management commands are used and, optionally, block access (for example through the use of a security mechanism). This callback can be enabled with :kconfig:option:`CONFIG_MCUMGR_GRP_SETTINGS_ACCESS_HOOK`, registered -with the event :c:enum:`MGMT_EVT_OP_SETTINGS_MGMT_ACCESS`, whereby the supplied callback data is -:c:struct:`settings_mgmt_access`. +with the event :c:enumerator:`MGMT_EVT_OP_SETTINGS_MGMT_ACCESS`, whereby the supplied callback data +is :c:struct:`settings_mgmt_access`. diff --git a/doc/services/device_mgmt/smp_groups/smp_group_8.rst b/doc/services/device_mgmt/smp_groups/smp_group_8.rst index 502a5757169040..7a50ebf3d7c897 100644 --- a/doc/services/device_mgmt/smp_groups/smp_group_8.rst +++ b/doc/services/device_mgmt/smp_groups/smp_group_8.rst @@ -47,7 +47,7 @@ requests or even be removed. However, if the Kconfig option :kconfig:option:`CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK` is enabled, then an application can register a callback handler for - :c:enum:`MGMT_EVT_OP_FS_MGMT_FILE_ACCESS` (see + :c:enumerator:`MGMT_EVT_OP_FS_MGMT_FILE_ACCESS` (see :ref:`MCUmgr callbacks `), which allows for allowing or declining access to reading/writing a particular file, or for rewriting the path supplied by the client. @@ -185,7 +185,7 @@ change between requests or even be removed. However, if the Kconfig option :kconfig:option:`CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK` is enabled, then an application can register a callback handler for - :c:enum:`MGMT_EVT_OP_FS_MGMT_FILE_ACCESS` (see + :c:enumerator:`MGMT_EVT_OP_FS_MGMT_FILE_ACCESS` (see :ref:`MCUmgr callbacks `), which allows for allowing or declining access to reading/writing a particular file, or for rewriting the path supplied by the client. diff --git a/doc/services/logging/index.rst b/doc/services/logging/index.rst index 9e54f8d4da8d01..1193bc6ce7ab98 100644 --- a/doc/services/logging/index.rst +++ b/doc/services/logging/index.rst @@ -53,7 +53,7 @@ For each level the following set of macros are available: - ``LOG_INST_X`` for standard printf-like message associated with the particular instance, e.g. :c:macro:`LOG_INST_INF`. - ``LOG_INST_HEXDUMP_X`` for dumping data associated with the particular - instance, e.g. :c:macro:`LOG_HEXDUMP_INST_DBG` + instance, e.g. :c:macro:`LOG_INST_HEXDUMP_DBG` The warning level also exposes the following additional macro: diff --git a/doc/services/pm/device.rst b/doc/services/pm/device.rst index 055591c5f2c0b9..379ebfbef74fb9 100644 --- a/doc/services/pm/device.rst +++ b/doc/services/pm/device.rst @@ -72,16 +72,46 @@ For more information, see :ref:`pm-device-runtime`. System-Managed Device Power Management ====================================== +The system managed device power management (PM) framework is a method where +devices are suspended along with the system entering a CPU (or SoC) power state. +It can be enabled by setting :kconfig:option:`CONFIG_PM_DEVICE_SYSTEM_MANAGED`. When using this method, device power management is mostly done inside -:c:func:`pm_system_suspend()` along with entering a CPU or SOC power state. +:c:func:`pm_system_suspend()`. If a decision to enter a CPU lower power state is made, the power management -subsystem will suspend devices before changing state. The subsystem takes care -of suspending devices following their initialization order, ensuring that +subsystem will check if the selected low power state triggers device power +management and then suspend devices before changing state. The subsystem takes +care of suspending devices following their initialization order, ensuring that possible dependencies between them are satisfied. As soon as the CPU wakes up from a sleep state, devices are resumed in the opposite order that they were suspended. +The decision about suspending devices when entering a low power state is done based on the +state and if it has set the property ``zephyr,pm-device-disabled``. Here is +an example of a target with two low power states with only one triggering device power +management: + +.. code-block:: devicetree + + /* Node in a DTS file */ + cpus { + power-states { + state0: state0 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <5000>; + exit-latency-us = <240>; + zephyr,pm-device-disabled; + }; + state1: state1 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <8000>; + exit-latency-us = <360>; + }; + }; + }; + .. note:: When using :ref:`pm-system`, device transitions can be run from the idle thread. @@ -114,12 +144,6 @@ It is important to emphasize that this method has drawbacks (see above) and :kconfig:option:`CONFIG_PM_NEED_ALL_DEVICES_IDLE` is set and a device is marked as busy. -.. note:: - - This method of device power management is disabled when - :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE` is set to ``y`` (that is - the default value when :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME` is enabled) - .. note:: Devices are suspended only when the last active core is entering a low power @@ -283,6 +307,96 @@ the system will not do power management on it. After the device is no longer doing an operation and can be suspended, it should call :c:func:`pm_device_busy_clear`. +.. _pm-device-constraint: + +Device Power Management X System Power Management +************************************************* + +When managing power in embedded systems, it's crucial to understand +the interplay between device power state and the overall system power +state. Some devices may have dependencies on the system power +state. For example, certain low-power states of the SoC might not +supply power to peripheral devices, leading to problems if the device +is in the middle of an operation. Proper coordination is essential to +maintain system stability and data integrity. + +To avoid this sort of problem, devices must :ref:`get and release lock ` +power states that cause power loss during an operation. + +Zephyr provides a mechanism for devices to declare which power states cause power +loss and an API that automatically get and put lock on them. This feature is +enabled setting :kconfig:option:`CONFIG_PM_POLICY_DEVICE_CONSTRAINTS` to ``y``. + +Once this feature is enabled, devices must declare in devicetree which +states cause power loss. In the following example, device ``test_dev`` +says that power states ``state1`` and ``state2`` cause power loss. + +.. code-block:: devicetree + + power-states { + state0: state0 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <10000>; + exit-latency-us = <100>; + }; + + state1: state1 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <20000>; + exit-latency-us = <200>; + }; + + state2: state2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <50000>; + exit-latency-us = <500>; + }; + + state3: state3 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + status = "disabled"; + }; + }; + + test_dev: test_dev { + compatible = "test-device-pm"; + status = "okay"; + zephyr,disabling-power-states = <&state1 &state2>; + }; + +After that devices can lock these state calling +:c:func:`pm_policy_device_power_lock_get` and release with +:c:func:`pm_policy_device_power_lock_put`. For example: + +.. code-block:: C + + static void timer_expire_cb(struct k_timer *timer) + { + struct test_driver_data *data = k_timer_user_data_get(timer); + + data->ongoing = false; + k_timer_stop(timer); + pm_policy_device_power_lock_put(data->self); + } + + void test_driver_async_operation(const struct device *dev) + { + struct test_driver_data *data = dev->data; + + data->ongoing = true; + pm_policy_device_power_lock_get(dev); + + /** Lets set a timer big enough to ensure that any deep + * sleep state would be suitable but constraints will + * make only state0 (suspend-to-idle) will be used. + */ + k_timer_start(&data->timer, K_MSEC(500), K_NO_WAIT); + } + Wakeup capability ***************** diff --git a/doc/services/pm/power_domain.rst b/doc/services/pm/power_domain.rst index feab6998c6ee37..faa677b796a1b2 100644 --- a/doc/services/pm/power_domain.rst +++ b/doc/services/pm/power_domain.rst @@ -184,5 +184,5 @@ Examples Some helpful examples showing power domain features: -* :zephyr_file:`samples/subsys/pm/device_power_domains/` -* :zephyr_file:`samples/subsys/pm/power_domain/` +* :zephyr_file:`tests/subsys/pm/device_power_domains/` +* :zephyr_file:`tests/subsys/pm/power_domain/` diff --git a/doc/services/pm/system.rst b/doc/services/pm/system.rst index d6ec306a200132..49ba81e9357316 100644 --- a/doc/services/pm/system.rst +++ b/doc/services/pm/system.rst @@ -122,6 +122,8 @@ remaining time until the next scheduled timeout. An example of an application that defines its own policy can be found in :zephyr_file:`tests/subsys/pm/power_mgmt/`. +.. _pm-policy-power-states: + Policy and Power States ------------------------ diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index a8f214ef2aacb9..3896d052184ffd 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -42,7 +42,7 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :header: Symbol, Support, Remarks :widths: 50, 10, 50 - _POSIX_AEP_REALTIME_MINIMAL, -1, + _POSIX_AEP_REALTIME_MINIMAL, -1, :kconfig:option:`CONFIG_POSIX_AEP_REALTIME_MINIMAL` .. csv-table:: PSE51 Option Groups :header: Symbol, Support, Remarks @@ -50,11 +50,10 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`POSIX_C_LANG_JUMP `, yes, :ref:`POSIX_C_LANG_SUPPORT `, yes, - :ref:`POSIX_DEVICE_IO `,, - :ref:`POSIX_SIGNALS `,, - :ref:`POSIX_SINGLE_PROCESS `, yes, - :ref:`POSIX_THREADS_BASE `, yes, - :ref:`XSI_THREADS_EXT `, yes, + :ref:`POSIX_DEVICE_IO `,, :kconfig:option:`CONFIG_POSIX_DEVICE_IO` + :ref:`POSIX_SIGNALS `,, :kconfig:option:`CONFIG_POSIX_SIGNALS` + :ref:`POSIX_SINGLE_PROCESS `, yes, :kconfig:option:`CONFIG_POSIX_SINGLE_PROCESS` + :ref:`XSI_THREADS_EXT `, yes, :kconfig:option:`CONFIG_XSI_THREADS_EXT` .. csv-table:: PSE51 Option Requirements :header: Symbol, Support, Remarks @@ -63,15 +62,15 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`_POSIX_FSYNC `, 200809L, :kconfig:option:`CONFIG_POSIX_FSYNC` :ref:`_POSIX_MEMLOCK `, -1, :ref:`_POSIX_MEMLOCK_RANGE `, -1, - :ref:`_POSIX_MONOTONIC_CLOCK `, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` + :ref:`_POSIX_MONOTONIC_CLOCK `, 200809L, :kconfig:option:`CONFIG_POSIX_MONOTONIC_CLOCK` :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, -1, - :ref:`_POSIX_SYNCHRONIZED_IO `, -1, - :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_PTHREAD` - :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_PTHREAD` - :ref:`_POSIX_THREAD_CPUTIME `, -1, - _POSIX_THREAD_PRIO_INHERIT, 200809L, :kconfig:option:`CONFIG_PTHREAD_MUTEX` - _POSIX_THREAD_PRIO_PROTECT, -1, - :ref:`_POSIX_THREAD_PRIORITY_SCHEDULING`, 200809L, :kconfig:option:`CONFIG_POSIX_PRIORITY_SCHEDULING` + :ref:`_POSIX_SYNCHRONIZED_IO `, -1, :kconfig:option:`CONFIG_POSIX_SYNCHRONIZED_IO` + :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKADDR` + :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKSIZE` + :ref:`_POSIX_THREAD_CPUTIME `, 200809L, :kconfig:option:`CONFIG_POSIX_CPUTIME` + :ref:`_POSIX_THREAD_PRIO_INHERIT `, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_PRIO_INHERIT` + :ref:`_POSIX_THREAD_PRIO_PROTECT `, -1, :kconfig:option:`CONFIG_POSIX_THREAD_PRIO_PROTECT` + :ref:`_POSIX_THREAD_PRIORITY_SCHEDULING `, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_PRIORITY_SCHEDULING` _POSIX_THREAD_SPORADIC_SERVER, -1, .. _posix_aep_pse52: @@ -95,21 +94,21 @@ The *Realtime Controller System Profile* (PSE52) includes all features from PSE5 :header: Symbol, Support, Remarks :widths: 50, 10, 50 - _POSIX_AEP_REALTIME_CONTROLLER, -1, + _POSIX_AEP_REALTIME_CONTROLLER, -1, :kconfig:option:`CONFIG_POSIX_AEP_REALTIME_CONTROLLER` .. csv-table:: PSE52 Option Groups :header: Symbol, Support, Remarks :widths: 50, 10, 50 :ref:`POSIX_C_LANG_MATH `, yes, - :ref:`POSIX_FD_MGMT `,, - :ref:`POSIX_FILE_SYSTEM `,, + :ref:`POSIX_FD_MGMT `,, :kconfig:option:`CONFIG_POSIX_FD_MGMT` + :ref:`POSIX_FILE_SYSTEM `,, :kconfig:option:`CONFIG_POSIX_FILE_SYSTEM` .. csv-table:: PSE52 Option Requirements :header: Symbol, Support, Remarks :widths: 50, 10, 50 - :ref:`_POSIX_MESSAGE_PASSING `, 200809L, :kconfig:option:`CONFIG_POSIX_MQUEUE` + :ref:`_POSIX_MESSAGE_PASSING `, 200809L, :kconfig:option:`CONFIG_POSIX_MESSAGE_PASSING` _POSIX_TRACE, -1, _POSIX_TRACE_EVENT_FILTER, -1, _POSIX_TRACE_LOG, -1, @@ -135,14 +134,14 @@ The *Dedicated Realtime System Profile* (PSE53) includes all features from PSE52 :header: Symbol, Support, Remarks :widths: 50, 10, 50 - _POSIX_AEP_REALTIME_DEDICATED, -1, + _POSIX_AEP_REALTIME_DEDICATED, -1, :kconfig:option:`CONFIG_POSIX_AEP_REALTIME_DEDICATED` .. csv-table:: PSE53 Option Groups :header: Symbol, Support, Remarks :widths: 50, 10, 50 - POSIX_MULTI_PROCESS,, :ref:`†` - :ref:`POSIX_NETWORKING `, yes, + :ref:`POSIX_MULTI_PROCESS`,, :kconfig:option:`CONFIG_POSIX_MULTI_PROCESS`:ref:`†` + :ref:`POSIX_NETWORKING `, yes, :kconfig:option:`CONFIG_POSIX_NETWORKING` :ref:`POSIX_PIPE `,, :ref:`POSIX_SIGNAL_JUMP `,, @@ -150,10 +149,10 @@ The *Dedicated Realtime System Profile* (PSE53) includes all features from PSE52 :header: Symbol, Support, Remarks :widths: 50, 10, 50 - _POSIX_CPUTIME, -1, + :ref:`_POSIX_CPUTIME `, 200809L, :kconfig:option:`CONFIG_POSIX_CPUTIME` _POSIX_PRIORITIZED_IO, -1, :ref:`_POSIX_PRIORITY_SCHEDULING `, -1, - _POSIX_RAW_SOCKETS, 200809L, :kconfig:option:`CONFIG_NET_SOCKETS_PACKET` + :ref:`_POSIX_RAW_SOCKETS `, 200809L, :kconfig:option:`CONFIG_POSIX_RAW_SOCKETS` _POSIX_SPAWN, -1, :ref:`†` _POSIX_SPORADIC_SERVER, -1, :ref:`†` diff --git a/doc/services/portability/posix/conformance/index.rst b/doc/services/portability/posix/conformance/index.rst index 69e77eed89c358..302bf4f6e71f38 100644 --- a/doc/services/portability/posix/conformance/index.rst +++ b/doc/services/portability/posix/conformance/index.rst @@ -5,22 +5,6 @@ POSIX Conformance As per `IEEE 1003.1-2017`, this section details Zephyr's POSIX conformance. -.. _posix_undefined_behaviour: - -.. note:: - As per POSIX 1003.13, single process mode is supported directly by both PSE51 and PSE52 - profiles. While Zephyr includes support for many features found in PSE53, PSE53 itself requires - supporting multiple processes. Since supporting multiple processes is beyond the scope of - Zephyr's current design, some features requiring multi-process capabilities may exhibit - undefined behaviour, which we denote with the † (obelus) symbol. - -.. _posix_libc_provided: - -.. note:: - Features listed in various POSIX Options or Option Groups may be provided in whole or in part - by a conformant C library implementation. This includes (but is not limited to) POSIX - Extensions to the ISO C Standard (`CX`_). - .. _posix_system_interfaces: POSIX System Interfaces @@ -34,19 +18,7 @@ POSIX System Interfaces _POSIX_CHOWN_RESTRICTED, 0, _POSIX_NO_TRUNC, 0, - _POSIX_VDISABLE, 0, - -.. The following should be valued greater than zero in Zephyr, in order to be strictly conformant - with the POSIX specification. - -.. csv-table:: POSIX System Interfaces - :header: Symbol, Support, Remarks - :widths: 50, 10, 50 - - _POSIX_JOB_CONTROL, -1, :ref:`†` - _POSIX_REGEXP, -1, :ref:`†` - _POSIX_SAVED_IDS, -1, :ref:`†` - _POSIX_SHELL, -1, :ref:`†` + _POSIX_VDISABLE, ``'\0'``, .. TODO: POSIX_ASYNCHRONOUS_IO, and other interfaces below, are mandatory. That means that a strictly conforming application need not be modified in order to compile against Zephyr. @@ -61,46 +33,58 @@ POSIX System Interfaces :widths: 50, 10, 50 _POSIX_VERSION, 200809L, - :ref:`_POSIX_ASYNCHRONOUS_IO`, 200809L, :ref:`†` - :ref:`_POSIX_BARRIERS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_BARRIER` - :ref:`_POSIX_CLOCK_SELECTION`, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` + :ref:`_POSIX_ASYNCHRONOUS_IO`, 200809L, :kconfig:option:`CONFIG_POSIX_ASYNCHRONOUS_IO`:ref:`†` + :ref:`_POSIX_BARRIERS`, 200809L, :kconfig:option:`CONFIG_POSIX_BARRIERS` + :ref:`_POSIX_CLOCK_SELECTION`, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK_SELECTION` _POSIX_MAPPED_FILES, -1, :ref:`†` _POSIX_MEMORY_PROTECTION, -1, :ref:`†` - :ref:`_POSIX_READER_WRITER_LOCKS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_IPC` - :ref:`_POSIX_REALTIME_SIGNALS`, -1, - :ref:`_POSIX_SEMAPHORES`, 200809L, :kconfig:option:`CONFIG_PTHREAD_IPC` - :ref:`_POSIX_SPIN_LOCKS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_SPINLOCK` - :ref:`_POSIX_THREAD_SAFE_FUNCTIONS`, -1, - :ref:`_POSIX_THREADS`, -1, :kconfig:option:`CONFIG_PTHREAD_IPC` - :ref:`_POSIX_TIMEOUTS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_IPC` - :ref:`_POSIX_TIMERS`, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` + :ref:`_POSIX_READER_WRITER_LOCKS`, 200809L, :kconfig:option:`CONFIG_POSIX_READER_WRITER_LOCKS` + :ref:`_POSIX_REALTIME_SIGNALS`, -1, :kconfig:option:`CONFIG_POSIX_REALTIME_SIGNALS` + :ref:`_POSIX_SEMAPHORES`, 200809L, :kconfig:option:`CONFIG_POSIX_SEMAPHORES` + :ref:`_POSIX_SPIN_LOCKS`, 200809L, :kconfig:option:`CONFIG_POSIX_SPIN_LOCKS` + :ref:`_POSIX_THREAD_SAFE_FUNCTIONS`, -1, :kconfig:option:`CONFIG_POSIX_THREAD_SAFE_FUNCTIONS` + :ref:`_POSIX_THREADS`, -1, :kconfig:option:`CONFIG_POSIX_THREADS` + :ref:`_POSIX_TIMEOUTS`, 200809L, :kconfig:option:`CONFIG_POSIX_TIMEOUTS` + :ref:`_POSIX_TIMERS`, 200809L, :kconfig:option:`CONFIG_POSIX_TIMERS` _POSIX2_C_BIND, 200809L, +.. The following should be valued greater than zero in Zephyr, in order to be strictly conformant + with the POSIX specification. + +.. csv-table:: POSIX System Interfaces (Unsupported) + :header: Symbol, Support, Remarks + :widths: 50, 10, 50 + + _POSIX_JOB_CONTROL, -1, :ref:`†` + _POSIX_REGEXP, -1, :ref:`†` + _POSIX_SAVED_IDS, -1, :ref:`†` + _POSIX_SHELL, -1, :ref:`†` + .. csv-table:: POSIX System Interfaces (Optional) :header: Symbol, Support, Remarks :widths: 50, 10, 50 _POSIX_ADVISORY_INFO, -1, - _POSIX_CPUTIME, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` + :ref:`_POSIX_CPUTIME`, 200809L, :kconfig:option:`CONFIG_POSIX_CPUTIME` :ref:`_POSIX_FSYNC`, 200809L, :kconfig:option:`CONFIG_POSIX_FSYNC` - _POSIX_IPV6, 200809L, :kconfig:option:`CONFIG_NET_IPV6` - _POSIX_MEMLOCK, -1, - _POSIX_MEMLOCK_RANGE, -1, - :ref:`_POSIX_MESSAGE_PASSING`, 200809L, :kconfig:option:`CONFIG_POSIX_MQUEUE` - :ref:`_POSIX_MONOTONIC_CLOCK`, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` + :ref:`_POSIX_IPV6`, 200809L, :kconfig:option:`CONFIG_POSIX_IPV6` + :ref:`_POSIX_MEMLOCK `, -1, + :ref:`_POSIX_MEMLOCK_RANGE `, -1, + :ref:`_POSIX_MESSAGE_PASSING`, 200809L, :kconfig:option:`CONFIG_POSIX_MESSAGE_PASSING` + :ref:`_POSIX_MONOTONIC_CLOCK`, 200809L, :kconfig:option:`CONFIG_POSIX_MONOTONIC_CLOCK` _POSIX_PRIORITIZED_IO, -1, :ref:`_POSIX_PRIORITY_SCHEDULING`, 200809L, :kconfig:option:`CONFIG_POSIX_PRIORITY_SCHEDULING` - _POSIX_RAW_SOCKETS, 200809L, :kconfig:option:`CONFIG_NET_SOCKETS_PACKET` - _POSIX_SHARED_MEMORY_OBJECTS, -1, + :ref:`_POSIX_RAW_SOCKETS`, 200809L, :kconfig:option:`CONFIG_POSIX_RAW_SOCKETS` + :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, -1, _POSIX_SPAWN, -1, :ref:`†` _POSIX_SPORADIC_SERVER, -1, :ref:`†` - _POSIX_SYNCHRONIZED_IO, -1, - :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_PTHREAD` - :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_PTHREAD` - _POSIX_THREAD_CPUTIME, -1, - _POSIX_THREAD_PRIO_INHERIT, 200809L, :kconfig:option:`CONFIG_PTHREAD_MUTEX` - _POSIX_THREAD_PRIO_PROTECT, -1, - :ref:`_POSIX_THREAD_PRIORITY_SCHEDULING`, 200809L, :kconfig:option:`CONFIG_PTHREAD` + :ref:`_POSIX_SYNCHRONIZED_IO `, -1, :kconfig:option:`CONFIG_POSIX_SYNCHRONIZED_IO` + :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKADDR` + :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKSIZE` + :ref:`_POSIX_THREAD_CPUTIME `, 200809L, :kconfig:option:`CONFIG_POSIX_CPUTIME` + :ref:`_POSIX_THREAD_PRIO_INHERIT `, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_PRIO_INHERIT` + :ref:`_POSIX_THREAD_PRIO_PROTECT `, -1, :kconfig:option:`CONFIG_POSIX_THREAD_PRIO_PROTECT` + :ref:`_POSIX_THREAD_PRIORITY_SCHEDULING `, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_PRIORITY_SCHEDULING` _POSIX_THREAD_PROCESS_SHARED, -1, _POSIX_THREAD_SPORADIC_SERVER, -1, _POSIX_TRACE, -1, @@ -111,9 +95,10 @@ POSIX System Interfaces _XOPEN_CRYPT, -1, _XOPEN_REALTIME, -1, _XOPEN_REALTIME_THREADS, -1, - :ref:`_XOPEN_STREAMS`, -1, :ref:`†` + :ref:`_XOPEN_STREAMS`, 200809L, :kconfig:option:`CONFIG_XOPEN_STREAMS` _XOPEN_UNIX, -1, + POSIX Shell and Utilities ========================= @@ -141,16 +126,32 @@ Zephyr does not support a POSIX shell or utilities at this time. XSI Conformance ############### -XSI System Interfaces -===================== +X/Open System Interfaces +======================== -.. csv-table:: XSI System Interfaces +.. csv-table:: X/Open System Interfaces :header: Symbol, Support, Remarks :widths: 50, 10, 50 :ref:`_POSIX_FSYNC`, 200809L, :kconfig:option:`CONFIG_POSIX_FSYNC` - :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_PTHREAD` - :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_PTHREAD` + :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKADDR` + :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKSIZE` _POSIX_THREAD_PROCESS_SHARED, -1, +.. _posix_undefined_behaviour: + +.. note:: + Some features may exhibit undefined behaviour as they fall beyond the scope of Zephyr's current + design and capabilities. For example, multi-processing, ad-hoc memory-mapping, multiple users, + or regular expressions are features that are uncommon in low-footprint embedded systems. + Such undefined behaviour is denoted with the † (obelus) symbol. Additional details + :ref:`here `. + +.. _posix_libc_provided: + +.. note:: + Features listed in various POSIX Options or Option Groups may be provided in whole or in part + by a conformant C library implementation. This includes (but is not limited to) POSIX + Extensions to the ISO C Standard (`CX`_). + .. _CX: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap01.html diff --git a/doc/services/portability/posix/kconfig/index.rst b/doc/services/portability/posix/kconfig/index.rst index 059c0c1affe50b..7c7055326df2cb 100644 --- a/doc/services/portability/posix/kconfig/index.rst +++ b/doc/services/portability/posix/kconfig/index.rst @@ -1,50 +1,40 @@ .. _posix_kconfig_options: -Configuration Options -********************* +Additional Configuration Options +******************************** -This is a non-exhaustive list of specific :ref:`kconfig` options relating to Zephyr's +Below is a non-exhaustive list of additional :ref:`kconfig` options relating to Zephyr's implementation of the POSIX API. +* :kconfig:option:`CONFIG_DYNAMIC_THREAD` +* :kconfig:option:`CONFIG_DYNAMIC_THREAD_POOL_SIZE` * :kconfig:option:`CONFIG_EVENTFD` -* :kconfig:option:`CONFIG_EVENTFD_MAX` * :kconfig:option:`CONFIG_FDTABLE` -* :kconfig:option:`CONFIG_FNMATCH` -* :kconfig:option:`CONFIG_GETOPT` * :kconfig:option:`CONFIG_GETOPT_LONG` -* :kconfig:option:`CONFIG_MAX_PTHREAD_BARRIER_COUNT` -* :kconfig:option:`CONFIG_MAX_PTHREAD_COUNT` -* :kconfig:option:`CONFIG_MAX_PTHREAD_KEY_COUNT` -* :kconfig:option:`CONFIG_MAX_PTHREAD_MUTEX_COUNT` * :kconfig:option:`CONFIG_MAX_PTHREAD_SPINLOCK_COUNT` -* :kconfig:option:`CONFIG_MAX_TIMER_COUNT` * :kconfig:option:`CONFIG_MQUEUE_NAMELEN_MAX` -* :kconfig:option:`CONFIG_MSG_COUNT_MAX` +* :kconfig:option:`CONFIG_POSIX_MQ_OPEN_MAX` * :kconfig:option:`CONFIG_MSG_SIZE_MAX` * :kconfig:option:`CONFIG_NET_SOCKETPAIR` * :kconfig:option:`CONFIG_NET_SOCKETS` * :kconfig:option:`CONFIG_NET_SOCKETS_POLL_MAX` +* :kconfig:option:`CONFIG_ZVFS_OPEN_MAX` * :kconfig:option:`CONFIG_POSIX_API` -* :kconfig:option:`CONFIG_POSIX_CLOCK` -* :kconfig:option:`CONFIG_POSIX_FS` -* :kconfig:option:`CONFIG_POSIX_LIMITS_RTSIG_MAX` -* :kconfig:option:`CONFIG_POSIX_MAX_FDS` -* :kconfig:option:`CONFIG_POSIX_MAX_OPEN_FILES` -* :kconfig:option:`CONFIG_POSIX_MQUEUE` +* :kconfig:option:`CONFIG_POSIX_OPEN_MAX` +* :kconfig:option:`CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS` +* :kconfig:option:`CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_DEFAULT` +* :kconfig:option:`CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS` * :kconfig:option:`CONFIG_POSIX_RTSIG_MAX` -* :kconfig:option:`CONFIG_POSIX_SIGNAL` * :kconfig:option:`CONFIG_POSIX_SIGNAL_STRING_DESC` -* :kconfig:option:`CONFIG_POSIX_UNAME` +* :kconfig:option:`CONFIG_POSIX_THREAD_KEYS_MAX` +* :kconfig:option:`CONFIG_POSIX_THREAD_THREADS_MAX` * :kconfig:option:`CONFIG_POSIX_UNAME_NODENAME_LEN` * :kconfig:option:`CONFIG_POSIX_UNAME_VERSION_LEN` -* :kconfig:option:`CONFIG_PTHREAD` -* :kconfig:option:`CONFIG_PTHREAD_BARRIER` -* :kconfig:option:`CONFIG_PTHREAD_COND` * :kconfig:option:`CONFIG_PTHREAD_CREATE_BARRIER` -* :kconfig:option:`CONFIG_PTHREAD_IPC` -* :kconfig:option:`CONFIG_PTHREAD_KEY` -* :kconfig:option:`CONFIG_PTHREAD_MUTEX` * :kconfig:option:`CONFIG_PTHREAD_RECYCLER_DELAY_MS` -* :kconfig:option:`CONFIG_PTHREAD_SPINLOCK` -* :kconfig:option:`CONFIG_SEM_VALUE_MAX` -* :kconfig:option:`CONFIG_TIMER` +* :kconfig:option:`CONFIG_POSIX_SEM_NAMELEN_MAX` +* :kconfig:option:`CONFIG_POSIX_SEM_NSEMS_MAX` +* :kconfig:option:`CONFIG_POSIX_SEM_VALUE_MAX` +* :kconfig:option:`CONFIG_TIMER_CREATE_WAIT` +* :kconfig:option:`CONFIG_THREAD_STACK_INFO` +* :kconfig:option:`CONFIG_ZVFS_EVENTFD_MAX` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index e284af76d02547..980732c4612b3c 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -102,6 +102,20 @@ This table lists service support status in Zephyr: pthread_getconcurrency(),yes pthread_setconcurrency(),yes +.. _posix_option_group_xsi_system_logging: + +XSI_SYSTEM_LOGGING +================== + +.. csv-table:: XSI_SYSTEM_LOGGING + :header: API, Supported + :widths: 50,10 + + closelog(),yes + openlog(),yes + setlogmask(),yes + syslog(),yes + .. _posix_option_group_c_lang_jump: POSIX_C_LANG_JUMP @@ -151,6 +165,31 @@ Group. For more information on developing Zephyr applications in the C programming language, please refer to :ref:`details`. +.. _posix_option_group_c_lib_ext: + +POSIX_C_LIB_EXT +=============== + +.. csv-table:: POSIX_C_LIB_EXT + :header: API, Supported + :widths: 50,10 + + fnmatch(), yes + getopt(), yes + getsubopt(), + optarg, yes + opterr, yes + optind, yes + optopt, yes + stpcpy(), + stpncpy(), + strcasecmp(), + strdup(), + strfmon(), + strncasecmp(), yes + strndup(), + strnlen(), yes + .. _posix_option_group_realtime_signals: POSIX_REALTIME_SIGNALS @@ -520,6 +559,40 @@ This table lists service support status in Zephyr for `POSIX_FD_MGMT`: putc_unlocked(), putchar_unlocked(), +.. _posix_option_group_multi_process: + +POSIX_MULTI_PROCESS +=================== + +.. csv-table:: POSIX_MULTI_PROCESS + :header: API, Supported + :widths: 50,10 + + _Exit(), yes + _exit(), yes + assert(), yes + atexit(),:ref:`†` + clock(), + execl(),:ref:`†` + execle(),:ref:`†` + execlp(),:ref:`†` + execv(),:ref:`†` + execve(),:ref:`†` + execvp(),:ref:`†` + exit(), yes + fork(),:ref:`†` + getpgrp(),:ref:`†` + getpgid(),:ref:`†` + getpid(), yes :ref:`†` + getppid(),:ref:`†` + getsid(),:ref:`†` + setsid(),:ref:`†` + sleep(),yes + times(), + wait(),:ref:`†` + waitid(),:ref:`†` + waitpid(),:ref:`†` + .. _posix_options: Additional POSIX Options @@ -543,6 +616,17 @@ _POSIX_ASYNCHRONOUS_IO aio_write(),yes (will fail with ``ENOSYS``:ref:`†`) lio_listio(),yes (will fail with ``ENOSYS``:ref:`†`) +.. _posix_option_cputime: + +_POSIX_CPUTIME +++++++++++++++ + +.. csv-table:: _POSIX_CPUTIME + :header: API, Supported + :widths: 50,10 + + CLOCK_PROCESS_CPUTIME_ID,yes + .. _posix_option_fsync: _POSIX_FSYNC @@ -554,6 +638,15 @@ _POSIX_FSYNC fsync(),yes +.. _posix_option_ipv6: + +_POSIX_IPV6 ++++++++++++ + +Internet Protocol Version 6 is supported. + +For more information, please refer to :ref:`Networking `. + .. _posix_option_memlock: _POSIX_MEMLOCK @@ -625,6 +718,15 @@ _POSIX_PRIORITY_SCHEDULING sched_setscheduler(),yes (will fail with ``ENOSYS``:ref:`†`) sched_yield(),yes +.. _posix_option_raw_sockets: + +_POSIX_RAW_SOCKETS +++++++++++++++++++ + +Raw sockets are supported. + +For more information, please refer to :kconfig:option:`CONFIG_NET_SOCKETS_PACKET`. + .. _posix_option_reader_writer_locks: _POSIX_READER_WRITER_LOCKS @@ -728,6 +830,34 @@ _POSIX_THREAD_PRIORITY_SCHEDULING pthread_setschedparam(),yes pthread_setschedprio(),yes +.. _posix_option_thread_prio_inherit: + +_POSIX_THREAD_PRIO_INHERIT +++++++++++++++++++++++++++ + +.. csv-table:: _POSIX_THREAD_PRIO_INHERIT + :header: API, Supported + :widths: 50,10 + + pthread_mutexattr_getprotocol(),yes + pthread_mutexattr_setprotocol(),yes + +.. _posix_option_thread_prio_protect: + +_POSIX_THREAD_PRIO_PROTECT +++++++++++++++++++++++++++ + +.. csv-table:: _POSIX_THREAD_PRIO_PROTECT + :header: API, Supported + :widths: 50,10 + + pthread_mutex_getprioceiling(), + pthread_mutex_setprioceiling(), + pthread_mutexattr_getprioceiling(), + pthread_mutexattr_getprotocol(),yes + pthread_mutexattr_setprioceiling(), + pthread_mutexattr_setprotocol(),yes + .. _posix_thread_safe_functions: _POSIX_THREAD_SAFE_FUNCTIONS @@ -779,18 +909,23 @@ _POSIX_TIMEOUTS _XOPEN_STREAMS ++++++++++++++ +With the exception of ``ioctl()``, functions in the ``_XOPEN_STREAMS`` option group are not +implemented in Zephyr but are provided so that conformant applications can still link. +Unimplemented functions in this option group will fail, setting ``errno`` to ``ENOSYS`` +:ref:`†`. + .. csv-table:: _XOPEN_STREAMS :header: API, Supported :widths: 50,10 - fattach(),yes (will fail with ``ENOSYS``:ref:`†`) - fdetach(),yes (will fail with ``ENOSYS``:ref:`†`) - getmsg(), yes (will fail with ``ENOSYS``:ref:`†`) - getpmsg(), yes (will fail with ``ENOSYS``:ref:`†`) - ioctl(),yes - isastream(),yes (will fail with ``ENOSYS``:ref:`†`) - putmsg(), yes (will fail with ``ENOSYS``:ref:`†`) - putpmsg(), + fattach(), yes :ref:`†` + fdetach(), yes :ref:`†` + getmsg(), yes :ref:`†` + getpmsg(), yes :ref:`†` + ioctl(), yes + isastream(), yes :ref:`†` + putmsg(), yes :ref:`†` + putpmsg(), yes :ref:`†` .. _Subprofiling Considerations: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/doc/services/portability/posix/overview/index.rst b/doc/services/portability/posix/overview/index.rst index cd00b68b1a7213..6c352cf245433f 100644 --- a/doc/services/portability/posix/overview/index.rst +++ b/doc/services/portability/posix/overview/index.rst @@ -122,23 +122,43 @@ Configuration Like most features in Zephyr, POSIX features are :ref:`highly configurable` but disabled by default. Users must -explicitly choose to enable POSIX options via :ref:`Kconfig` selection. Indeed, there are -:ref:`many Kconfig options in Zephyr` for the POSIX API to allow for -feature selection at various levels of granularity. +explicitly choose to enable POSIX options via :ref:`Kconfig` selection. -Alternatively, users may enable one of the Kconfig options below as a shortcut to enable multiple -:ref:`Option Groups`. +Subprofiles ++++++++++++ + +Enable one of the Kconfig options below to quickly configure a pre-defined +:ref:`POSIX subprofile `. + +* :kconfig:option:`CONFIG_POSIX_AEP_CHOICE_BASE` (:ref:`Base `) +* :kconfig:option:`CONFIG_POSIX_AEP_CHOICE_PSE51` (:ref:`PSE51 `) +* :kconfig:option:`CONFIG_POSIX_AEP_CHOICE_PSE52` (:ref:`PSE52 `) +* :kconfig:option:`CONFIG_POSIX_AEP_CHOICE_PSE53` (:ref:`PSE53 `) + +Additional POSIX :ref:`Options and Option Groups ` may be enabled as needed +via Kconfig (e.g. ``CONFIG_POSIX_C_LIB_EXT=y``). Further fine-tuning may be accomplished via +:ref:`additional POSIX-related Kconfig options `. + +Subprofiles, Options, and Option Groups should be considered the preferred way to configure POSIX +in Zephyr going forward. + +Legacy +++++++ + +Historically, Zephyr used :kconfig:option:`CONFIG_POSIX_API` to configure a set of POSIX features +that was overloaded and always increasing in size. * :kconfig:option:`CONFIG_POSIX_API` -* :kconfig:option:`CONFIG_PTHREAD_IPC` -.. note:: - Since the POSIX environment in Zephyr is fully configurable via :ref:`Kconfig`, - configurations that require modifying features should not be made if strict compliance is - required (POSIX-1.2017, section 2.1.3.1). +The option is now frozen, and can be considered equivalent to the following: + +* :kconfig:option:`CONFIG_POSIX_AEP_CHOICE_PSE51` +* :kconfig:option:`CONFIG_POSIX_FD_MGMT` +* :kconfig:option:`CONFIG_POSIX_MESSAGE_PASSING` +* :kconfig:option:`CONFIG_POSIX_NETWORKING` -.. - TODO: create Kconfig shortcuts for PSE51, PSE52, and PSE53 +However, :kconfig:option:`CONFIG_POSIX_API` should be considered legacy and should not be used for +new Zephyr applications. .. _IEEE: https://www.ieee.org/ .. _IEEE Computer Society: https://www.computer.org/ diff --git a/doc/services/rtio/index.rst b/doc/services/rtio/index.rst index df6e75d7702c88..cb33a3ffbeb6a3 100644 --- a/doc/services/rtio/index.rst +++ b/doc/services/rtio/index.rst @@ -216,13 +216,3 @@ API Reference ************* .. doxygengroup:: rtio - -MPSC Lock-free Queue API -======================== - -.. doxygengroup:: rtio_mpsc - -SPSC Lock-free Queue API -======================== - -.. doxygengroup:: rtio_spsc diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 504bef139fe019..582ddcd2f9ce79 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -556,7 +556,7 @@ is accomplished by the ``getopt`` family functions. For this purpose shell supports the getopt and getopt_long libraries available in the FreeBSD project. This feature is activated by: -:kconfig:option:`CONFIG_GETOPT` set to ``y`` and :kconfig:option:`CONFIG_GETOPT_LONG` +:kconfig:option:`CONFIG_POSIX_C_LIB_EXT` set to ``y`` and :kconfig:option:`CONFIG_GETOPT_LONG` set to ``y``. This feature can be used in thread safe as well as non thread safe manner. diff --git a/doc/services/storage/disk/access.rst b/doc/services/storage/disk/access.rst index db06e87e5c07e7..7cc5fe12f5419d 100644 --- a/doc/services/storage/disk/access.rst +++ b/doc/services/storage/disk/access.rst @@ -8,6 +8,35 @@ Overview The disk access API provides access to storage devices. +Initializing Disks +****************** + +Since many disk devices (such as SD cards) are hotpluggable, the disk access +API provides IOCTLs to initialize and de-initialize the disk. They are +as follows: + +* :c:macro:`DISK_IOCTL_CTRL_INIT`: Initialize the disk. Must be called before + additional I/O operations can be run on the disk device. Equivalent to + calling the legacy function :c:func:`disk_access_init`. + +* :c:macro:`DISK_IOCTL_CTRL_DEINIT`: De-initialize the disk. Once this IOCTL + is issued, the :c:macro:`DISK_IOCTL_CTRL_INIT` must be issued before + the disk can be used for addition I/O operations. + +Init/deinit IOCTL calls are balanced, so a disk will not de-initialize until +an equal number of deinit IOCTLs have been issued as init IOCTLs. + +It is also possible to force a disk de-initialization by passing a +pointer to a boolean set to ``true`` as a parameter to the +:c:macro:`DISK_IOCTL_CTRL_DEINIT` IOCTL. This is an unsafe operation which +each disk driver may handle differently, but it will always return +a value indicating success. + +Note that de-initializing a disk is a low level operation- typically the +de-initialization and initialization calls should be left to the filesystem +implementation, and the user application should not need to manually +de-initialize the disk and can instead call :c:func:`fs_unmount` + SD Card support *************** @@ -16,12 +45,9 @@ SD cards via SPI. These drivers use disk driver interface and a file system can access the SD cards via disk access API. Both standard and high-capacity SD cards are supported. -.. note:: The system does not support inserting or removing cards while the - system is running. The cards must be present at boot and must not be - removed. This may be fixed in future releases. - - FAT filesystems are not power safe so the filesystem may become - corrupted if power is lost or if the card is removed. +.. note:: FAT filesystems are not power safe so the filesystem may become + corrupted if power is lost or if the card is removed without unmounting + the filesystem SD Memory Card subsystem ======================== diff --git a/doc/services/storage/nvs/nvs.rst b/doc/services/storage/nvs/nvs.rst index 8278e49bf7128d..c41f6ad83edd19 100644 --- a/doc/services/storage/nvs/nvs.rst +++ b/doc/services/storage/nvs/nvs.rst @@ -19,11 +19,16 @@ combination of these. Each element is stored in flash as metadata (8 byte) and data. The metadata is written in a table starting from the end of a nvs sector, the data is written one after the other from the start of the sector. The metadata consists -of: id, data offset in sector, data length, part (unused), and a CRC. The CRC is +of: id, data offset in sector, data length, part (unused), and a CRC. This CRC is only calculated over the metadata and only ensures that a write has been -completed. The actual data of the element is not protected by a CRC. It is -encouraged to include a CRC as part of the data and to take appropriate -corrective actions when the data CRC does not match its expected value. +completed. The actual data of the element can be protected by a different (and optional) +CRC-32. Use the :kconfig:option:`CONFIG_NVS_DATA_CRC` configuration item to enable +the data part CRC. +**Note:** the data CRC is checked only when the whole data of the element is read. +The data CRC is not checked for a partial read, as it is stored at the end of the +element data area. +**Note 2:** enabling the data CRC feature on a previously existing NVS content without +data CRC will make all existing data invalid. A write of data to nvs always starts with writing the data, followed by a write of the metadata. Data that is written in flash without metadata is ignored diff --git a/drivers/adc/Kconfig.esp32 b/drivers/adc/Kconfig.esp32 index 8fc8c9cabce079..604d0ad49edbe9 100644 --- a/drivers/adc/Kconfig.esp32 +++ b/drivers/adc/Kconfig.esp32 @@ -8,3 +8,15 @@ config ADC_ESP32 depends on DT_HAS_ESPRESSIF_ESP32_ADC_ENABLED help Enable the driver implementation for the ESP32 ADC + +if ADC_ESP32 + +config ADC_ESP32_DMA + bool "ESP32 ADC DMA Support" + default n + depends on DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED + help + Enable the ADC DMA mode for ADC instances + that enable dma channels in their device tree node. + +endif diff --git a/drivers/adc/adc_ad559x.c b/drivers/adc/adc_ad559x.c index 21ee1e62e18dee..b0e7bb95810870 100644 --- a/drivers/adc/adc_ad559x.c +++ b/drivers/adc/adc_ad559x.c @@ -130,9 +130,6 @@ static int adc_ad559x_read_channel(const struct device *dev, uint8_t channel, ui if (ret < 0) { return ret; } - - *result = sys_get_be16((uint8_t *)&val); - } else { /* * Invalid data: @@ -145,31 +142,31 @@ static int adc_ad559x_read_channel(const struct device *dev, uint8_t channel, ui if (ret < 0) { return ret; } + } - val = sys_be16_to_cpu(val); + val = sys_be16_to_cpu(val); - /* - * Invalid data: - * See "ADC section" in "Theory of operation" chapter. - * Valid ADC result has MSB bit set to 0. - */ - if ((val & AD559X_ADC_RES_IND_BIT) != 0) { - return -EAGAIN; - } - - /* - * Invalid channel converted: - * See "ADC section" in "Theory of operation" chapter. - * Conversion result contains channel number which should match requested channel. - */ - conv_channel = FIELD_GET(AD559X_ADC_RES_CHAN_MASK, val); - if (conv_channel != channel) { - return -EIO; - } + /* + * Invalid data: + * See AD5592 "ADC section" in "Theory of operation" chapter. + * Valid ADC result has MSB bit set to 0. + */ + if ((val & AD559X_ADC_RES_IND_BIT) != 0) { + return -EAGAIN; + } - *result = val & AD559X_ADC_RES_VAL_MASK; + /* + * Invalid channel converted: + * See AD5592 "ADC section" in "Theory of operation" chapter. + * Conversion result contains channel number which should match requested channel. + */ + conv_channel = FIELD_GET(AD559X_ADC_RES_CHAN_MASK, val); + if (conv_channel != channel) { + return -EIO; } + *result = val & AD559X_ADC_RES_VAL_MASK; + return 0; } diff --git a/drivers/adc/adc_esp32.c b/drivers/adc/adc_esp32.c index 9b47fdf6bd723c..4e45a3ea22e54b 100644 --- a/drivers/adc/adc_esp32.c +++ b/drivers/adc/adc_esp32.c @@ -9,12 +9,25 @@ #include #include #include +#include #include +#include #include +#include +#include + +#if defined(CONFIG_ADC_ESP32_DMA) +#if !SOC_GDMA_SUPPORTED +#error "SoCs without GDMA peripheral are not supported!" +#endif +#include +#include +#endif #include #include #include +#include #include LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL); @@ -43,9 +56,16 @@ LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL); /* Default internal reference voltage */ #define ADC_ESP32_DEFAULT_VREF_INTERNAL (1100) +#define ADC_DMA_BUFFER_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED + struct adc_esp32_conf { adc_unit_t unit; uint8_t channel_count; +#if defined(CONFIG_ADC_ESP32_DMA) + const struct device *gpio_port; + const struct device *dma_dev; + uint8_t dma_channel; +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ }; struct adc_esp32_data { @@ -54,8 +74,12 @@ struct adc_esp32_data { esp_adc_cal_characteristics_t chars[SOC_ADC_MAX_CHANNEL_NUM]; uint16_t meas_ref_internal; uint16_t *buffer; - uint16_t *buffer_repeat; bool calibrate; +#if defined(CONFIG_ADC_ESP32_DMA) + adc_hal_dma_ctx_t adc_hal_dma_ctx; + uint8_t *dma_buffer; + struct k_sem dma_conv_wait_lock; +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ }; /* Convert zephyr,gain property to the ESP32 attenuation */ @@ -80,6 +104,7 @@ static inline int gain_to_atten(enum adc_gain gain, adc_atten_t *atten) return 0; } +#if !defined(CONFIG_ADC_ESP32_DMA) /* Convert voltage by inverted attenuation to support zephyr gain values */ static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv) { @@ -101,6 +126,7 @@ static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv) break; } } +#endif /* !defined(CONFIG_ADC_ESP32_DMA) */ static bool adc_calibration_init(const struct device *dev) { @@ -120,9 +146,229 @@ static bool adc_calibration_init(const struct device *dev) LOG_ERR("Invalid arg"); break; } + return false; } +#if defined(CONFIG_ADC_ESP32_DMA) + +static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void *user_data, + uint32_t channel, int status) +{ + ARG_UNUSED(dma_dev); + ARG_UNUSED(status); + + const struct device *dev = user_data; + struct adc_esp32_data *data = dev->data; + + k_sem_give(&data->dma_conv_wait_lock); +} + +static int adc_esp32_dma_start(const struct device *dev, uint8_t *buf, size_t len) +{ + const struct adc_esp32_conf *conf = dev->config; + struct adc_esp32_data *data = dev->data; + + int err = 0; + struct dma_config dma_cfg = {0}; + struct dma_status dma_status = {0}; + struct dma_block_config dma_blk = {0}; + + err = dma_get_status(conf->dma_dev, conf->dma_channel, &dma_status); + if (err) { + LOG_ERR("Unable to get dma channel[%u] status (%d)", + (unsigned int)conf->dma_channel, err); + return -EINVAL; + } + + if (dma_status.busy) { + LOG_ERR("dma channel[%u] is busy!", (unsigned int)conf->dma_channel); + return -EBUSY; + } + + unsigned int key = irq_lock(); + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.dma_callback = adc_esp32_dma_conv_done; + dma_cfg.user_data = (void *)dev; + dma_cfg.dma_slot = ESP_GDMA_TRIG_PERIPH_ADC0; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_blk.block_size = len; + dma_blk.dest_address = (uint32_t)buf; + + err = dma_config(conf->dma_dev, conf->dma_channel, &dma_cfg); + if (err) { + LOG_ERR("Error configuring dma (%d)", err); + goto unlock; + } + + err = dma_start(conf->dma_dev, conf->dma_channel); + if (err) { + LOG_ERR("Error starting dma (%d)", err); + goto unlock; + } + +unlock: + irq_unlock(key); + return err; +} + +static int adc_esp32_dma_stop(const struct device *dev) +{ + const struct adc_esp32_conf *conf = dev->config; + unsigned int key = irq_lock(); + int err = 0; + + err = dma_stop(conf->dma_dev, conf->dma_channel); + if (err) { + LOG_ERR("Error stopping dma (%d)", err); + } + + irq_unlock(key); + return err; +} + +static int adc_esp32_fill_digi_pattern(const struct device *dev, const struct adc_sequence *seq, + void *pattern_config, uint32_t *pattern_len, uint32_t *unit_attenuation) +{ + const struct adc_esp32_conf *conf = dev->config; + struct adc_esp32_data *data = dev->data; + + adc_digi_pattern_config_t *adc_digi_pattern_config = + (adc_digi_pattern_config_t *)pattern_config; + const uint32_t unit_atten_uninit = 999; + uint32_t channel_mask = 1, channels_copy = seq->channels; + + *pattern_len = 0; + *unit_attenuation = unit_atten_uninit; + for (uint8_t channel_id = 0; channel_id < conf->channel_count; channel_id++) { + if (channels_copy & channel_mask) { + if (*unit_attenuation == unit_atten_uninit) { + *unit_attenuation = data->attenuation[channel_id]; + } else if (*unit_attenuation != data->attenuation[channel_id]) { + LOG_ERR("Channel[%u] attenuation different of unit[%u] attenuation", + (unsigned int)channel_id, (unsigned int)conf->unit); + return -EINVAL; + } + + adc_digi_pattern_config->atten = data->attenuation[channel_id]; + adc_digi_pattern_config->channel = channel_id; + adc_digi_pattern_config->unit = conf->unit; + adc_digi_pattern_config->bit_width = seq->resolution; + adc_digi_pattern_config++; + + *pattern_len += 1; + if (*pattern_len > SOC_ADC_PATT_LEN_MAX) { + LOG_ERR("Max pattern len is %d", SOC_ADC_PATT_LEN_MAX); + return -EINVAL; + } + + channels_copy &= ~channel_mask; + if (!channels_copy) { + break; + } + } + channel_mask <<= 1; + } + + return 0; +} + +static void adc_esp32_digi_start(const struct device *dev, void *pattern_config, + uint32_t pattern_len, uint32_t number_of_samplings, + uint32_t sample_freq_hz, uint32_t unit_attenuation) +{ + const struct adc_esp32_conf *conf = dev->config; + struct adc_esp32_data *data = dev->data; + + sar_periph_ctrl_adc_continuous_power_acquire(); + adc_lock_acquire(conf->unit); + +#if SOC_ADC_CALIBRATION_V1_SUPPORTED + adc_set_hw_calibration_code(conf->unit, unit_attenuation); +#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */ + +#if SOC_ADC_ARBITER_SUPPORTED + if (conf->unit == ADC_UNIT_2) { + adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); + + adc_hal_arbiter_config(&config); + } +#endif /* SOC_ADC_ARBITER_SUPPORTED */ + + adc_hal_digi_ctrlr_cfg_t adc_hal_digi_ctrlr_cfg; + soc_module_clk_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT; + uint32_t clk_src_freq_hz = 0; + + esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &clk_src_freq_hz); + + adc_hal_digi_ctrlr_cfg.conv_mode = + (conf->unit == ADC_UNIT_1)?ADC_CONV_SINGLE_UNIT_1:ADC_CONV_SINGLE_UNIT_2; + adc_hal_digi_ctrlr_cfg.clk_src = clk_src; + adc_hal_digi_ctrlr_cfg.clk_src_freq_hz = clk_src_freq_hz; + adc_hal_digi_ctrlr_cfg.sample_freq_hz = sample_freq_hz; + adc_hal_digi_ctrlr_cfg.adc_pattern = (adc_digi_pattern_config_t *)pattern_config; + adc_hal_digi_ctrlr_cfg.adc_pattern_len = pattern_len; + + uint32_t number_of_adc_digi_samples = number_of_samplings * pattern_len; + + adc_hal_dma_config_t adc_hal_dma_config = { + .dev = (void *)GDMA_LL_GET_HW(0), + .eof_desc_num = 1, + .eof_step = 1, + .dma_chan = conf->dma_channel, + .eof_num = number_of_adc_digi_samples, + }; + + adc_hal_dma_ctx_config(&data->adc_hal_dma_ctx, &adc_hal_dma_config); + + adc_hal_set_controller(conf->unit, ADC_HAL_CONTINUOUS_READ_MODE); + adc_hal_digi_init(&data->adc_hal_dma_ctx); + adc_hal_digi_controller_config(&data->adc_hal_dma_ctx, &adc_hal_digi_ctrlr_cfg); + adc_hal_digi_start(&data->adc_hal_dma_ctx, data->dma_buffer); +} + +static void adc_esp32_digi_stop(const struct device *dev) +{ + const struct adc_esp32_conf *conf = dev->config; + struct adc_esp32_data *data = dev->data; + + adc_hal_digi_dis_intr(&data->adc_hal_dma_ctx, ADC_HAL_DMA_INTR_MASK); + adc_hal_digi_clr_intr(&data->adc_hal_dma_ctx, ADC_HAL_DMA_INTR_MASK); + adc_hal_digi_stop(&data->adc_hal_dma_ctx); + adc_hal_digi_deinit(&data->adc_hal_dma_ctx); + adc_lock_release(conf->unit); + sar_periph_ctrl_adc_continuous_power_release(); +} + +static void adc_esp32_fill_seq_buffer(const void *seq_buffer, const void *dma_buffer, + uint32_t number_of_samples) +{ + uint16_t *sample = (uint16_t *)seq_buffer; + adc_digi_output_data_t *digi_data = (adc_digi_output_data_t *)dma_buffer; + + for (uint32_t k = 0; k < number_of_samples; k++) { + *sample++ = (uint16_t)(digi_data++)->type2.data; + } +} + +static int adc_esp32_wait_for_dma_conv_done(const struct device *dev) +{ + struct adc_esp32_data *data = dev->data; + int err = 0; + + err = k_sem_take(&data->dma_conv_wait_lock, K_FOREVER); + if (err) { + LOG_ERR("Error taking dma_conv_wait_lock (%d)", err); + } + + return err; +} + +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ + static int adc_esp32_read(const struct device *dev, const struct adc_sequence *seq) { const struct adc_esp32_conf *conf = dev->config; @@ -137,10 +383,12 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s return -ENOMEM; } +#if !defined(CONFIG_ADC_ESP32_DMA) if (seq->channels > BIT(channel_id)) { LOG_ERR("Multi-channel readings not supported"); return -ENOTSUP; } +#endif /* !defined(CONFIG_ADC_ESP32_DMA) */ if (seq->options) { if (seq->options->extra_samplings) { @@ -148,10 +396,12 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s return -ENOTSUP; } +#if !defined(CONFIG_ADC_ESP32_DMA) if (seq->options->interval_us) { LOG_ERR("Interval between samplings not supported"); return -ENOTSUP; } +#endif /* !defined(CONFIG_ADC_ESP32_DMA) */ } if (INVALID_RESOLUTION(seq->resolution)) { @@ -176,6 +426,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s adc_set_data_width(conf->unit, WIDTH_MASK(data->resolution[channel_id])); #endif /* CONFIG_SOC_SERIES_ESP32C3 */ +#if !defined(CONFIG_ADC_ESP32_DMA) /* Read raw value */ if (conf->unit == ADC_UNIT_1) { reading = adc1_get_raw(channel_id); @@ -216,6 +467,74 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s data->buffer = (uint16_t *) seq->buffer; data->buffer[0] = cal; +#else /* !defined(CONFIG_ADC_ESP32_DMA) */ + + int err = 0; + uint32_t adc_pattern_len, unit_attenuation; + adc_digi_pattern_config_t adc_digi_pattern_config[SOC_ADC_MAX_CHANNEL_NUM]; + + err = adc_esp32_fill_digi_pattern(dev, seq, &adc_digi_pattern_config, + &adc_pattern_len, &unit_attenuation); + if (err || adc_pattern_len == 0) { + return -EINVAL; + } + + const struct adc_sequence_options *options = seq->options; + uint32_t sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, + number_of_samplings = 1; + + if (options != NULL) { + number_of_samplings = seq->buffer_size / (adc_pattern_len * sizeof(uint16_t)); + + if (options->interval_us) { + sample_freq_hz = MHZ(1) / options->interval_us; + } + } + + if (!number_of_samplings) { + LOG_ERR("buffer_size insufficient to store at least one set of samples!"); + return -EINVAL; + } + + if (sample_freq_hz < SOC_ADC_SAMPLE_FREQ_THRES_LOW || + sample_freq_hz > SOC_ADC_SAMPLE_FREQ_THRES_HIGH) { + LOG_ERR("ADC sampling frequency out of range: %uHz", sample_freq_hz); + return -EINVAL; + } + + uint32_t number_of_adc_samples = number_of_samplings * adc_pattern_len; + uint32_t number_of_adc_dma_data_bytes = + number_of_adc_samples * SOC_ADC_DIGI_DATA_BYTES_PER_CONV; + + if (number_of_adc_dma_data_bytes > ADC_DMA_BUFFER_SIZE) { + LOG_ERR("dma buffer size insufficient to store a complete sequence!"); + return -EINVAL; + } + + err = adc_esp32_dma_start(dev, data->dma_buffer, number_of_adc_dma_data_bytes); + if (err) { + return err; + } + + adc_esp32_digi_start(dev, &adc_digi_pattern_config, adc_pattern_len, number_of_samplings, + sample_freq_hz, unit_attenuation); + + err = adc_esp32_wait_for_dma_conv_done(dev); + if (err) { + return err; + } + + adc_esp32_digi_stop(dev); + + err = adc_esp32_dma_stop(dev); + if (err) { + return err; + } + + adc_esp32_fill_seq_buffer(seq->buffer, data->dma_buffer, number_of_adc_samples); + +#endif /* !defined(CONFIG_ADC_ESP32_DMA) */ + return 0; } @@ -284,6 +603,34 @@ static int adc_esp32_channel_setup(const struct device *dev, const struct adc_ch LOG_DBG("Using ADC calibration method %d", cal); } +#if defined(CONFIG_ADC_ESP32_DMA) + + if (!SOC_ADC_DIG_SUPPORTED_UNIT(conf->unit)) { + LOG_ERR("ADC2 dma mode is no longer supported, please use ADC1!"); + return -EINVAL; + } + + int io_num = adc_channel_io_map[conf->unit][cfg->channel_id]; + + if (io_num < 0) { + LOG_ERR("Channel %u not supported!", cfg->channel_id); + return -ENOTSUP; + } + + struct gpio_dt_spec gpio = { + .port = conf->gpio_port, + .dt_flags = 0, + .pin = io_num, + }; + + err = gpio_pin_configure_dt(&gpio, GPIO_DISCONNECTED); + if (err) { + LOG_ERR("Error disconnecting io (%d)", io_num); + return err; + } + +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ + return 0; } @@ -291,9 +638,41 @@ static int adc_esp32_init(const struct device *dev) { struct adc_esp32_data *data = (struct adc_esp32_data *) dev->data; +#if defined(CONFIG_ADC_ESP32_DMA) + struct adc_esp32_conf *conf = (struct adc_esp32_conf *) dev->config; + + if (!device_is_ready(conf->gpio_port)) { + LOG_ERR("gpio0 port not ready"); + return -ENODEV; + } + + if (k_sem_init(&data->dma_conv_wait_lock, 0, 1)) { + LOG_ERR("dma_conv_wait_lock initialization failed!"); + return -EINVAL; + } + + data->adc_hal_dma_ctx.rx_desc = k_aligned_alloc(sizeof(uint32_t), + sizeof(dma_descriptor_t)); + if (!data->adc_hal_dma_ctx.rx_desc) { + LOG_ERR("rx_desc allocation failed!"); + return -ENOMEM; + } + LOG_DBG("rx_desc = 0x%08X", (unsigned int)data->adc_hal_dma_ctx.rx_desc); + + data->dma_buffer = k_aligned_alloc(sizeof(uint32_t), ADC_DMA_BUFFER_SIZE); + if (!data->dma_buffer) { + LOG_ERR("dma buffer allocation failed!"); + k_free(data->adc_hal_dma_ctx.rx_desc); + return -ENOMEM; + } + LOG_DBG("data->dma_buffer = 0x%08X", (unsigned int)data->dma_buffer); + +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ + for (uint8_t i = 0; i < ARRAY_SIZE(data->resolution); i++) { data->resolution[i] = ADC_RESOLUTION_MAX; } + for (uint8_t i = 0; i < ARRAY_SIZE(data->attenuation); i++) { data->attenuation[i] = ADC_ATTEN_DB_0; } @@ -316,11 +695,30 @@ static const struct adc_driver_api api_esp32_driver_api = { .ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL, }; +#if defined(CONFIG_ADC_ESP32_DMA) + +#define ADC_ESP32_CONF_GPIO_PORT_INIT .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)), + +#define ADC_ESP32_CONF_DMA_INIT(n) .dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0))), \ + (NULL)), \ + .dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)), \ + (0xff)), +#else + +#define ADC_ESP32_CONF_GPIO_PORT_INIT +#define ADC_ESP32_CONF_DMA_INIT(inst) + +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ + #define ESP32_ADC_INIT(inst) \ \ static const struct adc_esp32_conf adc_esp32_conf_##inst = { \ .unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \ .channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \ + ADC_ESP32_CONF_GPIO_PORT_INIT \ + ADC_ESP32_CONF_DMA_INIT(inst) \ }; \ \ static struct adc_esp32_data adc_esp32_data_##inst = { \ diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index e5e658c893aee6..ba22a05325d382 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -8,6 +8,7 @@ #include "adc_context.h" #include #include +#include #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL #include @@ -18,6 +19,18 @@ LOG_MODULE_REGISTER(adc_nrfx_saadc); #if (NRF_SAADC_HAS_AIN_AS_PIN) +#if defined(CONFIG_SOC_NRF54H20) +static const uint8_t saadc_psels[NRF_SAADC_AIN7 + 1] = { + [NRF_SAADC_AIN0] = NRF_PIN_PORT_TO_PIN_NUMBER(0U, 1), + [NRF_SAADC_AIN1] = NRF_PIN_PORT_TO_PIN_NUMBER(1U, 1), + [NRF_SAADC_AIN2] = NRF_PIN_PORT_TO_PIN_NUMBER(2U, 1), + [NRF_SAADC_AIN3] = NRF_PIN_PORT_TO_PIN_NUMBER(3U, 1), + [NRF_SAADC_AIN4] = NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), + [NRF_SAADC_AIN5] = NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), + [NRF_SAADC_AIN6] = NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1), + [NRF_SAADC_AIN7] = NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1), +}; +#elif defined(CONFIG_SOC_NRF54L15) static const uint8_t saadc_psels[NRF_SAADC_AIN7 + 1] = { [NRF_SAADC_AIN0] = NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), [NRF_SAADC_AIN1] = NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), @@ -28,6 +41,7 @@ static const uint8_t saadc_psels[NRF_SAADC_AIN7 + 1] = { [NRF_SAADC_AIN6] = NRF_PIN_PORT_TO_PIN_NUMBER(13U, 1), [NRF_SAADC_AIN7] = NRF_PIN_PORT_TO_PIN_NUMBER(14U, 1), }; +#endif #else BUILD_ASSERT((NRF_SAADC_AIN0 == NRF_SAADC_INPUT_AIN0) && @@ -38,7 +52,6 @@ BUILD_ASSERT((NRF_SAADC_AIN0 == NRF_SAADC_INPUT_AIN0) && (NRF_SAADC_AIN5 == NRF_SAADC_INPUT_AIN5) && (NRF_SAADC_AIN6 == NRF_SAADC_INPUT_AIN6) && (NRF_SAADC_AIN7 == NRF_SAADC_INPUT_AIN7) && - (NRF_SAADC_AIN7 == NRF_SAADC_INPUT_AIN7) && #if defined(SAADC_CH_PSELP_PSELP_VDDHDIV5) (NRF_SAADC_VDDHDIV5 == NRF_SAADC_INPUT_VDDHDIV5) && #endif @@ -49,16 +62,43 @@ BUILD_ASSERT((NRF_SAADC_AIN0 == NRF_SAADC_INPUT_AIN0) && "Definitions from nrf-adc.h do not match those from nrf_saadc.h"); #endif +#ifdef CONFIG_SOC_NRF54H20 + +/* nRF54H20 always uses bounce buffers in RAM */ + +#define SAADC_MEMORY_SECTION \ + COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(adc), memory_regions), \ + (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ + DT_PHANDLE(DT_NODELABEL(adc), memory_regions)))))), \ + ()) + +static uint16_t adc_samples_buffer[SAADC_CH_NUM] SAADC_MEMORY_SECTION; + +#define ADC_BUFFER_IN_RAM + +#endif /* CONFIG_SOC_NRF54H20 */ + struct driver_data { struct adc_context ctx; uint8_t positive_inputs[SAADC_CH_NUM]; + +#if defined(ADC_BUFFER_IN_RAM) + void *samples_buffer; + void *user_buffer; + uint8_t active_channels; +#endif }; static struct driver_data m_data = { ADC_CONTEXT_INIT_TIMER(m_data, ctx), ADC_CONTEXT_INIT_LOCK(m_data, ctx), ADC_CONTEXT_INIT_SYNC(m_data, ctx), +#if defined(ADC_BUFFER_IN_RAM) + .samples_buffer = adc_samples_buffer, + .user_buffer = NULL, + .active_channels = 0, +#endif }; /* Helper function to convert number of samples to the byte representation. */ @@ -279,11 +319,15 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, ARG_UNUSED(ctx); if (!repeat) { +#if defined(ADC_BUFFER_IN_RAM) + m_data.user_buffer = (uint8_t *)m_data.user_buffer + + samples_to_bytes(&ctx->sequence, nrfy_saadc_amount_get(NRF_SAADC)); +#else nrf_saadc_value_t *buffer = (uint8_t *)nrf_saadc_buffer_pointer_get(NRF_SAADC) + - samples_to_bytes(&ctx->sequence, nrfy_saadc_amount_get(NRF_SAADC)); - + samples_to_bytes(&ctx->sequence, nrfy_saadc_amount_get(NRF_SAADC)); nrfy_saadc_buffer_pointer_set(NRF_SAADC, buffer); +#endif } } @@ -457,13 +501,23 @@ static int start_read(const struct device *dev, return error; } +#if defined(ADC_BUFFER_IN_RAM) + m_data.user_buffer = sequence->buffer; + m_data.active_channels = active_channels; + + nrf_saadc_buffer_init(NRF_SAADC, + (nrf_saadc_value_t *)m_data.samples_buffer, + active_channels); +#else nrf_saadc_buffer_init(NRF_SAADC, (nrf_saadc_value_t *)sequence->buffer, active_channels); +#endif adc_context_start_read(&m_data.ctx, sequence); error = adc_context_wait_for_completion(&m_data.ctx); + return error; } @@ -504,6 +558,11 @@ static void saadc_irq_handler(const struct device *dev) nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP); nrf_saadc_disable(NRF_SAADC); +#if defined(ADC_BUFFER_IN_RAM) + memcpy(m_data.user_buffer, m_data.samples_buffer, + samples_to_bytes(&m_data.ctx.sequence, m_data.active_channels)); +#endif + adc_context_on_sampling_done(&m_data.ctx, dev); } else if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE)) { @@ -544,6 +603,8 @@ static const struct adc_driver_api adc_nrfx_driver_api = { #endif #if defined(CONFIG_SOC_NRF54L15) .ref_internal = 900, +#elif defined(CONFIG_SOC_NRF54H20) + .ref_internal = 1024, #else .ref_internal = 600, #endif diff --git a/drivers/adc/adc_smartbond_gpadc.c b/drivers/adc/adc_smartbond_gpadc.c index 49854372a5aab0..367d32110ea2fa 100644 --- a/drivers/adc/adc_smartbond_gpadc.c +++ b/drivers/adc/adc_smartbond_gpadc.c @@ -8,6 +8,7 @@ #define ADC_CONTEXT_USES_KERNEL_TIMER #include +#include #include "adc_context.h" #include @@ -15,7 +16,13 @@ #include #include #include +#include +#include +#include #include +#include +#include +#include LOG_MODULE_REGISTER(adc_smartbond_adc); @@ -34,6 +41,10 @@ struct adc_smartbond_data { uint8_t sequence_channel_count; /* Index in buffer to store current value to */ uint8_t result_index; +#if defined(CONFIG_PM_DEVICE) + /* Flag to prevent sleep */ + ATOMIC_DEFINE(pm_policy_state_flag, 1); +#endif }; #define SMARTBOND_ADC_CHANNEL_COUNT 8 @@ -101,6 +112,42 @@ static int adc_smartbond_channel_setup(const struct device *dev, return 0; } +static inline void gpadc_smartbond_pm_policy_state_lock_get(const struct device *dev, + struct adc_smartbond_data *data) +{ + +#if defined(CONFIG_PM_DEVICE) +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_get(dev); +#endif + + if (!atomic_test_and_set_bit(data->pm_policy_state_flag, 0)) { + /* + * Prevent the SoC from entering the normal sleep state. + */ + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } + +#endif +} + +static inline void gpadc_smartbond_pm_policy_state_lock_put(const struct device *dev, + struct adc_smartbond_data *data) +{ +#if defined(CONFIG_PM_DEVICE) +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_put(dev); +#endif + + if (atomic_test_and_clear_bit(data->pm_policy_state_flag, 0)) { + /* + * Allow the SoC to enter the normal sleep state once GPADC is done. + */ + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } +#endif +} + #define PER_CHANNEL_ADC_CONFIG_MASK (GPADC_GP_ADC_CTRL_REG_GP_ADC_SEL_Msk | \ GPADC_GP_ADC_CTRL_REG_GP_ADC_SE_Msk) @@ -213,6 +260,7 @@ static void adc_smartbond_isr(const struct device *dev) if (data->channel_read_mask == 0) { adc_context_on_sampling_done(&data->ctx, dev); + gpadc_smartbond_pm_policy_state_lock_put(dev, data); } else { adc_context_start_sampling(&data->ctx); } @@ -227,6 +275,7 @@ static int adc_smartbond_read(const struct device *dev, int error; struct adc_smartbond_data *data = dev->data; + gpadc_smartbond_pm_policy_state_lock_get(dev, data); adc_context_lock(&data->ctx, false, NULL); error = start_read(dev, sequence); adc_context_release(&data->ctx, error); @@ -243,6 +292,7 @@ static int adc_smartbond_read_async(const struct device *dev, struct adc_smartbond_data *data = dev->data; int error; + gpadc_smartbond_pm_policy_state_lock_get(dev, data); adc_context_lock(&data->ctx, true, async); error = start_read(dev, sequence); adc_context_release(&data->ctx, error); @@ -251,26 +301,99 @@ static int adc_smartbond_read_async(const struct device *dev, } #endif /* CONFIG_ADC_ASYNC */ -static int adc_smartbond_init(const struct device *dev) +static int gpadc_smartbond_resume(const struct device *dev) { - int err; - struct adc_smartbond_data *data = dev->data; + int ret, rate; const struct adc_smartbond_cfg *config = dev->config; + const struct device *clock_dev = DEVICE_DT_GET(DT_NODELABEL(osc)); + + da1469x_pd_acquire(MCU_PD_DOMAIN_PER); + + /* Get current clock to determine GP_ADC_EN_DEL */ + clock_control_get_rate(clock_dev, (clock_control_subsys_t)SMARTBOND_CLK_SYS_CLK, &rate); + GPADC->GP_ADC_CTRL3_REG = (rate/1600000)&0xff; GPADC->GP_ADC_CTRL_REG = GPADC_GP_ADC_CTRL_REG_GP_ADC_EN_Msk; - GPADC->GP_ADC_CTRL2_REG = 0; - GPADC->GP_ADC_CTRL3_REG = 0x40; - GPADC->GP_ADC_CLEAR_INT_REG = 0x0; /* * Configure dt provided device signals when available. * pinctrl is optional so ENOENT is not setup failure. */ - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0 && err != -ENOENT) { - LOG_ERR("ADC pinctrl setup failed (%d)", err); - return err; + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0 && ret != -ENOENT) { + /* Disable the GPADC LDO */ + GPADC->GP_ADC_CTRL_REG = 0; + + /* Release the peripheral domain */ + da1469x_pd_release(MCU_PD_DOMAIN_PER); + + LOG_ERR("ADC pinctrl setup failed (%d)", ret); + return ret; + } + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int gpadc_smartbond_suspend(const struct device *dev) +{ + int ret; + const struct adc_smartbond_cfg *config = dev->config; + + /* Disable the GPADC LDO */ + GPADC->GP_ADC_CTRL_REG = 0; + + /* Release the peripheral domain */ + da1469x_pd_release(MCU_PD_DOMAIN_PER); + + /* + * Configure dt provided device signals for sleep. + * pinctrl is optional so ENOENT is not setup failure. + */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); + if (ret < 0 && ret != -ENOENT) { + LOG_WRN("Failed to configure the GPADC pins to inactive state"); + return ret; } + + return 0; +} + +static int gpadc_smartbond_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = gpadc_smartbond_resume(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = gpadc_smartbond_suspend(dev); + break; + default: + return -ENOTSUP; + } + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +static int adc_smartbond_init(const struct device *dev) +{ + int ret; + struct adc_smartbond_data *data = dev->data; + +#ifdef CONFIG_PM_DEVICE_RUNTIME + /* Make sure device state is marked as suspended */ + pm_device_init_suspended(dev); + + ret = pm_device_runtime_enable(dev); + +#else + ret = gpadc_smartbond_resume(dev); + +#endif + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), adc_smartbond_isr, DEVICE_DT_INST_GET(0), 0); @@ -279,7 +402,7 @@ static int adc_smartbond_init(const struct device *dev) adc_context_unlock_unconditionally(&data->ctx); - return 0; + return ret; } static const struct adc_driver_api adc_smartbond_driver_api = { @@ -312,8 +435,10 @@ static const struct adc_driver_api adc_smartbond_driver_api = { ADC_CONTEXT_INIT_LOCK(adc_smartbond_data_##inst, ctx), \ ADC_CONTEXT_INIT_SYNC(adc_smartbond_data_##inst, ctx), \ }; \ - DEVICE_DT_INST_DEFINE(0, \ - adc_smartbond_init, NULL, \ + PM_DEVICE_DT_INST_DEFINE(inst, gpadc_smartbond_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, \ + adc_smartbond_init, \ + PM_DEVICE_DT_INST_GET(inst), \ &adc_smartbond_data_##inst, \ &adc_smartbond_cfg_##inst, \ POST_KERNEL, \ diff --git a/drivers/adc/adc_smartbond_sdadc.c b/drivers/adc/adc_smartbond_sdadc.c index 7ac435f7860344..5576a65bed159e 100644 --- a/drivers/adc/adc_smartbond_sdadc.c +++ b/drivers/adc/adc_smartbond_sdadc.c @@ -8,6 +8,7 @@ #define ADC_CONTEXT_USES_KERNEL_TIMER #include +#include #include "adc_context.h" #include @@ -16,6 +17,9 @@ #include #include #include +#include +#include +#include LOG_MODULE_REGISTER(adc_smartbond_sdadc); @@ -36,6 +40,10 @@ struct sdadc_smartbond_data { uint8_t sequence_channel_count; /* Index in buffer to store current value to */ uint8_t result_index; +#if defined(CONFIG_PM_DEVICE) + /* Flag to prevent sleep */ + ATOMIC_DEFINE(pm_policy_state_flag, 1); +#endif }; #define SMARTBOND_SDADC_CHANNEL_COUNT 8 @@ -107,6 +115,41 @@ static int sdadc_smartbond_channel_setup(const struct device *dev, SDADC_SDADC_CTRL_REG_SDADC_SE_Msk \ ) +static inline void sdadc_smartbond_pm_policy_state_lock_get(const struct device *dev, + struct sdadc_smartbond_data *data) +{ +#if defined(CONFIG_PM_DEVICE) +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_get(dev); +#endif + + if (!atomic_test_and_set_bit(data->pm_policy_state_flag, 0)) { + /* + * Prevent the SoC from entering the normal sleep state. + */ + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } +#endif +} + +static inline void sdadc_smartbond_pm_policy_state_lock_put(const struct device *dev, + struct sdadc_smartbond_data *data) +{ +#if defined(CONFIG_PM_DEVICE) +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_put(dev); +#endif + + if (atomic_test_and_clear_bit(data->pm_policy_state_flag, 0)) { + /* + * Allow the SoC to enter the normal sleep state once sdadc is done. + */ + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } +#endif +} + + static int pop_count(uint32_t n) { return __builtin_popcount(n); @@ -120,6 +163,10 @@ static void adc_context_start_sampling(struct adc_context *ctx) /* Extract lower channel from sequence mask */ int current_channel = u32_count_trailing_zeros(data->channel_read_mask); + /* Wait until the SDADC LDO stabilizes */ + while (!(SDADC->SDADC_CTRL_REG & SDADC_SDADC_CTRL_REG_SDADC_LDO_OK_Msk)) + __NOP(); + if (ctx->sequence.calibrate) { /* TODO: Add calibration code */ } else { @@ -216,6 +263,7 @@ static void sdadc_smartbond_isr(const struct device *dev) if (data->channel_read_mask == 0) { adc_context_on_sampling_done(&data->ctx, dev); + sdadc_smartbond_pm_policy_state_lock_put(dev, data); } else { adc_context_start_sampling(&data->ctx); } @@ -230,6 +278,7 @@ static int sdadc_smartbond_read(const struct device *dev, int error; struct sdadc_smartbond_data *data = dev->data; + sdadc_smartbond_pm_policy_state_lock_get(dev, data); adc_context_lock(&data->ctx, false, NULL); error = start_read(dev, sequence); adc_context_release(&data->ctx, error); @@ -246,6 +295,7 @@ static int sdadc_smartbond_read_async(const struct device *dev, struct sdadc_smartbond_data *data = dev->data; int error; + sdadc_smartbond_pm_policy_state_lock_get(dev, data); adc_context_lock(&data->ctx, true, async); error = start_read(dev, sequence); adc_context_release(&data->ctx, error); @@ -254,26 +304,97 @@ static int sdadc_smartbond_read_async(const struct device *dev, } #endif /* CONFIG_ADC_ASYNC */ -static int sdadc_smartbond_init(const struct device *dev) +static int sdadc_smartbond_resume(const struct device *dev) { - int err; - struct sdadc_smartbond_data *data = dev->data; + int ret; const struct sdadc_smartbond_cfg *config = dev->config; - SDADC->SDADC_CTRL_REG = SDADC_SDADC_CTRL_REG_SDADC_EN_Msk; - SDADC->SDADC_CLEAR_INT_REG = 0x0; + da1469x_pd_acquire(MCU_PD_DOMAIN_COM); + SDADC->SDADC_TEST_REG = (SDADC->SDADC_TEST_REG & ~SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Msk) | (config->sdadc_clk_freq) << SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Pos; + + SDADC->SDADC_CTRL_REG = SDADC_SDADC_CTRL_REG_SDADC_EN_Msk; + /* * Configure dt provided device signals when available. * pinctrl is optional so ENOENT is not setup failure. */ - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0 && err != -ENOENT) { - LOG_ERR("ADC pinctrl setup failed (%d)", err); - return err; + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0 && ret != -ENOENT) { + SDADC->SDADC_CTRL_REG = 0; + + /* Release the comms domain */ + da1469x_pd_release(MCU_PD_DOMAIN_COM); + + LOG_ERR("ADC pinctrl setup failed (%d)", ret); + return ret; } + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int sdadc_smartbond_suspend(const struct device *dev) +{ + int ret; + const struct sdadc_smartbond_cfg *config = dev->config; + + /* Disable the sdadc LDO */ + SDADC->SDADC_CTRL_REG = 0; + + /* Release the comms domain */ + da1469x_pd_release(MCU_PD_DOMAIN_COM); + + /* + * Configure dt provided device signals for sleep. + * pinctrl is optional so ENOENT is not setup failure. + */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); + if (ret < 0 && ret != -ENOENT) { + LOG_WRN("Failed to configure the sdadc pins to inactive state"); + return ret; + } + + return 0; +} + +static int sdadc_smartbond_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = sdadc_smartbond_resume(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = sdadc_smartbond_suspend(dev); + break; + default: + return -ENOTSUP; + } + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +static int sdadc_smartbond_init(const struct device *dev) +{ + int ret; + struct sdadc_smartbond_data *data = dev->data; + +#ifdef CONFIG_PM_DEVICE_RUNTIME + /* Make sure device state is marked as suspended */ + pm_device_init_suspended(dev); + + ret = pm_device_runtime_enable(dev); + +#else + ret = sdadc_smartbond_resume(dev); + +#endif + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), sdadc_smartbond_isr, DEVICE_DT_INST_GET(0), 0); @@ -282,7 +403,7 @@ static int sdadc_smartbond_init(const struct device *dev) adc_context_unlock_unconditionally(&data->ctx); - return 0; + return ret; } static const struct adc_driver_api sdadc_smartbond_driver_api = { @@ -316,8 +437,10 @@ static const struct adc_driver_api sdadc_smartbond_driver_api = { ADC_CONTEXT_INIT_LOCK(sdadc_smartbond_data_##inst, ctx), \ ADC_CONTEXT_INIT_SYNC(sdadc_smartbond_data_##inst, ctx), \ }; \ - DEVICE_DT_INST_DEFINE(0, \ - sdadc_smartbond_init, NULL, \ + PM_DEVICE_DT_INST_DEFINE(inst, sdadc_smartbond_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, \ + sdadc_smartbond_init, \ + PM_DEVICE_DT_INST_GET(inst), \ &sdadc_smartbond_data_##inst, \ &sdadc_smartbond_cfg_##inst, \ POST_KERNEL, \ diff --git a/drivers/bbram/bbram_stm32.c b/drivers/bbram/bbram_stm32.c index 8412153bc76c4c..26acf001a9aed0 100644 --- a/drivers/bbram/bbram_stm32.c +++ b/drivers/bbram/bbram_stm32.c @@ -11,6 +11,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(bbram, CONFIG_BBRAM_LOG_LEVEL); @@ -65,6 +66,10 @@ static int bbram_stm32_write(const struct device *dev, size_t offset, size_t siz return -EFAULT; } +#if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP) + LL_PWR_EnableBkUpAccess(); +#endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPCR_DBP || PWR_DBPR_DBP */ + for (size_t written = 0; written < size; written += to_copy) { reg = STM32_BKP_REG(STM32_BKP_REG_INDEX(offset + written)); begin = STM32_BKP_REG_BYTE_INDEX(offset + written); @@ -73,6 +78,10 @@ static int bbram_stm32_write(const struct device *dev, size_t offset, size_t siz STM32_BKP_REG(STM32_BKP_REG_INDEX(offset + written)) = reg; } +#if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP) + LL_PWR_DisableBkUpAccess(); +#endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPCR_DBP || PWR_DBPR_DBP */ + return 0; } diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 46bf62bb1a7ff8..a1680af6583d00 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -12,7 +12,7 @@ menuconfig BT_DRIVERS bool "Bluetooth drivers" default y - depends on BT && !BT_CTLR + depends on BT if BT_DRIVERS diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index 94210e7963174b..14d81d7458d5b5 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -13,7 +13,6 @@ if(CONFIG_BT_HCI_IPC) endif() endif() -zephyr_library_sources_ifdef(CONFIG_BT_AIROC cyw43xxx.c) zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c) zephyr_library_sources_ifdef(CONFIG_BT_H4 h4.c) zephyr_library_sources_ifdef(CONFIG_BT_H5 h5.c) @@ -25,12 +24,16 @@ if(CONFIG_BT_SPI) zephyr_library_sources(spi.c) endif() endif() +zephyr_library_sources_ifdef(CONFIG_BT_CYW43XX h4_ifx_cyw43xxx.c) +zephyr_library_sources_ifdef(CONFIG_BT_CYW208XX hci_ifx_cyw208xx.c) + zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c) zephyr_library_sources_ifdef(CONFIG_BT_STM32WBA hci_stm32wba.c) zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c) zephyr_library_sources_ifdef(CONFIG_BT_SILABS_HCI slz_hci.c) -zephyr_library_sources_ifdef(CONFIG_BT_PSOC6_BLESS hci_psoc6_bless.c) +zephyr_library_sources_ifdef(CONFIG_BT_PSOC6_BLESS hci_ifx_psoc6_bless.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP nrf53_support.c) zephyr_library_sources_ifdef(CONFIG_BT_AMBIQ_HCI hci_ambiq.c apollox_blue.c) zephyr_library_sources_ifdef(CONFIG_BT_DA1469X hci_da1469x.c) zephyr_library_sources_ifdef(CONFIG_BT_NXP hci_nxp.c) +zephyr_library_sources_ifdef(CONFIG_BT_H4_NXP_CTLR hci_nxp_setup.c) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index d00cb7315634ab..c311fc185eecbc 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -10,13 +10,11 @@ config BT_UART select SERIAL select UART_INTERRUPT_DRIVEN - -choice BT_HCI_BUS_TYPE - prompt "Bluetooth HCI driver" - config BT_H4 bool "H:4 UART" select BT_UART + default y + depends on DT_HAS_ZEPHYR_BT_HCI_UART_ENABLED help Bluetooth H:4 UART driver. Requires hardware flow control lines to be available. @@ -25,6 +23,8 @@ config BT_H5 bool "H:5 UART [EXPERIMENTAL]" select BT_UART select EXPERIMENTAL + default y + depends on DT_HAS_ZEPHYR_BT_HCI_3WIRE_UART_ENABLED help Bluetooth three-wire (H:5) UART driver. Implementation of HCI Three-Wire UART Transport Layer. @@ -38,6 +38,8 @@ config BT_RPMSG config BT_HCI_IPC bool "HCI using the IPC subsystem" + default y + depends on DT_HAS_ZEPHYR_BT_HCI_IPC_ENABLED select BT_HAS_HCI_VS select IPC_SERVICE select MBOX @@ -57,6 +59,8 @@ config BT_SPI config BT_STM32_IPM bool "IPM HCI" + default y + depends on DT_HAS_ST_STM32WB_RF_ENABLED select USE_STM32_HAL_CORTEX select HAS_STM32LIB help @@ -64,13 +68,16 @@ config BT_STM32_IPM config BT_STM32WBA bool "STM32WBA HCI driver" + default y + depends on DT_HAS_ST_HCI_STM32WBA_ENABLED select HAS_STM32LIB help ST STM32WBA HCI Bluetooth interface config BT_SILABS_HCI bool "Silicon Labs Bluetooth interface" - depends on SOC_SERIES_EFR32BG22 || SOC_SERIES_EFR32MG24 || SOC_SERIES_EFR32BG27 + default y + depends on DT_HAS_SILABS_BT_HCI_ENABLED depends on !PM || SOC_GECKO_PM_BACKEND_PMGR select SOC_GECKO_USE_RAIL select ENTROPY_GENERATOR @@ -85,6 +92,8 @@ config BT_SILABS_HCI config BT_USERCHAN bool "HCI User Channel based driver" depends on BOARD_NATIVE_POSIX + default y + depends on DT_HAS_ZEPHYR_BT_HCI_USERCHAN_ENABLED help This driver provides access to the local Linux host's Bluetooth adapter using a User Channel HCI socket to the Linux kernel. It @@ -94,11 +103,15 @@ config BT_USERCHAN config BT_ESP32 bool "ESP32 HCI driver" + default y + depends on DT_HAS_ESPRESSIF_ESP32_BT_HCI_ENABLED help Espressif HCI bluetooth interface config BT_PSOC6_BLESS bool "PSOC6 BLESS driver" + default y + depends on DT_HAS_INFINEON_CAT1_BLESS_HCI_ENABLED select BT_HCI_SETUP help PSOC6 BLESS driver with BLE Controller which operates in @@ -106,24 +119,31 @@ config BT_PSOC6_BLESS config BT_DA1469X bool "DA1469x HCI driver" + default y + depends on DT_HAS_RENESAS_BT_HCI_DA1469X_ENABLED help Bluetooth HCI driver for communication with CMAC core on DA1469x MCU. config BT_NXP bool "NXP HCI driver" + default y + depends on DT_HAS_NXP_HCI_BLE_ENABLED + select BT_HCI_SETUP help NXP HCI bluetooth interface -config BT_NO_DRIVER - bool "No default HCI driver" - select BT_HAS_HCI_VS +config BT_CYW208XX + bool "CYW208XX BLE driver" + default y + depends on DT_HAS_INFINEON_CYW208XX_HCI_ENABLED help - This is intended for unit tests where no internal driver - should be selected. + Infineon CYW208XX HCI bluetooth interface config BT_AMBIQ_HCI bool "AMBIQ BT HCI driver" + default y + depends on DT_HAS_AMBIQ_BT_HCI_SPI_ENABLED select SPI select GPIO if SOC_SERIES_APOLLO4X select CLOCK_CONTROL if SOC_SERIES_APOLLO4X @@ -132,7 +152,6 @@ config BT_AMBIQ_HCI Supports Ambiq Bluetooth SoC using SPI as the communication protocol. HCI packets are sent and received as single Byte transfers. -endchoice if BT_SPI @@ -164,11 +183,13 @@ config BT_STM32_IPM_RX_STACK_SIZE menuconfig BT_AIROC bool "AIROC BT connectivity" default y + select GPIO if BT_H4 + select UART if BT_H4 + select UART_USE_RUNTIME_CONFIGURE if BT_H4 select BT_HCI_SETUP - select UART_USE_RUNTIME_CONFIGURE - depends on GPIO - depends on DT_HAS_INFINEON_CYW43XXX_BT_HCI_ENABLED - depends on BT_H4 + select USE_INFINEON_ABSTRACTION_RTOS if BT_CYW208XX + select EVENTS if BT_CYW208XX + depends on DT_HAS_INFINEON_CYW43XXX_BT_HCI_ENABLED || DT_HAS_INFINEON_CYW208XX_HCI_ENABLED help Infineon's AIROC™ Wi-Fi & combos portfolio integrates IEEE 802.11a/b/g/n/ac/ax Wi-Fi and Bluetooth® 5.2 in a single-chip @@ -237,3 +258,33 @@ config BT_SILABS_HCI_BUFFER_MEMORY help Select the size of allocated memory buffer for the Silicon Labs Bluetooth Library. + +config BT_H4_NXP_CTLR + bool "NXP Bluetooth Controller" + select GPIO + depends on BT_H4 + select CRC + default y + depends on DT_HAS_NXP_BT_HCI_UART_ENABLED + help + Enables support for NXP Bluetooth Controller. + More inforamtion about NXP Bluetooth profuct could be found on + https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4:WIFI-BLUETOOTH + +if BT_H4_NXP_CTLR + +config BT_H4_NXP_CTLR_WAIT_HDR_SIG_TIMEOUT + int "Timeout for waiting HDR Signure" + range 1000 60000 + default 2500 + help + Timeout for waiting HDR Signure. Unit is millisecond. + +config BT_H4_NXP_CTLR_WAIT_TIME_AFTER_UPLOAD + int "Waiting time after firmware is uploaded" + range 1000 5000 + default 1000 + help + Waiting time after firmware is uploaded. Unit is millisecond. + +endif #BT_H4_NXP_CTLR diff --git a/drivers/bluetooth/hci/Kconfig.infineon b/drivers/bluetooth/hci/Kconfig.infineon index 6204ed4f8a2fdf..3e9138eb500546 100644 --- a/drivers/bluetooth/hci/Kconfig.infineon +++ b/drivers/bluetooth/hci/Kconfig.infineon @@ -4,11 +4,16 @@ if BT_AIROC +config BT_CYW43XX + bool + default y if BT_AIROC && BT_H4 + choice AIROC_PART prompt "Select AIROC part" config CYW4343W bool "CYW4343W" + depends on BT_H4 help Enable Infineon CYW4343W BLE connectivity, More information about CYW4343W device you can find on @@ -16,6 +21,7 @@ config CYW4343W config CYW4373 bool "CYW4373" + depends on BT_H4 help Enable Infineon CYW4373 BLE connectivity, More information about CYW4373 device you can find on @@ -23,6 +29,7 @@ config CYW4373 config CYW43012 bool "CYW43012" + depends on BT_H4 help Enable Infineon CYW43012 BLE connectivity, More information about CYW43012 device you can find on @@ -30,6 +37,7 @@ config CYW43012 config CYW43438 bool "CYW43438" + depends on BT_H4 help Enable Infineon CYW43438 BLE connectivity, More information about CYW43438 device you can find on @@ -37,11 +45,20 @@ config CYW43438 config CYW43439 bool "CYW43439" + depends on BT_H4 help Enable Infineon CYW43439 BLE connectivity, More information about CYW43439 device you can find on https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/cyw43439/ +config CYW20829 + bool "CYW20829" + depends on BT_CYW208XX + help + Enable Infineon CYW20829 BLE connectivity, + More information about CYW20829 device you can find on + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-bluetooth-le-bluetooth-multiprotocol/airoc-bluetooth-le/cyw20829/ + config BT_AIROC_CUSTOM bool "Custom AIROC device/module" help @@ -92,11 +109,11 @@ choice CYW4373_MODULE config CYW4373_STERLING_LWB5PLUS bool "STERLING-LWB5plus" help - Laird Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board + Ezurio Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board (E-Type Key w/ SDIO/UART) Detailed information about Type Sterling LWB5+ module you can find on - https://www.lairdconnect.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module + https://www.ezurio.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module endchoice @@ -117,6 +134,61 @@ config CYW43439_MURATA_1YN endchoice +if CYW20829 + +config CYW20829_BT_FW_TX10DBM_POWER + bool "CYW20829_BT_FW_TX10DBM_POWER" + help + Enable 10dBm TX Power variant of CYW20829 FW patch. + +choice CYW20829_BT_FW + prompt "Select variant of default CYW20829 BT FW" + default CYW20829_BT_FW_ISOC_TX10 if BT_ISO && CYW20829_BT_FW_TX10DBM_POWER + default CYW20829_BT_FW_ISOC_TX0 if BT_ISO && !CYW20829_BT_FW_TX10DBM_POWER + default CYW20829_BT_FW_PAWR_TX10 if BT_PER_ADV_RSP && CYW20829_BT_FW_TX10DBM_POWER + default CYW20829_BT_FW_PAWR_TX0 if BT_PER_ADV_RSP && !CYW20829_BT_FW_TX10DBM_POWER + default CYW20829_BT_FW_TX10 if CYW20829_BT_FW_TX10DBM_POWER + default CYW20829_BT_FW_TX0 + +config CYW20829_BT_FW_TX0 + bool "CYW20829_BT_FW_TX0" + help + Enable CYW20829 FW patch for 0dBm TX Power. + This configuration should be used with non-PAWR and non-ISOC applications. + +config CYW20829_BT_FW_TX10 + bool "CYW20829_BT_FW_TX10" + help + Enable CYW20829 FW patch for 10dBm TX Power. + This configuration should be used with non-PAwR and non-ISOC applications. + +config CYW20829_BT_FW_PAWR_TX0 + bool "CYW20829_BT_FW_PAWR_TX0" + help + Enable CYW20829 FW patch with PAwR support for 0dBm TX Power. + This configuration should be used with PAwR applications. + +config CYW20829_BT_FW_PAWR_TX10 + bool "CYW20829_BT_FW_PAWR_TX10" + help + Enable CYW20829 FW patch for 10dBm TX Power. + This configuration should be used with PAwR applications. + +config CYW20829_BT_FW_ISOC_TX0 + bool "CYW20829_BT_FW_ISOC_TX0" + help + Enable CYW20829 FW patch for 0dBm TX Power. + This configuration should be used with ISOC applications. + +config CYW20829_BT_FW_ISOC_TX10 + bool "CYW20829_BT_FW_ISOC_TX10" + help + Enable CYW20829 FW patch for 10dBm TX Power. + This configuration should be used with ISOC applications. + +endchoice +endif # CYW20829 + config AIROC_CUSTOM_FIRMWARE_HCD_BLOB depends on BT_AIROC_CUSTOM string "Path to user BT firmware HCD file" diff --git a/drivers/bluetooth/hci/Kconfig.nxp b/drivers/bluetooth/hci/Kconfig.nxp index a5eb8648c8ad5f..65bbc3067e76d5 100644 --- a/drivers/bluetooth/hci/Kconfig.nxp +++ b/drivers/bluetooth/hci/Kconfig.nxp @@ -1,5 +1,5 @@ # -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -22,3 +22,19 @@ config HCI_NXP_SET_CAL_DATA_ANNEX100 help If enabled, the Host will send calibration data annex 100 to the BLE Controller during HCI init. + +if BT_H4_NXP_CTLR + +config BT_NXP_NW612 + bool "NXP IW612 Chipset" + help + NXP IW612 Chipset supports Wi-Fi? 802.11a/b/g/n/ac/ax + Bluetooth? 5.3 + BR/EDR/LE + IEEE802.1.5.4 up to 601 Mbps data rate on Wi-Fi? and 2Mbps + data rate on Bluetooth?. 4-wire UART@3M baud is supported. PCM for + audio is also supported. + Details of the module could be fond on https://www.nxp.com/products/ + wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/2-4-5-ghz- + dual-band-1x1-wi-fi-6-802-11ax-plus-bluetooth-5-4-plus-802-15-4-tri- + radio-solution:IW612. + +endif # BT_H4_NXP_CTLR diff --git a/drivers/bluetooth/hci/apollox_blue.c b/drivers/bluetooth/hci/apollox_blue.c index a25af495bf6e12..7994069a5a2a42 100644 --- a/drivers/bluetooth/hci/apollox_blue.c +++ b/drivers/bluetooth/hci/apollox_blue.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 16b28b52586a3d..412214c7f32241 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -20,7 +20,7 @@ #include #include -#include +#include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL #include @@ -30,168 +30,183 @@ LOG_MODULE_REGISTER(bt_driver); #include "../util.h" -static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_DRV_RX_STACK_SIZE); -static struct k_thread rx_thread_data; +#define DT_DRV_COMPAT zephyr_bt_hci_uart -static struct { - struct net_buf *buf; - struct k_fifo fifo; +struct h4_data { + struct { + struct net_buf *buf; + struct k_fifo fifo; - uint16_t remaining; - uint16_t discard; + uint16_t remaining; + uint16_t discard; - bool have_hdr; - bool discardable; + bool have_hdr; + bool discardable; - uint8_t hdr_len; + uint8_t hdr_len; - uint8_t type; - union { - struct bt_hci_evt_hdr evt; - struct bt_hci_acl_hdr acl; - struct bt_hci_iso_hdr iso; - uint8_t hdr[4]; - }; -} rx = { - .fifo = Z_FIFO_INITIALIZER(rx.fifo), -}; + uint8_t type; + union { + struct bt_hci_evt_hdr evt; + struct bt_hci_acl_hdr acl; + struct bt_hci_iso_hdr iso; + uint8_t hdr[4]; + }; + } rx; -static struct { - uint8_t type; - struct net_buf *buf; - struct k_fifo fifo; -} tx = { - .fifo = Z_FIFO_INITIALIZER(tx.fifo), + struct { + uint8_t type; + struct net_buf *buf; + struct k_fifo fifo; + } tx; + + bt_hci_recv_t recv; }; -static const struct device *const h4_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_uart)); +struct h4_config { + const struct device *uart; + k_thread_stack_t *rx_thread_stack; + size_t rx_thread_stack_size; + struct k_thread *rx_thread; +}; -static inline void h4_get_type(void) +static inline void h4_get_type(const struct device *dev) { + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; + /* Get packet type */ - if (uart_fifo_read(h4_dev, &rx.type, 1) != 1) { + if (uart_fifo_read(cfg->uart, &h4->rx.type, 1) != 1) { LOG_WRN("Unable to read H:4 packet type"); - rx.type = BT_HCI_H4_NONE; + h4->rx.type = BT_HCI_H4_NONE; return; } - switch (rx.type) { + switch (h4->rx.type) { case BT_HCI_H4_EVT: - rx.remaining = sizeof(rx.evt); - rx.hdr_len = rx.remaining; + h4->rx.remaining = sizeof(h4->rx.evt); + h4->rx.hdr_len = h4->rx.remaining; break; case BT_HCI_H4_ACL: - rx.remaining = sizeof(rx.acl); - rx.hdr_len = rx.remaining; + h4->rx.remaining = sizeof(h4->rx.acl); + h4->rx.hdr_len = h4->rx.remaining; break; case BT_HCI_H4_ISO: if (IS_ENABLED(CONFIG_BT_ISO)) { - rx.remaining = sizeof(rx.iso); - rx.hdr_len = rx.remaining; + h4->rx.remaining = sizeof(h4->rx.iso); + h4->rx.hdr_len = h4->rx.remaining; break; } __fallthrough; default: - LOG_ERR("Unknown H:4 type 0x%02x", rx.type); - rx.type = BT_HCI_H4_NONE; + LOG_ERR("Unknown H:4 type 0x%02x", h4->rx.type); + h4->rx.type = BT_HCI_H4_NONE; } } -static void h4_read_hdr(void) +static void h4_read_hdr(const struct device *dev) { - int bytes_read = rx.hdr_len - rx.remaining; + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; + int bytes_read = h4->rx.hdr_len - h4->rx.remaining; int ret; - ret = uart_fifo_read(h4_dev, rx.hdr + bytes_read, rx.remaining); + ret = uart_fifo_read(cfg->uart, h4->rx.hdr + bytes_read, h4->rx.remaining); if (unlikely(ret < 0)) { LOG_ERR("Unable to read from UART (ret %d)", ret); } else { - rx.remaining -= ret; + h4->rx.remaining -= ret; } } -static inline void get_acl_hdr(void) +static inline void get_acl_hdr(const struct device *dev) { - h4_read_hdr(); + struct h4_data *h4 = dev->data; - if (!rx.remaining) { - struct bt_hci_acl_hdr *hdr = &rx.acl; + h4_read_hdr(dev); - rx.remaining = sys_le16_to_cpu(hdr->len); - LOG_DBG("Got ACL header. Payload %u bytes", rx.remaining); - rx.have_hdr = true; + if (!h4->rx.remaining) { + struct bt_hci_acl_hdr *hdr = &h4->rx.acl; + + h4->rx.remaining = sys_le16_to_cpu(hdr->len); + LOG_DBG("Got ACL header. Payload %u bytes", h4->rx.remaining); + h4->rx.have_hdr = true; } } -static inline void get_iso_hdr(void) +static inline void get_iso_hdr(const struct device *dev) { - h4_read_hdr(); + struct h4_data *h4 = dev->data; + + h4_read_hdr(dev); - if (!rx.remaining) { - struct bt_hci_iso_hdr *hdr = &rx.iso; + if (!h4->rx.remaining) { + struct bt_hci_iso_hdr *hdr = &h4->rx.iso; - rx.remaining = bt_iso_hdr_len(sys_le16_to_cpu(hdr->len)); - LOG_DBG("Got ISO header. Payload %u bytes", rx.remaining); - rx.have_hdr = true; + h4->rx.remaining = bt_iso_hdr_len(sys_le16_to_cpu(hdr->len)); + LOG_DBG("Got ISO header. Payload %u bytes", h4->rx.remaining); + h4->rx.have_hdr = true; } } -static inline void get_evt_hdr(void) +static inline void get_evt_hdr(const struct device *dev) { - struct bt_hci_evt_hdr *hdr = &rx.evt; + struct h4_data *h4 = dev->data; + + struct bt_hci_evt_hdr *hdr = &h4->rx.evt; - h4_read_hdr(); + h4_read_hdr(dev); - if (rx.hdr_len == sizeof(*hdr) && rx.remaining < sizeof(*hdr)) { - switch (rx.evt.evt) { + if (h4->rx.hdr_len == sizeof(*hdr) && h4->rx.remaining < sizeof(*hdr)) { + switch (h4->rx.evt.evt) { case BT_HCI_EVT_LE_META_EVENT: - rx.remaining++; - rx.hdr_len++; + h4->rx.remaining++; + h4->rx.hdr_len++; break; #if defined(CONFIG_BT_CLASSIC) case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: - rx.discardable = true; + h4->rx.discardable = true; break; #endif } } - if (!rx.remaining) { - if (rx.evt.evt == BT_HCI_EVT_LE_META_EVENT && - (rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { + if (!h4->rx.remaining) { + if (h4->rx.evt.evt == BT_HCI_EVT_LE_META_EVENT && + (h4->rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT)) { LOG_DBG("Marking adv report as discardable"); - rx.discardable = true; + h4->rx.discardable = true; } - rx.remaining = hdr->len - (rx.hdr_len - sizeof(*hdr)); + h4->rx.remaining = hdr->len - (h4->rx.hdr_len - sizeof(*hdr)); LOG_DBG("Got event header. Payload %u bytes", hdr->len); - rx.have_hdr = true; + h4->rx.have_hdr = true; } } -static inline void copy_hdr(struct net_buf *buf) +static inline void copy_hdr(struct h4_data *h4) { - net_buf_add_mem(buf, rx.hdr, rx.hdr_len); + net_buf_add_mem(h4->rx.buf, h4->rx.hdr, h4->rx.hdr_len); } -static void reset_rx(void) +static void reset_rx(struct h4_data *h4) { - rx.type = BT_HCI_H4_NONE; - rx.remaining = 0U; - rx.have_hdr = false; - rx.hdr_len = 0U; - rx.discardable = false; + h4->rx.type = BT_HCI_H4_NONE; + h4->rx.remaining = 0U; + h4->rx.have_hdr = false; + h4->rx.hdr_len = 0U; + h4->rx.discardable = false; } -static struct net_buf *get_rx(k_timeout_t timeout) +static struct net_buf *get_rx(struct h4_data *h4, k_timeout_t timeout) { - LOG_DBG("type 0x%02x, evt 0x%02x", rx.type, rx.evt.evt); + LOG_DBG("type 0x%02x, evt 0x%02x", h4->rx.type, h4->rx.evt.evt); - switch (rx.type) { + switch (h4->rx.type) { case BT_HCI_H4_EVT: - return bt_buf_get_evt(rx.evt.evt, rx.discardable, timeout); + return bt_buf_get_evt(h4->rx.evt.evt, h4->rx.discardable, timeout); case BT_HCI_H4_ACL: return bt_buf_get_rx(BT_BUF_ACL_IN, timeout); case BT_HCI_H4_ISO: @@ -205,42 +220,44 @@ static struct net_buf *get_rx(k_timeout_t timeout) static void rx_thread(void *p1, void *p2, void *p3) { + const struct device *dev = p1; + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; struct net_buf *buf; - ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); LOG_DBG("started"); while (1) { - LOG_DBG("rx.buf %p", rx.buf); + LOG_DBG("rx.buf %p", h4->rx.buf); /* We can only do the allocation if we know the initial * header, since Command Complete/Status events must use the * original command buffer (if available). */ - if (rx.have_hdr && !rx.buf) { - rx.buf = get_rx(K_FOREVER); - LOG_DBG("Got rx.buf %p", rx.buf); - if (rx.remaining > net_buf_tailroom(rx.buf)) { + if (h4->rx.have_hdr && !h4->rx.buf) { + h4->rx.buf = get_rx(h4, K_FOREVER); + LOG_DBG("Got rx.buf %p", h4->rx.buf); + if (h4->rx.remaining > net_buf_tailroom(h4->rx.buf)) { LOG_ERR("Not enough space in buffer"); - rx.discard = rx.remaining; - reset_rx(); + h4->rx.discard = h4->rx.remaining; + reset_rx(h4); } else { - copy_hdr(rx.buf); + copy_hdr(h4); } } /* Let the ISR continue receiving new packets */ - uart_irq_rx_enable(h4_dev); + uart_irq_rx_enable(cfg->uart); - buf = net_buf_get(&rx.fifo, K_FOREVER); + buf = net_buf_get(&h4->rx.fifo, K_FOREVER); do { - uart_irq_rx_enable(h4_dev); + uart_irq_rx_enable(cfg->uart); LOG_DBG("Calling bt_recv(%p)", buf); - bt_recv(buf); + h4->recv(dev, buf); /* Give other threads a chance to run if the ISR * is receiving data so fast that rx.fifo never @@ -248,8 +265,8 @@ static void rx_thread(void *p1, void *p2, void *p3) */ k_yield(); - uart_irq_rx_disable(h4_dev); - buf = net_buf_get(&rx.fifo, K_NO_WAIT); + uart_irq_rx_disable(cfg->uart); + buf = net_buf_get(&h4->rx.fifo, K_NO_WAIT); } while (buf); } } @@ -268,87 +285,93 @@ static size_t h4_discard(const struct device *uart, size_t len) return err; } -static inline void read_payload(void) +static inline void read_payload(const struct device *dev) { + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; struct net_buf *buf; int read; - if (!rx.buf) { + if (!h4->rx.buf) { size_t buf_tailroom; - rx.buf = get_rx(K_NO_WAIT); - if (!rx.buf) { - if (rx.discardable) { - LOG_WRN("Discarding event 0x%02x", rx.evt.evt); - rx.discard = rx.remaining; - reset_rx(); + h4->rx.buf = get_rx(h4, K_NO_WAIT); + if (!h4->rx.buf) { + if (h4->rx.discardable) { + LOG_WRN("Discarding event 0x%02x", h4->rx.evt.evt); + h4->rx.discard = h4->rx.remaining; + reset_rx(h4); return; } LOG_WRN("Failed to allocate, deferring to rx_thread"); - uart_irq_rx_disable(h4_dev); + uart_irq_rx_disable(cfg->uart); return; } - LOG_DBG("Allocated rx.buf %p", rx.buf); + LOG_DBG("Allocated rx.buf %p", h4->rx.buf); - buf_tailroom = net_buf_tailroom(rx.buf); - if (buf_tailroom < rx.remaining) { - LOG_ERR("Not enough space in buffer %u/%zu", rx.remaining, buf_tailroom); - rx.discard = rx.remaining; - reset_rx(); + buf_tailroom = net_buf_tailroom(h4->rx.buf); + if (buf_tailroom < h4->rx.remaining) { + LOG_ERR("Not enough space in buffer %u/%zu", h4->rx.remaining, + buf_tailroom); + h4->rx.discard = h4->rx.remaining; + reset_rx(h4); return; } - copy_hdr(rx.buf); + copy_hdr(h4); } - read = uart_fifo_read(h4_dev, net_buf_tail(rx.buf), rx.remaining); + read = uart_fifo_read(cfg->uart, net_buf_tail(h4->rx.buf), h4->rx.remaining); if (unlikely(read < 0)) { LOG_ERR("Failed to read UART (err %d)", read); return; } - net_buf_add(rx.buf, read); - rx.remaining -= read; + net_buf_add(h4->rx.buf, read); + h4->rx.remaining -= read; - LOG_DBG("got %d bytes, remaining %u", read, rx.remaining); - LOG_DBG("Payload (len %u): %s", rx.buf->len, bt_hex(rx.buf->data, rx.buf->len)); + LOG_DBG("got %d bytes, remaining %u", read, h4->rx.remaining); + LOG_DBG("Payload (len %u): %s", h4->rx.buf->len, + bt_hex(h4->rx.buf->data, h4->rx.buf->len)); - if (rx.remaining) { + if (h4->rx.remaining) { return; } - buf = rx.buf; - rx.buf = NULL; + buf = h4->rx.buf; + h4->rx.buf = NULL; - if (rx.type == BT_HCI_H4_EVT) { + if (h4->rx.type == BT_HCI_H4_EVT) { bt_buf_set_type(buf, BT_BUF_EVT); } else { bt_buf_set_type(buf, BT_BUF_ACL_IN); } - reset_rx(); + reset_rx(h4); LOG_DBG("Putting buf %p to rx fifo", buf); - net_buf_put(&rx.fifo, buf); + net_buf_put(&h4->rx.fifo, buf); } -static inline void read_header(void) +static inline void read_header(const struct device *dev) { - switch (rx.type) { + struct h4_data *h4 = dev->data; + + switch (h4->rx.type) { case BT_HCI_H4_NONE: - h4_get_type(); + h4_get_type(dev); return; case BT_HCI_H4_EVT: - get_evt_hdr(); + get_evt_hdr(dev); break; case BT_HCI_H4_ACL: - get_acl_hdr(); + get_acl_hdr(dev); break; case BT_HCI_H4_ISO: if (IS_ENABLED(CONFIG_BT_ISO)) { - get_iso_hdr(); + get_iso_hdr(dev); break; } __fallthrough; @@ -357,41 +380,43 @@ static inline void read_header(void) return; } - if (rx.have_hdr && rx.buf) { - if (rx.remaining > net_buf_tailroom(rx.buf)) { + if (h4->rx.have_hdr && h4->rx.buf) { + if (h4->rx.remaining > net_buf_tailroom(h4->rx.buf)) { LOG_ERR("Not enough space in buffer"); - rx.discard = rx.remaining; - reset_rx(); + h4->rx.discard = h4->rx.remaining; + reset_rx(h4); } else { - copy_hdr(rx.buf); + copy_hdr(h4); } } } -static inline void process_tx(void) +static inline void process_tx(const struct device *dev) { + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; int bytes; - if (!tx.buf) { - tx.buf = net_buf_get(&tx.fifo, K_NO_WAIT); - if (!tx.buf) { + if (!h4->tx.buf) { + h4->tx.buf = net_buf_get(&h4->tx.fifo, K_NO_WAIT); + if (!h4->tx.buf) { LOG_ERR("TX interrupt but no pending buffer!"); - uart_irq_tx_disable(h4_dev); + uart_irq_tx_disable(cfg->uart); return; } } - if (!tx.type) { - switch (bt_buf_get_type(tx.buf)) { + if (!h4->tx.type) { + switch (bt_buf_get_type(h4->tx.buf)) { case BT_BUF_ACL_OUT: - tx.type = BT_HCI_H4_ACL; + h4->tx.type = BT_HCI_H4_ACL; break; case BT_BUF_CMD: - tx.type = BT_HCI_H4_CMD; + h4->tx.type = BT_HCI_H4_CMD; break; case BT_BUF_ISO_OUT: if (IS_ENABLED(CONFIG_BT_ISO)) { - tx.type = BT_HCI_H4_ISO; + h4->tx.type = BT_HCI_H4_ISO; break; } __fallthrough; @@ -400,73 +425,79 @@ static inline void process_tx(void) goto done; } - bytes = uart_fifo_fill(h4_dev, &tx.type, 1); + bytes = uart_fifo_fill(cfg->uart, &h4->tx.type, 1); if (bytes != 1) { LOG_WRN("Unable to send H:4 type"); - tx.type = BT_HCI_H4_NONE; + h4->tx.type = BT_HCI_H4_NONE; return; } } - bytes = uart_fifo_fill(h4_dev, tx.buf->data, tx.buf->len); + bytes = uart_fifo_fill(cfg->uart, h4->tx.buf->data, h4->tx.buf->len); if (unlikely(bytes < 0)) { LOG_ERR("Unable to write to UART (err %d)", bytes); } else { - net_buf_pull(tx.buf, bytes); + net_buf_pull(h4->tx.buf, bytes); } - if (tx.buf->len) { + if (h4->tx.buf->len) { return; } done: - tx.type = BT_HCI_H4_NONE; - net_buf_unref(tx.buf); - tx.buf = net_buf_get(&tx.fifo, K_NO_WAIT); - if (!tx.buf) { - uart_irq_tx_disable(h4_dev); + h4->tx.type = BT_HCI_H4_NONE; + net_buf_unref(h4->tx.buf); + h4->tx.buf = net_buf_get(&h4->tx.fifo, K_NO_WAIT); + if (!h4->tx.buf) { + uart_irq_tx_disable(cfg->uart); } } -static inline void process_rx(void) +static inline void process_rx(const struct device *dev) { - LOG_DBG("remaining %u discard %u have_hdr %u rx.buf %p len %u", rx.remaining, rx.discard, - rx.have_hdr, rx.buf, rx.buf ? rx.buf->len : 0); + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; + + LOG_DBG("remaining %u discard %u have_hdr %u rx.buf %p len %u", + h4->rx.remaining, h4->rx.discard, h4->rx.have_hdr, h4->rx.buf, + h4->rx.buf ? h4->rx.buf->len : 0); - if (rx.discard) { - rx.discard -= h4_discard(h4_dev, rx.discard); + if (h4->rx.discard) { + h4->rx.discard -= h4_discard(cfg->uart, h4->rx.discard); return; } - if (rx.have_hdr) { - read_payload(); + if (h4->rx.have_hdr) { + read_payload(dev); } else { - read_header(); + read_header(dev); } } -static void bt_uart_isr(const struct device *unused, void *user_data) +static void bt_uart_isr(const struct device *uart, void *user_data) { - ARG_UNUSED(unused); - ARG_UNUSED(user_data); + struct device *dev = user_data; - while (uart_irq_update(h4_dev) && uart_irq_is_pending(h4_dev)) { - if (uart_irq_tx_ready(h4_dev)) { - process_tx(); + while (uart_irq_update(uart) && uart_irq_is_pending(uart)) { + if (uart_irq_tx_ready(uart)) { + process_tx(dev); } - if (uart_irq_rx_ready(h4_dev)) { - process_rx(); + if (uart_irq_rx_ready(uart)) { + process_rx(dev); } } } -static int h4_send(struct net_buf *buf) +static int h4_send(const struct device *dev, struct net_buf *buf) { + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; + LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); - net_buf_put(&tx.fifo, buf); - uart_irq_tx_enable(h4_dev); + net_buf_put(&h4->tx.fifo, buf); + uart_irq_tx_enable(cfg->uart); return 0; } @@ -477,32 +508,36 @@ static int h4_send(struct net_buf *buf) * * @return 0 on success, negative error value on failure */ -int __weak bt_hci_transport_setup(const struct device *dev) +int __weak bt_hci_transport_setup(const struct device *uart) { - h4_discard(h4_dev, 32); + h4_discard(uart, 32); return 0; } -static int h4_open(void) +static int h4_open(const struct device *dev, bt_hci_recv_t recv) { + const struct h4_config *cfg = dev->config; + struct h4_data *h4 = dev->data; int ret; k_tid_t tid; LOG_DBG(""); - uart_irq_rx_disable(h4_dev); - uart_irq_tx_disable(h4_dev); + uart_irq_rx_disable(cfg->uart); + uart_irq_tx_disable(cfg->uart); - ret = bt_hci_transport_setup(h4_dev); + ret = bt_hci_transport_setup(cfg->uart); if (ret < 0) { return -EIO; } - uart_irq_callback_set(h4_dev, bt_uart_isr); + h4->recv = recv; + + uart_irq_callback_user_data_set(cfg->uart, bt_uart_isr, (void *)dev); - tid = k_thread_create(&rx_thread_data, rx_thread_stack, - K_KERNEL_STACK_SIZEOF(rx_thread_stack), - rx_thread, NULL, NULL, NULL, + tid = k_thread_create(cfg->rx_thread, cfg->rx_thread_stack, + cfg->rx_thread_stack_size, + rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT); k_thread_name_set(tid, "bt_rx_thread"); @@ -511,8 +546,10 @@ static int h4_open(void) } #if defined(CONFIG_BT_HCI_SETUP) -static int h4_setup(const struct bt_hci_setup_params *params) +static int h4_setup(const struct device *dev, const struct bt_hci_setup_params *params) { + const struct h4_config *cfg = dev->config; + ARG_UNUSED(params); /* Extern bt_h4_vnd_setup function. @@ -523,30 +560,36 @@ static int h4_setup(const struct bt_hci_setup_params *params) */ extern int bt_h4_vnd_setup(const struct device *dev); - return bt_h4_vnd_setup(h4_dev); + return bt_h4_vnd_setup(cfg->uart); } #endif -static const struct bt_hci_driver drv = { - .name = "H:4", - .bus = BT_HCI_DRIVER_BUS_UART, - .open = h4_open, - .send = h4_send, +static const struct bt_hci_driver_api h4_driver_api = { + .open = h4_open, + .send = h4_send, #if defined(CONFIG_BT_HCI_SETUP) - .setup = h4_setup + .setup = h4_setup, #endif }; -static int bt_uart_init(void) -{ - - if (!device_is_ready(h4_dev)) { - return -ENODEV; - } - - bt_hci_driver_register(&drv); - - return 0; -} - -SYS_INIT(bt_uart_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#define BT_UART_DEVICE_INIT(inst) \ + static K_KERNEL_STACK_DEFINE(rx_thread_stack_##inst, CONFIG_BT_DRV_RX_STACK_SIZE); \ + static struct k_thread rx_thread_##inst; \ + static const struct h4_config h4_config_##inst = { \ + .uart = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .rx_thread_stack = rx_thread_stack_##inst, \ + .rx_thread_stack_size = K_KERNEL_STACK_SIZEOF(rx_thread_stack_##inst), \ + .rx_thread = &rx_thread_##inst, \ + }; \ + static struct h4_data h4_data_##inst = { \ + .rx = { \ + .fifo = Z_FIFO_INITIALIZER(h4_data_##inst.rx.fifo), \ + }, \ + .tx = { \ + .fifo = Z_FIFO_INITIALIZER(h4_data_##inst.tx.fifo), \ + }, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &h4_data_##inst, &h4_config_##inst, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &h4_driver_api) + +DT_INST_FOREACH_STATUS_OKAY(BT_UART_DEVICE_INIT) diff --git a/drivers/bluetooth/hci/cyw43xxx.c b/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c similarity index 99% rename from drivers/bluetooth/hci/cyw43xxx.c rename to drivers/bluetooth/hci/h4_ifx_cyw43xxx.c index 8da6192610dbe5..252b40129d7ad2 100644 --- a/drivers/bluetooth/hci/cyw43xxx.c +++ b/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c @@ -25,11 +25,11 @@ LOG_MODULE_REGISTER(cyw43xxx_driver); #include -BUILD_ASSERT(DT_PROP(DT_CHOSEN(zephyr_bt_uart), hw_flow_control) == 1, - "hw_flow_control must be enabled for HCI H4 UART"); - #define DT_DRV_COMPAT infineon_cyw43xxx_bt_hci +BUILD_ASSERT(DT_PROP(DT_INST_GPARENT(0), hw_flow_control) == 1, + "hw_flow_control must be enabled for HCI H4 UART"); + /* BT settling time after power on */ #define BT_POWER_ON_SETTLING_TIME_MS (500u) diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index 25a3b3e28f622e..0be22f61f888f7 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -17,11 +17,13 @@ #include #include #include +#include +#include #include #include #include -#include +#include #include "../util.h" @@ -29,14 +31,7 @@ #include LOG_MODULE_REGISTER(bt_driver); -static K_KERNEL_STACK_DEFINE(tx_stack, CONFIG_BT_DRV_TX_STACK_SIZE); -static K_KERNEL_STACK_DEFINE(rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE); - -static struct k_thread tx_thread_data; -static struct k_thread rx_thread_data; - -static struct k_work_delayable ack_work; -static struct k_work_delayable retx_work; +#define DT_DRV_COMPAT zephyr_bt_hci_3wire_uart #define HCI_3WIRE_ACK_PKT 0x00 #define HCI_COMMAND_PKT 0x01 @@ -86,13 +81,21 @@ static bool reliable_packet(uint8_t type) #define H5_SET_LEN(hdr, len) (((hdr)[1] |= ((len) & 0x0f) << 4), \ ((hdr)[2] |= (len) >> 4)) -static struct h5 { +struct h5_data { + /* Needed for delayed work callbacks */ + const struct device *dev; + + bt_hci_recv_t recv; + struct net_buf *rx_buf; struct k_fifo tx_queue; struct k_fifo rx_queue; struct k_fifo unack_queue; + struct k_work_delayable ack_work; + struct k_work_delayable retx_work; + uint8_t tx_win; uint8_t tx_ack; uint8_t tx_seq; @@ -111,9 +114,21 @@ static struct h5 { PAYLOAD, END, } rx_state; -} h5; -static uint8_t unack_queue_len; + uint8_t unack_queue_len; +}; + +struct h5_config { + const struct device *uart; + + k_thread_stack_t *rx_stack; + size_t rx_stack_size; + struct k_thread *rx_thread; + + k_thread_stack_t *tx_stack; + size_t tx_stack_size; + struct k_thread *tx_thread; +}; static const uint8_t sync_req[] = { 0x01, 0x7e }; static const uint8_t sync_rsp[] = { 0x02, 0x7d }; @@ -123,23 +138,21 @@ static const uint8_t conf_rsp[] = { 0x04, 0x7b }; /* H5 signal buffers pool */ #define MAX_SIG_LEN 3 -#define SIGNAL_COUNT 2 +#define SIGNAL_COUNT (2 * DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)) #define SIG_BUF_SIZE (BT_BUF_RESERVE + MAX_SIG_LEN) NET_BUF_POOL_DEFINE(h5_pool, SIGNAL_COUNT, SIG_BUF_SIZE, 0, NULL); -static const struct device *const h5_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_uart)); - -static void h5_reset_rx(void) +static void h5_reset_rx(struct h5_data *h5) { - if (h5.rx_buf) { - net_buf_unref(h5.rx_buf); - h5.rx_buf = NULL; + if (h5->rx_buf) { + net_buf_unref(h5->rx_buf); + h5->rx_buf = NULL; } - h5.rx_state = START; + h5->rx_state = START; } -static int h5_unslip_byte(uint8_t *byte) +static int h5_unslip_byte(const struct device *uart, uint8_t *byte) { int count; @@ -148,7 +161,7 @@ static int h5_unslip_byte(uint8_t *byte) } do { - count = uart_fifo_read(h5_dev, byte, sizeof(*byte)); + count = uart_fifo_read(uart, byte, sizeof(*byte)); } while (!count); switch (*byte) { @@ -166,20 +179,20 @@ static int h5_unslip_byte(uint8_t *byte) return 0; } -static void process_unack(void) +static void process_unack(struct h5_data *h5) { - uint8_t next_seq = h5.tx_seq; - uint8_t number_removed = unack_queue_len; + uint8_t next_seq = h5->tx_seq; + uint8_t number_removed = h5->unack_queue_len; - if (!unack_queue_len) { + if (!h5->unack_queue_len) { return; } - LOG_DBG("rx_ack %u tx_ack %u tx_seq %u unack_queue_len %u", h5.rx_ack, h5.tx_ack, h5.tx_seq, - unack_queue_len); + LOG_DBG("rx_ack %u tx_ack %u tx_seq %u unack_queue_len %u", h5->rx_ack, h5->tx_ack, + h5->tx_seq, h5->unack_queue_len); - while (unack_queue_len > 0) { - if (next_seq == h5.rx_ack) { + while (h5->unack_queue_len > 0) { + if (next_seq == h5->rx_ack) { /* Next sequence number is the same as last received * ack number */ @@ -191,15 +204,15 @@ static void process_unack(void) next_seq = (next_seq - 1) & 0x07; } - if (next_seq != h5.rx_ack) { - LOG_ERR("Wrong sequence: rx_ack %u tx_seq %u next_seq %u", h5.rx_ack, h5.tx_seq, - next_seq); + if (next_seq != h5->rx_ack) { + LOG_ERR("Wrong sequence: rx_ack %u tx_seq %u next_seq %u", h5->rx_ack, + h5->tx_seq, next_seq); } LOG_DBG("Need to remove %u packet from the queue", number_removed); while (number_removed) { - struct net_buf *buf = net_buf_get(&h5.unack_queue, K_NO_WAIT); + struct net_buf *buf = net_buf_get(&h5->unack_queue, K_NO_WAIT); if (!buf) { LOG_ERR("Unack queue is empty"); @@ -210,7 +223,7 @@ static void process_unack(void) LOG_DBG("Remove buf from the unack_queue"); net_buf_unref(buf); - unack_queue_len--; + h5->unack_queue_len--; number_removed--; } } @@ -261,25 +274,27 @@ static void hexdump(const char *str, const uint8_t *packet, size_t length) #define hexdump(str, packet, length) #endif -static uint8_t h5_slip_byte(uint8_t byte) +static uint8_t h5_slip_byte(const struct device *uart, uint8_t byte) { switch (byte) { case SLIP_DELIMITER: - uart_poll_out(h5_dev, SLIP_ESC); - uart_poll_out(h5_dev, SLIP_ESC_DELIM); + uart_poll_out(uart, SLIP_ESC); + uart_poll_out(uart, SLIP_ESC_DELIM); return 2; case SLIP_ESC: - uart_poll_out(h5_dev, SLIP_ESC); - uart_poll_out(h5_dev, SLIP_ESC_ESC); + uart_poll_out(uart, SLIP_ESC); + uart_poll_out(uart, SLIP_ESC_ESC); return 2; default: - uart_poll_out(h5_dev, byte); + uart_poll_out(uart, byte); return 1; } } -static void h5_send(const uint8_t *payload, uint8_t type, int len) +static void h5_send(const struct device *dev, const uint8_t *payload, uint8_t type, int len) { + const struct h5_config *cfg = dev->config; + struct h5_data *h5 = dev->data; uint8_t hdr[4]; int i; @@ -288,14 +303,14 @@ static void h5_send(const uint8_t *payload, uint8_t type, int len) (void)memset(hdr, 0, sizeof(hdr)); /* Set ACK for outgoing packet and stop delayed work */ - H5_SET_ACK(hdr, h5.tx_ack); + H5_SET_ACK(hdr, h5->tx_ack); /* If cancel fails we may ack the same seq number twice, this is OK. */ - (void)k_work_cancel_delayable(&ack_work); + (void)k_work_cancel_delayable(&h5->ack_work); if (reliable_packet(type)) { H5_SET_RELIABLE(hdr); - H5_SET_SEQ(hdr, h5.tx_seq); - h5.tx_seq = (h5.tx_seq + 1) % 8; + H5_SET_SEQ(hdr, h5->tx_seq); + h5->tx_seq = (h5->tx_seq + 1) % 8; } H5_SET_TYPE(hdr, type); @@ -306,97 +321,100 @@ static void h5_send(const uint8_t *payload, uint8_t type, int len) h5_print_header(hdr, "TX: <"); - uart_poll_out(h5_dev, SLIP_DELIMITER); + uart_poll_out(cfg->uart, SLIP_DELIMITER); for (i = 0; i < 4; i++) { - h5_slip_byte(hdr[i]); + h5_slip_byte(cfg->uart, hdr[i]); } for (i = 0; i < len; i++) { - h5_slip_byte(payload[i]); + h5_slip_byte(cfg->uart, payload[i]); } - uart_poll_out(h5_dev, SLIP_DELIMITER); + uart_poll_out(cfg->uart, SLIP_DELIMITER); } /* Delayed work taking care about retransmitting packets */ static void retx_timeout(struct k_work *work) { - ARG_UNUSED(work); + struct k_work_delayable *delayable = k_work_delayable_from_work(work); + struct h5_data *h5 = CONTAINER_OF(delayable, struct h5_data, retx_work); - LOG_DBG("unack_queue_len %u", unack_queue_len); + LOG_DBG("unack_queue_len %u", h5->unack_queue_len); - if (unack_queue_len) { + if (h5->unack_queue_len) { struct k_fifo tmp_queue; struct net_buf *buf; k_fifo_init(&tmp_queue); /* Queue to temporary queue */ - while ((buf = net_buf_get(&h5.tx_queue, K_NO_WAIT))) { + while ((buf = net_buf_get(&h5->tx_queue, K_NO_WAIT))) { net_buf_put(&tmp_queue, buf); } /* Queue unack packets to the beginning of the queue */ - while ((buf = net_buf_get(&h5.unack_queue, K_NO_WAIT))) { + while ((buf = net_buf_get(&h5->unack_queue, K_NO_WAIT))) { /* include also packet type */ net_buf_push(buf, sizeof(uint8_t)); - net_buf_put(&h5.tx_queue, buf); - h5.tx_seq = (h5.tx_seq - 1) & 0x07; - unack_queue_len--; + net_buf_put(&h5->tx_queue, buf); + h5->tx_seq = (h5->tx_seq - 1) & 0x07; + h5->unack_queue_len--; } /* Queue saved packets from temp queue */ while ((buf = net_buf_get(&tmp_queue, K_NO_WAIT))) { - net_buf_put(&h5.tx_queue, buf); + net_buf_put(&h5->tx_queue, buf); } } } static void ack_timeout(struct k_work *work) { - ARG_UNUSED(work); + struct k_work_delayable *delayable = k_work_delayable_from_work(work); + struct h5_data *h5 = CONTAINER_OF(delayable, struct h5_data, ack_work); LOG_DBG(""); - h5_send(NULL, HCI_3WIRE_ACK_PKT, 0); + h5_send(h5->dev, NULL, HCI_3WIRE_ACK_PKT, 0); } -static void h5_process_complete_packet(uint8_t *hdr) +static void h5_process_complete_packet(const struct device *dev, uint8_t *hdr) { + struct h5_data *h5 = dev->data; struct net_buf *buf; LOG_DBG(""); /* rx_ack should be in every packet */ - h5.rx_ack = H5_HDR_ACK(hdr); + h5->rx_ack = H5_HDR_ACK(hdr); if (reliable_packet(H5_HDR_PKT_TYPE(hdr))) { /* For reliable packet increment next transmit ack number */ - h5.tx_ack = (h5.tx_ack + 1) % 8; + h5->tx_ack = (h5->tx_ack + 1) % 8; /* Submit delayed work to ack the packet */ - k_work_reschedule(&ack_work, H5_RX_ACK_TIMEOUT); + k_work_reschedule(&h5->ack_work, H5_RX_ACK_TIMEOUT); } h5_print_header(hdr, "RX: >"); - process_unack(); + process_unack(h5); - buf = h5.rx_buf; - h5.rx_buf = NULL; + buf = h5->rx_buf; + h5->rx_buf = NULL; switch (H5_HDR_PKT_TYPE(hdr)) { case HCI_3WIRE_ACK_PKT: net_buf_unref(buf); break; case HCI_3WIRE_LINK_PKT: - net_buf_put(&h5.rx_queue, buf); + net_buf_put(&h5->rx_queue, buf); break; case HCI_EVENT_PKT: case HCI_ACLDATA_PKT: case HCI_ISODATA_PKT: hexdump("=> ", buf->data, buf->len); - bt_recv(buf); + h5->recv(dev, buf); break; } } @@ -406,22 +424,21 @@ static inline struct net_buf *get_evt_buf(uint8_t evt) return bt_buf_get_evt(evt, false, K_NO_WAIT); } -static void bt_uart_isr(const struct device *unused, void *user_data) +static void bt_uart_isr(const struct device *uart, void *user_data) { + const struct device *dev = user_data; + struct h5_data *h5 = dev->data; static int remaining; uint8_t byte; int ret; static uint8_t hdr[4]; size_t buf_tailroom; - ARG_UNUSED(unused); - ARG_UNUSED(user_data); - - while (uart_irq_update(h5_dev) && - uart_irq_is_pending(h5_dev)) { + while (uart_irq_update(uart) && + uart_irq_is_pending(uart)) { - if (!uart_irq_rx_ready(h5_dev)) { - if (uart_irq_tx_ready(h5_dev)) { + if (!uart_irq_rx_ready(uart)) { + if (uart_irq_tx_ready(uart)) { LOG_DBG("transmit ready"); } else { LOG_DBG("spurious interrupt"); @@ -430,15 +447,15 @@ static void bt_uart_isr(const struct device *unused, void *user_data) break; } - ret = uart_fifo_read(h5_dev, &byte, sizeof(byte)); + ret = uart_fifo_read(uart, &byte, sizeof(byte)); if (!ret) { continue; } - switch (h5.rx_state) { + switch (h5->rx_state) { case START: if (byte == SLIP_DELIMITER) { - h5.rx_state = HEADER; + h5->rx_state = HEADER; remaining = sizeof(hdr); } break; @@ -451,8 +468,8 @@ static void bt_uart_isr(const struct device *unused, void *user_data) continue; } - if (h5_unslip_byte(&byte) < 0) { - h5_reset_rx(); + if (h5_unslip_byte(uart, &byte) < 0) { + h5_reset_rx(h5); continue; } @@ -470,86 +487,85 @@ static void bt_uart_isr(const struct device *unused, void *user_data) /* The buffer is allocated only once we know * the exact event type. */ - h5.rx_state = PAYLOAD; + h5->rx_state = PAYLOAD; break; case HCI_ACLDATA_PKT: - h5.rx_buf = bt_buf_get_rx(BT_BUF_ACL_IN, - K_NO_WAIT); - if (!h5.rx_buf) { + h5->rx_buf = bt_buf_get_rx(BT_BUF_ACL_IN, + K_NO_WAIT); + if (!h5->rx_buf) { LOG_WRN("No available data buffers"); - h5_reset_rx(); + h5_reset_rx(h5); continue; } - h5.rx_state = PAYLOAD; + h5->rx_state = PAYLOAD; break; case HCI_ISODATA_PKT: - h5.rx_buf = bt_buf_get_rx(BT_BUF_ISO_IN, - K_NO_WAIT); - if (!h5.rx_buf) { + h5->rx_buf = bt_buf_get_rx(BT_BUF_ISO_IN, K_NO_WAIT); + if (!h5->rx_buf) { LOG_WRN("No available data buffers"); - h5_reset_rx(); + h5_reset_rx(h5); continue; } - h5.rx_state = PAYLOAD; + h5->rx_state = PAYLOAD; break; case HCI_3WIRE_LINK_PKT: case HCI_3WIRE_ACK_PKT: - h5.rx_buf = net_buf_alloc(&h5_pool, K_NO_WAIT); - if (!h5.rx_buf) { + h5->rx_buf = net_buf_alloc(&h5_pool, K_NO_WAIT); + if (!h5->rx_buf) { LOG_WRN("No available signal buffers"); - h5_reset_rx(); + h5_reset_rx(h5); continue; } - h5.rx_state = PAYLOAD; + h5->rx_state = PAYLOAD; break; default: LOG_ERR("Wrong packet type %u", H5_HDR_PKT_TYPE(hdr)); - h5.rx_state = END; + h5->rx_state = END; break; } if (!remaining) { - h5.rx_state = END; + h5->rx_state = END; } break; case PAYLOAD: - if (h5_unslip_byte(&byte) < 0) { - h5_reset_rx(); + if (h5_unslip_byte(uart, &byte) < 0) { + h5_reset_rx(h5); continue; } /* Allocate HCI event buffer now that we know the * exact event type. */ - if (!h5.rx_buf) { - h5.rx_buf = get_evt_buf(byte); - if (!h5.rx_buf) { + if (!h5->rx_buf) { + h5->rx_buf = get_evt_buf(byte); + if (!h5->rx_buf) { LOG_WRN("No available event buffers"); - h5_reset_rx(); + h5_reset_rx(h5); continue; } } - buf_tailroom = net_buf_tailroom(h5.rx_buf); + buf_tailroom = net_buf_tailroom(h5->rx_buf); if (buf_tailroom < sizeof(byte)) { LOG_ERR("Not enough space in buffer %zu/%zu", sizeof(byte), buf_tailroom); - h5_reset_rx(); + h5_reset_rx(h5); break; } - net_buf_add_mem(h5.rx_buf, &byte, sizeof(byte)); + net_buf_add_mem(h5->rx_buf, &byte, sizeof(byte)); remaining--; if (!remaining) { - h5.rx_state = END; + h5->rx_state = END; } break; case END: if (byte != SLIP_DELIMITER) { LOG_ERR("Missing ending SLIP_DELIMITER"); - h5_reset_rx(); + h5_reset_rx(h5); break; } @@ -560,15 +576,15 @@ static void bt_uart_isr(const struct device *unused, void *user_data) * full packet anyway to clear UART. */ if (H5_HDR_RELIABLE(hdr) && - H5_HDR_SEQ(hdr) != h5.tx_ack) { - LOG_ERR("Seq expected %u got %u. Drop packet", h5.tx_ack, + H5_HDR_SEQ(hdr) != h5->tx_ack) { + LOG_ERR("Seq expected %u got %u. Drop packet", h5->tx_ack, H5_HDR_SEQ(hdr)); - h5_reset_rx(); + h5_reset_rx(h5); break; } - h5_process_complete_packet(hdr); - h5.rx_state = START; + h5_process_complete_packet(dev, hdr); + h5->rx_state = START; break; } } @@ -579,8 +595,9 @@ static uint8_t h5_get_type(struct net_buf *buf) return net_buf_pull_u8(buf); } -static int h5_queue(struct net_buf *buf) +static int h5_queue(const struct device *dev, struct net_buf *buf) { + struct h5_data *h5 = dev->data; uint8_t type; LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); @@ -602,29 +619,31 @@ static int h5_queue(struct net_buf *buf) memcpy(net_buf_push(buf, sizeof(type)), &type, sizeof(type)); - net_buf_put(&h5.tx_queue, buf); + net_buf_put(&h5->tx_queue, buf); return 0; } static void tx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct h5_data *h5 = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); LOG_DBG(""); /* FIXME: make periodic sending */ - h5_send(sync_req, HCI_3WIRE_LINK_PKT, sizeof(sync_req)); + h5_send(dev, sync_req, HCI_3WIRE_LINK_PKT, sizeof(sync_req)); while (true) { struct net_buf *buf; uint8_t type; - LOG_DBG("link_state %u", h5.link_state); + LOG_DBG("link_state %u", h5->link_state); - switch (h5.link_state) { + switch (h5->link_state) { case UNINIT: /* FIXME: send sync */ k_sleep(K_MSEC(100)); @@ -634,32 +653,34 @@ static void tx_thread(void *p1, void *p2, void *p3) k_sleep(K_MSEC(100)); break; case ACTIVE: - buf = net_buf_get(&h5.tx_queue, K_FOREVER); + buf = net_buf_get(&h5->tx_queue, K_FOREVER); type = h5_get_type(buf); - h5_send(buf->data, type, buf->len); + h5_send(dev, buf->data, type, buf->len); /* buf is dequeued from tx_queue and queued to unack * queue. */ - net_buf_put(&h5.unack_queue, buf); - unack_queue_len++; + net_buf_put(&h5->unack_queue, buf); + h5->unack_queue_len++; - k_work_reschedule(&retx_work, H5_TX_ACK_TIMEOUT); + k_work_reschedule(&h5->retx_work, H5_TX_ACK_TIMEOUT); break; } } } -static void h5_set_txwin(uint8_t *conf) +static void h5_set_txwin(struct h5_data *h5, uint8_t *conf) { - conf[2] = h5.tx_win & 0x07; + conf[2] = h5->tx_win & 0x07; } static void rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct h5_data *h5 = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -668,42 +689,42 @@ static void rx_thread(void *p1, void *p2, void *p3) while (true) { struct net_buf *buf; - buf = net_buf_get(&h5.rx_queue, K_FOREVER); + buf = net_buf_get(&h5->rx_queue, K_FOREVER); hexdump("=> ", buf->data, buf->len); if (!memcmp(buf->data, sync_req, sizeof(sync_req))) { - if (h5.link_state == ACTIVE) { + if (h5->link_state == ACTIVE) { /* TODO Reset H5 */ } - h5_send(sync_rsp, HCI_3WIRE_LINK_PKT, sizeof(sync_rsp)); + h5_send(dev, sync_rsp, HCI_3WIRE_LINK_PKT, sizeof(sync_rsp)); } else if (!memcmp(buf->data, sync_rsp, sizeof(sync_rsp))) { - if (h5.link_state == ACTIVE) { + if (h5->link_state == ACTIVE) { /* TODO Reset H5 */ } - h5.link_state = INIT; - h5_set_txwin(conf_req); - h5_send(conf_req, HCI_3WIRE_LINK_PKT, sizeof(conf_req)); + h5->link_state = INIT; + h5_set_txwin(h5, conf_req); + h5_send(dev, conf_req, HCI_3WIRE_LINK_PKT, sizeof(conf_req)); } else if (!memcmp(buf->data, conf_req, 2)) { /* * The Host sends Config Response messages without a * Configuration Field. */ - h5_send(conf_rsp, HCI_3WIRE_LINK_PKT, sizeof(conf_rsp)); + h5_send(dev, conf_rsp, HCI_3WIRE_LINK_PKT, sizeof(conf_rsp)); /* Then send Config Request with Configuration Field */ - h5_set_txwin(conf_req); - h5_send(conf_req, HCI_3WIRE_LINK_PKT, sizeof(conf_req)); + h5_set_txwin(h5, conf_req); + h5_send(dev, conf_req, HCI_3WIRE_LINK_PKT, sizeof(conf_req)); } else if (!memcmp(buf->data, conf_rsp, 2)) { - h5.link_state = ACTIVE; + h5->link_state = ACTIVE; if (buf->len > 2) { /* Configuration field present */ - h5.tx_win = (buf->data[2] & 0x07); + h5->tx_win = (buf->data[2] & 0x07); } - LOG_DBG("Finished H5 configuration, tx_win %u", h5.tx_win); + LOG_DBG("Finished H5 configuration, tx_win %u", h5->tx_win); } else { LOG_ERR("Not handled yet %x %x", buf->data[0], buf->data[1]); } @@ -717,74 +738,91 @@ static void rx_thread(void *p1, void *p2, void *p3) } } -static void h5_init(void) +static void h5_init(const struct device *dev) { + const struct h5_config *cfg = dev->config; + struct h5_data *h5 = dev->data; + k_tid_t tid; + LOG_DBG(""); - h5.link_state = UNINIT; - h5.rx_state = START; - h5.tx_win = 4U; + h5->link_state = UNINIT; + h5->rx_state = START; + h5->tx_win = 4U; /* TX thread */ - k_fifo_init(&h5.tx_queue); - k_thread_create(&tx_thread_data, tx_stack, - K_KERNEL_STACK_SIZEOF(tx_stack), - tx_thread, NULL, NULL, NULL, - K_PRIO_COOP(CONFIG_BT_HCI_TX_PRIO), - 0, K_NO_WAIT); - k_thread_name_set(&tx_thread_data, "tx_thread"); - - k_fifo_init(&h5.rx_queue); - k_thread_create(&rx_thread_data, rx_stack, - K_KERNEL_STACK_SIZEOF(rx_stack), - rx_thread, NULL, NULL, NULL, - K_PRIO_COOP(CONFIG_BT_RX_PRIO), - 0, K_NO_WAIT); - k_thread_name_set(&rx_thread_data, "rx_thread"); + k_fifo_init(&h5->tx_queue); + tid = k_thread_create(cfg->tx_thread, cfg->tx_stack, cfg->tx_stack_size, + tx_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_BT_HCI_TX_PRIO), + 0, K_NO_WAIT); + k_thread_name_set(tid, "tx_thread"); + + k_fifo_init(&h5->rx_queue); + tid = k_thread_create(cfg->rx_thread, cfg->rx_stack, cfg->rx_stack_size, + rx_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_BT_RX_PRIO), + 0, K_NO_WAIT); + k_thread_name_set(tid, "rx_thread"); /* Unack queue */ - k_fifo_init(&h5.unack_queue); + k_fifo_init(&h5->unack_queue); /* Init delayed work */ - k_work_init_delayable(&ack_work, ack_timeout); - k_work_init_delayable(&retx_work, retx_timeout); + k_work_init_delayable(&h5->ack_work, ack_timeout); + k_work_init_delayable(&h5->retx_work, retx_timeout); } -static int h5_open(void) +static int h5_open(const struct device *dev, bt_hci_recv_t recv) { + const struct h5_config *cfg = dev->config; + struct h5_data *h5 = dev->data; + LOG_DBG(""); - uart_irq_rx_disable(h5_dev); - uart_irq_tx_disable(h5_dev); + /* This is needed so that we can access the device struct from within the + * delayed work callbacks. + */ + h5->dev = dev; - bt_uart_drain(h5_dev); + h5->recv = recv; - uart_irq_callback_set(h5_dev, bt_uart_isr); + uart_irq_rx_disable(cfg->uart); + uart_irq_tx_disable(cfg->uart); - h5_init(); + bt_uart_drain(cfg->uart); - uart_irq_rx_enable(h5_dev); + uart_irq_callback_user_data_set(cfg->uart, bt_uart_isr, (void *)dev); - return 0; -} + h5_init(dev); -static const struct bt_hci_driver drv = { - .name = "H:5", - .bus = BT_HCI_DRIVER_BUS_UART, - .open = h5_open, - .send = h5_queue, -}; - -static int bt_uart_init(void) -{ - - if (!device_is_ready(h5_dev)) { - return -ENODEV; - } - - bt_hci_driver_register(&drv); + uart_irq_rx_enable(cfg->uart); return 0; } -SYS_INIT(bt_uart_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +static const struct bt_hci_driver_api h5_driver_api = { + .open = h5_open, + .send = h5_queue, +}; + +#define BT_UART_DEVICE_INIT(inst) \ + static K_KERNEL_STACK_DEFINE(rx_thread_stack_##inst, CONFIG_BT_DRV_RX_STACK_SIZE); \ + static struct k_thread rx_thread_##inst; \ + static K_KERNEL_STACK_DEFINE(tx_thread_stack_##inst, CONFIG_BT_DRV_TX_STACK_SIZE); \ + static struct k_thread tx_thread_##inst; \ + static const struct h5_config h5_config_##inst = { \ + .uart = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .rx_stack = rx_thread_stack_##inst, \ + .rx_stack_size = K_KERNEL_STACK_SIZEOF(rx_thread_stack_##inst), \ + .rx_thread = &rx_thread_##inst, \ + .tx_stack = tx_thread_stack_##inst, \ + .tx_stack_size = K_KERNEL_STACK_SIZEOF(tx_thread_stack_##inst), \ + .tx_thread = &tx_thread_##inst, \ + }; \ + static struct h5_data h5_##inst; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &h5_##inst, &h5_config_##inst, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &h5_driver_api) + + +DT_INST_FOREACH_STATUS_OKAY(BT_UART_DEVICE_INIT) diff --git a/drivers/bluetooth/hci/hci_ambiq.c b/drivers/bluetooth/hci/hci_ambiq.c index 9428594980d661..34a2360a2c21f2 100644 --- a/drivers/bluetooth/hci/hci_ambiq.c +++ b/drivers/bluetooth/hci/hci_ambiq.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL @@ -72,6 +72,10 @@ static const struct spi_buf_set spi_rx = {.buffers = &spi_rx_buf, .count = 1}; static K_SEM_DEFINE(sem_irq, 0, 1); static K_SEM_DEFINE(sem_spi_available, 1, 1); +struct bt_apollo_data { + bt_hci_recv_t recv; +}; + void bt_packet_irq_isr(const struct device *unused1, struct gpio_callback *unused2, uint32_t unused3) { @@ -85,6 +89,18 @@ static inline int bt_spi_transceive(void *tx, uint32_t tx_len, void *rx, uint32_ spi_tx_buf.len = (size_t)tx_len; spi_rx_buf.buf = rx; spi_rx_buf.len = (size_t)rx_len; + + /* Before sending packet to controller the host needs to poll the status of + * controller to know it's ready, or before reading packets from controller + * the host needs to get the payload size of coming packets by sending specific + * command and putting the status or size to the rx buffer, the CS should be + * held at this moment to continue to send or receive packets. + */ + if (tx_len && rx_len) { + spi_cfg.operation |= SPI_HOLD_ON_CS; + } else { + spi_cfg.operation &= ~SPI_HOLD_ON_CS; + } return spi_transceive(spi_dev, &spi_cfg, &spi_tx, &spi_rx); } @@ -276,7 +292,9 @@ static struct net_buf *bt_hci_acl_recv(uint8_t *data, size_t len) static void bt_spi_rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct bt_apollo_data *hci = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -319,13 +337,13 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3) /* Post the RX message to host stack to process */ if (buf) { - bt_recv(buf); + hci->recv(dev, buf); } } while (0); } } -static int bt_hci_send(struct net_buf *buf) +static int bt_apollo_send(const struct device *dev, struct net_buf *buf) { int ret = 0; @@ -356,8 +374,9 @@ static int bt_hci_send(struct net_buf *buf) return ret; } -static int bt_hci_open(void) +static int bt_apollo_open(const struct device *dev, bt_hci_recv_t recv) { + struct bt_apollo_data *hci = dev->data; int ret; ret = bt_hci_transport_setup(spi_dev); @@ -367,15 +386,18 @@ static int bt_hci_open(void) /* Start RX thread */ k_thread_create(&spi_rx_thread_data, spi_rx_stack, K_KERNEL_STACK_SIZEOF(spi_rx_stack), - (k_thread_entry_t)bt_spi_rx_thread, NULL, NULL, NULL, + (k_thread_entry_t)bt_spi_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); ret = bt_apollo_controller_init(spi_send_packet); + if (ret == 0) { + hci->recv = recv; + } return ret; } -static int bt_spi_setup(const struct bt_hci_setup_params *params) +static int bt_apollo_setup(const struct device *dev, const struct bt_hci_setup_params *params) { ARG_UNUSED(params); @@ -386,18 +408,18 @@ static int bt_spi_setup(const struct bt_hci_setup_params *params) return ret; } -static const struct bt_hci_driver drv = { - .name = "ambiq hci", - .bus = BT_HCI_DRIVER_BUS_SPI, - .open = bt_hci_open, - .send = bt_hci_send, - .setup = bt_spi_setup, +static const struct bt_hci_driver_api drv = { + .open = bt_apollo_open, + .send = bt_apollo_send, + .setup = bt_apollo_setup, }; -static int bt_hci_init(void) +static int bt_apollo_init(const struct device *dev) { int ret; + ARG_UNUSED(dev); + if (!device_is_ready(spi_dev)) { LOG_ERR("SPI device not ready"); return -ENODEV; @@ -408,11 +430,16 @@ static int bt_hci_init(void) return ret; } - bt_hci_driver_register(&drv); - LOG_DBG("BT HCI initialized"); return 0; } -SYS_INIT(bt_hci_init, POST_KERNEL, CONFIG_BT_HCI_INIT_PRIORITY); +#define HCI_DEVICE_INIT(inst) \ + static struct bt_apollo_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, bt_apollo_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_BT_HCI_INIT_PRIORITY, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_da1469x.c b/drivers/bluetooth/hci/hci_da1469x.c index c97b83f3b35cfd..18733d8444cdbb 100644 --- a/drivers/bluetooth/hci/hci_da1469x.c +++ b/drivers/bluetooth/hci/hci_da1469x.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,6 +26,12 @@ LOG_MODULE_REGISTER(hci_da1469x); +#define DT_DRV_COMPAT renesas_bt_hci_da1469x + +struct hci_data { + bt_hci_recv_t recv; +}; + static K_KERNEL_STACK_DEFINE(rng_thread_stack, CONFIG_BT_RX_STACK_SIZE); static struct k_thread rng_thread_data; struct k_sem rng_sem; @@ -205,9 +211,10 @@ static void rx_isr_stop(void) static void rx_thread(void *p1, void *p2, void *p3) { + const struct device *dev = p1; + struct hci_data *hci = dev->data; struct net_buf *buf; - ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -240,7 +247,7 @@ static void rx_thread(void *p1, void *p2, void *p3) rx_isr_start(); LOG_DBG("Calling bt_recv(%p)", buf); - bt_recv(buf); + hci->recv(dev, buf); /* Give other threads a chance to run if the ISR * is receiving data so fast that rx.fifo never @@ -420,13 +427,14 @@ static void rng_thread(void *p1, void *p2, void *p3) } } -static int bt_da1469x_open(void) +static int bt_da1469x_open(const struct device *dev, bt_hci_recv_t recv) { + struct hci_data *hci = dev->data; k_tid_t tid; tid = k_thread_create(&rx_thread_data, rx_thread_stack, K_KERNEL_STACK_SIZEOF(rx_thread_stack), - rx_thread, NULL, NULL, NULL, + rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT); k_thread_name_set(tid, "bt_rx_thread"); @@ -440,6 +448,8 @@ static int bt_da1469x_open(void) 0, K_NO_WAIT); k_thread_name_set(tid, "bt_rng_thread"); + hci->recv = recv; + cmac_enable(); irq_enable(CMAC2SYS_IRQn); @@ -447,17 +457,23 @@ static int bt_da1469x_open(void) } #ifdef CONFIG_BT_HCI_HOST -static int bt_da1469x_close(void) +static int bt_da1469x_close(const struct device *dev) { + struct hci_data *hci = dev->data; + irq_disable(CMAC2SYS_IRQn); cmac_disable(); + hci->recv = NULL; + return 0; } #endif /* CONFIG_BT_HCI_HOST */ -static int bt_da1469x_send(struct net_buf *buf) +static int bt_da1469x_send(const struct device *dev, struct net_buf *buf) { + ARG_UNUSED(dev); + switch (bt_buf_get_type(buf)) { case BT_BUF_ACL_OUT: LOG_DBG("ACL: buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); @@ -479,20 +495,16 @@ static int bt_da1469x_send(struct net_buf *buf) return 0; } -static const struct bt_hci_driver drv = { - .name = "BT DA1469x", - .bus = BT_HCI_DRIVER_BUS_IPM, +static const struct bt_hci_driver_api drv = { .open = bt_da1469x_open, .close = bt_da1469x_close, .send = bt_da1469x_send, }; -static int bt_da1469x_init(void) +static int bt_da1469x_init(const struct device *dev) { irq_disable(CMAC2SYS_IRQn); - bt_hci_driver_register(&drv); - cmac_disable(); cmac_load_image(); cmac_configure_pdc(); @@ -503,4 +515,11 @@ static int bt_da1469x_init(void) return 0; } -SYS_INIT(bt_da1469x_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, bt_da1469x_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_esp32.c b/drivers/bluetooth/hci/hci_esp32.c index 311dddf916c32f..7536e9f7622e91 100644 --- a/drivers/bluetooth/hci/hci_esp32.c +++ b/drivers/bluetooth/hci/hci_esp32.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -17,8 +17,14 @@ #include LOG_MODULE_REGISTER(bt_hci_driver_esp32); +#define DT_DRV_COMPAT espressif_esp32_bt_hci + #define HCI_BT_ESP32_TIMEOUT K_MSEC(2000) +struct bt_esp32_data { + bt_hci_recv_t recv; +}; + static K_SEM_DEFINE(hci_send_sem, 1, 1); static bool is_hci_event_discardable(const uint8_t *evt_data) @@ -180,6 +186,8 @@ static struct net_buf *bt_esp_iso_recv(uint8_t *data, size_t remaining) static int hci_esp_host_rcv_pkt(uint8_t *data, uint16_t len) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct bt_esp32_data *hci = dev->data; uint8_t pkt_indicator; struct net_buf *buf = NULL; size_t remaining = len; @@ -210,7 +218,7 @@ static int hci_esp_host_rcv_pkt(uint8_t *data, uint16_t len) if (buf) { LOG_DBG("Calling bt_recv(%p)", buf); - bt_recv(buf); + hci->recv(dev, buf); } return 0; @@ -226,7 +234,7 @@ static esp_vhci_host_callback_t vhci_host_cb = { hci_esp_host_rcv_pkt }; -static int bt_esp32_send(struct net_buf *buf) +static int bt_esp32_send(const struct device *dev, struct net_buf *buf) { int err = 0; uint8_t pkt_indicator; @@ -316,8 +324,9 @@ static int bt_esp32_ble_deinit(void) return 0; } -static int bt_esp32_open(void) +static int bt_esp32_open(const struct device *dev, bt_hci_recv_t recv) { + struct bt_esp32_data *hci = dev->data; int err; err = bt_esp32_ble_init(); @@ -325,13 +334,16 @@ static int bt_esp32_open(void) return err; } + hci->recv = recv; + LOG_DBG("ESP32 BT started"); return 0; } -static int bt_esp32_close(void) +static int bt_esp32_close(const struct device *dev) { + struct bt_esp32_data *hci = dev->data; int err; err = bt_esp32_ble_deinit(); @@ -339,27 +351,24 @@ static int bt_esp32_close(void) return err; } + hci->recv = NULL; + LOG_DBG("ESP32 BT stopped"); return 0; } -static const struct bt_hci_driver drv = { - .name = "BT ESP32", +static const struct bt_hci_driver_api drv = { .open = bt_esp32_open, .send = bt_esp32_send, .close = bt_esp32_close, - .bus = BT_HCI_DRIVER_BUS_IPM, -#if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE) - .quirks = BT_QUIRK_NO_AUTO_DLE, -#endif }; -static int bt_esp32_init(void) -{ - bt_hci_driver_register(&drv); - - return 0; -} +#define BT_ESP32_DEVICE_INIT(inst) \ + static struct bt_esp32_data bt_esp32_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &bt_esp32_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) -SYS_INIT(bt_esp32_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +/* Only one instance supported */ +BT_ESP32_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_ifx_cyw208xx.c b/drivers/bluetooth/hci/hci_ifx_cyw208xx.c new file mode 100644 index 00000000000000..0590b4c55755a5 --- /dev/null +++ b/drivers/bluetooth/hci/hci_ifx_cyw208xx.c @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2024 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + /** + * @brief Zephyr CYW20829 driver. + * + * This driver uses btstack-integration asset as hosts platform adaptation layer + * (porting layer) for CYW20829. btstack-integration layer implements/ + * invokes the interfaces defined by BTSTACK to to enable communication + * with the BT controller by using IPC_BTSS (IPC Bluetooth sub-system interface). + * Zephyr CYW20829 driver implements wiced_bt_**** functions requreds for + * btstack-integration asset and Zephyr Bluetooth driver interface + * (defined in struct bt_hci_driver). + * + * CM33 (application core) + * |=========================================| + * | |-------------------------| | + * | | Zephyr application | | + * | |-------------------------| | + * | | | + * | |------------| | + * | | Zephyr | | + * | | Bluetooth | | + * CM33 (BTSS core) | | Host | | + * |=====================| | |------------| | + * | | | | | + * | |---------------| | | |--------------| | -----------| | + * | | Bluetooth | | IPC_BTSS | | btstack- | | Zephyr | | + * | | Controller FW | | <--------|-> | integration | ---- | CYW20829 | | + * | |---------------| | | | asset | | driver | | + * | | | |--------------| |------------| | + * |=====================| | | + * | |=========================================| + * |====================| + * | CYW20829 | + * | Bluetooth | + * |====================| + * + * NOTE: + * cyw920829 requires fetch binary files of Bluetooth controller firmware. + * To fetch Binary Blobs: west blobs fetch hal_infineon + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(cyw208xx); + +#define DT_DRV_COMPAT infineon_cyw208xx_hci + +struct cyw208xx_data { + bt_hci_recv_t recv; +}; + +enum { + BT_HCI_VND_OP_DOWNLOAD_MINIDRIVER = 0xFC2E, + BT_HCI_VND_OP_WRITE_RAM = 0xFC4C, + BT_HCI_VND_OP_LAUNCH_RAM = 0xFC4E, + BT_HCI_VND_OP_UPDATE_BAUDRATE = 0xFC18, +}; + +/* Externs for CY43xxx controller FW */ +extern const uint8_t brcm_patchram_buf[]; +extern const int brcm_patch_ram_length; + +#define CYBSP_BT_PLATFORM_CFG_SLEEP_MODE_LP_ENABLED (1) + +static K_SEM_DEFINE(hci_sem, 1, 1); +static K_SEM_DEFINE(cybt_platform_task_init_sem, 0, 1); + + +/****************************************************************************** + * Function Declarations + ******************************************************************************/ +extern void host_stack_platform_interface_init(void); +extern void cybt_platform_hci_wait_for_boot_fully_up(bool is_from_isr); +extern uint8_t *host_stack_get_acl_to_lower_buffer(wiced_bt_transport_t transport, uint32_t size); +extern wiced_result_t host_stack_send_acl_to_lower(wiced_bt_transport_t transport, + uint8_t *data, uint16_t len); +extern wiced_result_t host_stack_send_cmd_to_lower(uint8_t *cmd, uint16_t cmd_len); +extern wiced_result_t host_stack_send_iso_to_lower(uint8_t *data, uint16_t len); +extern cybt_result_t cybt_platform_msg_to_bt_task(const uint16_t msg, bool is_from_isr); +extern void cybt_bttask_deinit(void); + +static int cyw208xx_bt_firmware_download(const uint8_t *firmware_image, uint32_t size) +{ + uint8_t *data = (uint8_t *)firmware_image; + volatile uint32_t remaining_length = size; + struct net_buf *buf; + int err; + + LOG_DBG("Executing Fw downloading for CYW208xx device"); + + /* The firmware image (.hcd format) contains a collection of hci_write_ram + * command + a block of the image, followed by a hci_write_ram image at the end. + * Parse and send each individual command and wait for the response. This is to + * ensure the integrity of the firmware image sent to the bluetooth chip. + */ + while (remaining_length) { + size_t data_length = data[2]; /* data length from firmware image block */ + uint16_t op_code = *(uint16_t *)data; + + /* Allocate buffer for hci_write_ram/hci_launch_ram command. */ + buf = bt_hci_cmd_create(op_code, data_length); + if (buf == NULL) { + LOG_ERR("Unable to allocate command buffer"); + return err; + } + + /* Add data part of packet */ + net_buf_add_mem(buf, &data[3], data_length); + + /* Send hci_write_ram command. */ + err = bt_hci_cmd_send_sync(op_code, buf, NULL); + if (err) { + return err; + } + + switch (op_code) { + case BT_HCI_VND_OP_WRITE_RAM: + /* Update remaining length and data pointer: + * content of data length + 2 bytes of opcode and 1 byte of data length. + */ + data += data_length + 3; + remaining_length -= data_length + 3; + break; + + case BT_HCI_VND_OP_LAUNCH_RAM: + remaining_length = 0; + break; + + default: + return -ENOMEM; + } + } + + LOG_DBG("Fw downloading complete"); + return 0; +} + +static int cyw208xx_setup(const struct device *dev, const struct bt_hci_setup_params *params) +{ + ARG_UNUSED(dev); + ARG_UNUSED(params); + int err; + + /* Send HCI_RESET */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL); + if (err) { + return err; + } + + /* BT firmware download */ + err = cyw208xx_bt_firmware_download(brcm_patchram_buf, (uint32_t)brcm_patch_ram_length); + if (err) { + return err; + } + + /* Waiting when BLE up after firmware launch */ + cybt_platform_hci_wait_for_boot_fully_up(false); + return 0; +} + +static int cyw208xx_open(const struct device *dev, bt_hci_recv_t recv) +{ + int err; + struct cyw208xx_data *hci = dev->data; + + hci->recv = recv; + + /* Initialize Bluetooth platform related OS tasks. */ + err = cybt_platform_task_init((void *)NULL); + if (err) { + return err; + } + + /* Wait until cybt platform task starts */ + k_sem_take(&cybt_platform_task_init_sem, K_FOREVER); + + return 0; +} + +static int cyw208xx_close(const struct device *dev) +{ + struct cyw208xx_data *hci = dev->data; + + /* Send SHUTDOWN event, BT task will release resources and tervinate task */ + cybt_platform_msg_to_bt_task(BT_EVT_TASK_SHUTDOWN, false); + + cybt_bttask_deinit(); + + k_sem_reset(&cybt_platform_task_init_sem); + hci->recv = NULL; + + return 0; +} + +static int cyw208xx_send(const struct device *dev, struct net_buf *buf) +{ + ARG_UNUSED(dev); + + int ret = 0; + + k_sem_take(&hci_sem, K_FOREVER); + + LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + uint8_t *bt_msg = host_stack_get_acl_to_lower_buffer(BT_TRANSPORT_LE, buf->len); + + memcpy(bt_msg, buf->data, buf->len); + ret = host_stack_send_acl_to_lower(BT_TRANSPORT_LE, bt_msg, buf->len); + break; + + case BT_BUF_CMD: + ret = host_stack_send_cmd_to_lower(buf->data, buf->len); + break; + + case BT_BUF_ISO_OUT: + ret = host_stack_send_iso_to_lower(buf->data, buf->len); + break; + + default: + LOG_ERR("Unknown type %u", bt_buf_get_type(buf)); + ret = EIO; + goto done; + } + + LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:"); + + if (ret) { + LOG_ERR("SPI write error %d", ret); + } + +done: + k_sem_give(&hci_sem); + net_buf_unref(buf); + return ret ? -EIO : 0; +} + +static const struct bt_hci_driver_api drv = { + .open = cyw208xx_open, + .close = cyw208xx_close, + .send = cyw208xx_send, + .setup = cyw208xx_setup +}; + +static int cyw208xx_hci_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + const cybt_platform_config_t cybsp_bt_platform_cfg = { + .hci_config = { + .hci_transport = CYBT_HCI_IPC, + }, + + .controller_config = { + .sleep_mode = { + .sleep_mode_enabled = CYBSP_BT_PLATFORM_CFG_SLEEP_MODE_LP_ENABLED, + }, + } + }; + + /* Configure platform specific settings for the BT device */ + cybt_platform_config_init(&cybsp_bt_platform_cfg); + + return 0; +} + +/* Implements wiced_bt_**** functions requreds for the btstack-integration asset */ + +wiced_result_t wiced_bt_dev_vendor_specific_command(uint16_t opcode, uint8_t param_len, + uint8_t *param_buf, wiced_bt_dev_vendor_specific_command_complete_cback_t cback) + +{ + /* + * This function is using only by btstack-integration asset + * for enable LPM. + */ + struct net_buf *buf = NULL; + + /* Allocate a HCI command buffer */ + buf = bt_hci_cmd_create(opcode, param_len); + if (!buf) { + LOG_ERR("Unable to allocate buffer"); + return WICED_NO_MEMORY; + } + + /* Add data part of packet */ + net_buf_add_mem(buf, param_buf, param_len); + bt_hci_cmd_send(opcode, buf); + + return WICED_BT_SUCCESS; +} + +void wiced_bt_process_hci(hci_packet_type_t pti, uint8_t *data, uint32_t length) +{ + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct cyw208xx_data *hci = dev->data; + struct net_buf *buf = NULL; + size_t buf_tailroom = 0; + + switch (pti) { + case HCI_PACKET_TYPE_EVENT: + buf = bt_buf_get_evt(data[0], 0, K_NO_WAIT); + if (!buf) { + LOG_ERR("Failed to allocate the buffer for RX: EVENT "); + return; + } + break; + + case HCI_PACKET_TYPE_ACL: + buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT); + if (!buf) { + LOG_ERR("Failed to allocate the buffer for RX: ACL "); + return; + } + bt_buf_set_type(buf, BT_BUF_ACL_IN); + break; + + case HCI_PACKET_TYPE_SCO: + /* NA */ + break; + + case HCI_PACKET_TYPE_ISO: + buf = bt_buf_get_rx(BT_BUF_ISO_IN, K_NO_WAIT); + if (!buf) { + LOG_ERR("Failed to allocate the buffer for RX: ISO "); + return; + } + break; + + default: + return; + + } + + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < length) { + LOG_WRN("Not enough space for rx data"); + return; + } + net_buf_add_mem(buf, data, length); + + /* Provide the buffer to the host */ + hci->recv(dev, buf); +} + +void wiced_bt_process_hci_events(uint8_t *data, uint32_t length) +{ + wiced_bt_process_hci(HCI_PACKET_TYPE_EVENT, data, length); +} + +void wiced_bt_process_acl_data(uint8_t *data, uint32_t length) +{ + wiced_bt_process_hci(HCI_PACKET_TYPE_ACL, data, length); +} + +void wiced_bt_process_isoc_data(uint8_t *data, uint32_t length) +{ + wiced_bt_process_hci(HCI_PACKET_TYPE_ISO, data, length); +} + +void wiced_bt_stack_init_internal(wiced_bt_management_cback_t mgmt_cback, + wiced_bt_internal_post_stack_init_cb post_stack_cb, + wiced_bt_internal_stack_evt_handler_cb evt_handler_cb) +{ + k_sem_give(&cybt_platform_task_init_sem); +} + +/* Keep below empty functions, used in the btstack_integration assets for Wiced BT stack. */ +void wiced_bt_stack_indicate_lower_tx_complete(void) +{ + /* NA for Zephyr */ +} + +void wiced_bt_stack_shutdown(void) +{ + /* NA for Zephyr */ +} + +void wiced_bt_process_timer(void) +{ + /* NA for Zephyr */ +} + +#define CYW208XX_DEVICE_INIT(inst) \ + static struct cyw208xx_data cyw208xx_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, cyw208xx_hci_init, NULL, &cyw208xx_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported */ +CYW208XX_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_psoc6_bless.c b/drivers/bluetooth/hci/hci_ifx_psoc6_bless.c similarity index 84% rename from drivers/bluetooth/hci/hci_psoc6_bless.c rename to drivers/bluetooth/hci/hci_ifx_psoc6_bless.c index af6804f2f17596..5f4d1fdd13dddc 100644 --- a/drivers/bluetooth/hci/hci_psoc6_bless.c +++ b/drivers/bluetooth/hci/hci_ifx_psoc6_bless.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,6 +32,10 @@ LOG_MODULE_REGISTER(psoc6_bless); #define DT_DRV_COMPAT infineon_cat1_bless_hci +struct psoc6_bless_data { + bt_hci_recv_t recv; +}; + #define BLE_LOCK_TMOUT_MS (1000) #define BLE_THREAD_SEM_TMOUT_MS (1000) @@ -94,6 +98,8 @@ static void psoc6_bless_isr_handler(const struct device *dev) static void psoc6_bless_events_handler(uint32_t eventCode, void *eventParam) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct psoc6_bless_data *hci = dev->data; cy_stc_ble_hci_tx_packet_info_t *hci_rx = NULL; struct net_buf *buf = NULL; size_t buf_tailroom = 0; @@ -135,13 +141,16 @@ static void psoc6_bless_events_handler(uint32_t eventCode, void *eventParam) return; } net_buf_add_mem(buf, hci_rx->data, hci_rx->dataLength); - bt_recv(buf); + hci->recv(dev, buf); } -static int psoc6_bless_open(void) +static int psoc6_bless_open(const struct device *dev, bt_hci_recv_t recv) { + struct psoc6_bless_data *hci = dev->data; k_tid_t tid; + hci->recv = recv; + tid = k_thread_create(&psoc6_bless_rx_thread_data, psoc6_bless_rx_thread_stack, K_KERNEL_STACK_SIZEOF(psoc6_bless_rx_thread_stack), psoc6_bless_rx_thread, NULL, NULL, NULL, @@ -151,10 +160,12 @@ static int psoc6_bless_open(void) return 0; } -static int psoc6_bless_send(struct net_buf *buf) +static int psoc6_bless_send(const struct device *dev, struct net_buf *buf) { cy_en_ble_api_result_t result; + ARG_UNUSED(dev); + memset(&hci_tx_pkt, 0, sizeof(cy_stc_ble_hci_tx_packet_info_t)); hci_tx_pkt.dataLength = buf->len; @@ -190,8 +201,9 @@ static int psoc6_bless_send(struct net_buf *buf) return 0; } -static int psoc6_bless_setup(const struct bt_hci_setup_params *params) +static int psoc6_bless_setup(const struct device *dev, const struct bt_hci_setup_params *params) { + ARG_UNUSED(dev); ARG_UNUSED(params); struct net_buf *buf; int err; @@ -217,17 +229,11 @@ static int psoc6_bless_setup(const struct bt_hci_setup_params *params) return 0; } -static int psoc6_bless_hci_init(void) +static int psoc6_bless_hci_init(const struct device *dev) { cy_en_ble_api_result_t result; - static const struct bt_hci_driver drv = { - .name = "PSoC 6 BLESS", - .bus = BT_HCI_DRIVER_BUS_VIRTUAL, - .quirks = BT_QUIRK_NO_RESET, - .open = psoc6_bless_open, - .send = psoc6_bless_send, - .setup = psoc6_bless_setup, - }; + + ARG_UNUSED(dev); /* Connect BLE interrupt to ISR */ IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), psoc6_bless_isr_handler, 0, 0); @@ -252,10 +258,20 @@ static int psoc6_bless_hci_init(void) /* Enables BLE Low-power mode (LPM)*/ Cy_BLE_EnableLowPowerMode(); - /* Register a BLESS HCI driver to the Bluetooth stack. */ - bt_hci_driver_register(&drv); - return 0; } -SYS_INIT(psoc6_bless_hci_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +static const struct bt_hci_driver_api drv = { + .open = psoc6_bless_open, + .send = psoc6_bless_send, + .setup = psoc6_bless_setup, +}; + +#define PSOC6_BLESS_DEVICE_INIT(inst) \ + static struct psoc6_bless_data psoc6_bless_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, psoc6_bless_hci_init, NULL, &psoc6_bless_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported */ +PSOC6_BLESS_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_nxp.c b/drivers/bluetooth/hci/hci_nxp.c index 78016a794b5fd8..ff9d9628c16074 100644 --- a/drivers/bluetooth/hci/hci_nxp.c +++ b/drivers/bluetooth/hci/hci_nxp.c @@ -9,7 +9,7 @@ /* -------------------------------------------------------------------------- */ #include -#include +#include #include #include #include @@ -26,6 +26,10 @@ #define DT_DRV_COMPAT nxp_hci_ble +struct bt_nxp_data { + bt_hci_recv_t recv; +}; + #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL LOG_MODULE_REGISTER(bt_driver); @@ -244,6 +248,8 @@ static struct net_buf *bt_acl_recv(uint8_t *data, size_t len) static void hci_rx_cb(uint8_t packetType, uint8_t *data, uint16_t len) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct bt_nxp_data *hci = dev->data; struct net_buf *buf; switch (packetType) { @@ -262,14 +268,16 @@ static void hci_rx_cb(uint8_t packetType, uint8_t *data, uint16_t len) if (buf) { /* Provide the buffer to the host */ - bt_recv(buf); + hci->recv(dev, buf); } } -static int bt_nxp_send(struct net_buf *buf) +static int bt_nxp_send(const struct device *dev, struct net_buf *buf) { uint8_t packetType; + ARG_UNUSED(dev); + switch (bt_buf_get_type(buf)) { case BT_BUF_CMD: packetType = BT_HCI_H4_CMD; @@ -290,8 +298,9 @@ static int bt_nxp_send(struct net_buf *buf) return 0; } -static int bt_nxp_open(void) +static int bt_nxp_open(const struct device *dev, bt_hci_recv_t recv) { + struct bt_nxp_data *hci = dev->data; int ret = 0; do { @@ -313,6 +322,20 @@ static int bt_nxp_open(void) break; } + hci->recv = recv; + } while (false); + + return ret; +} + +int bt_nxp_setup(const struct device *dev, const struct bt_hci_setup_params *params) +{ + ARG_UNUSED(dev); + ARG_UNUSED(params); + + int ret; + + do { #if CONFIG_HCI_NXP_SET_CAL_DATA ret = bt_nxp_set_calibration_data(); if (ret < 0) { @@ -345,14 +368,15 @@ static int bt_nxp_open(void) LOG_ERR("Failed to configure controller autosleep"); break; } -#endif +#endif /* CONFIG_HCI_NXP_ENABLE_AUTO_SLEEP */ } while (false); return ret; } -static int bt_nxp_close(void) +static int bt_nxp_close(const struct device *dev) { + struct bt_nxp_data *hci = dev->data; int ret = 0; /* Reset the Controller */ #if CONFIG_BT_HCI_HOST @@ -367,22 +391,25 @@ static int bt_nxp_close(void) LOG_ERR("Failed to shutdown BLE controller"); } #endif + hci->recv = NULL; + return ret; } -static const struct bt_hci_driver drv = { - .name = "BT NXP", +static const struct bt_hci_driver_api drv = { .open = bt_nxp_open, + .setup = bt_nxp_setup, .close = bt_nxp_close, .send = bt_nxp_send, - .bus = BT_HCI_DRIVER_BUS_IPM, }; -static int bt_nxp_init(void) +static int bt_nxp_init(const struct device *dev) { int status; int ret = 0; + ARG_UNUSED(dev); + /* HCI Interrupt */ IRQ_CONNECT(HCI_IRQ_N, HCI_IRQ_P, ble_hci_handler, 0, 0); irq_enable(HCI_IRQ_N); @@ -402,16 +429,16 @@ static int bt_nxp_init(void) ret = status; break; } - - status = bt_hci_driver_register(&drv); - if (status < 0) { - LOG_ERR("HCI driver registration failed"); - ret = status; - break; - } } while (0); return ret; } -SYS_INIT(bt_nxp_init, POST_KERNEL, CONFIG_BT_HCI_INIT_PRIORITY); +#define HCI_DEVICE_INIT(inst) \ + static struct bt_nxp_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, bt_nxp_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_BT_HCI_INIT_PRIORITY, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_nxp_setup.c b/drivers/bluetooth/hci/hci_nxp_setup.c new file mode 100644 index 00000000000000..b3cc0e18c6f2c3 --- /dev/null +++ b/drivers/bluetooth/hci/hci_nxp_setup.c @@ -0,0 +1,1177 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_nxp_ctlr); + +#include "common/bt_str.h" + +#include "bt_nxp_ctlr_fw.h" + +#define DT_DRV_COMPAT nxp_bt_hci_uart + +#define FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT 6 + +static const struct device *uart_dev = DEVICE_DT_GET(DT_INST_GPARENT(0)); + +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) +struct gpio_dt_spec sdio_reset = GPIO_DT_SPEC_GET(DT_DRV_INST(0), sdio_reset_gpios); +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */ +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) +struct gpio_dt_spec w_disable = GPIO_DT_SPEC_GET(DT_DRV_INST(0), w_disable_gpios); +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */ + +struct nxp_ctlr_dev_data { + uint32_t primary_speed; + bool primary_flowcontrol; + uint32_t secondary_speed; + bool secondary_flowcontrol; +}; + +static struct nxp_ctlr_dev_data uart_dev_data; + +#define DI 0x07U +#define POLYNOMIAL 0x04c11db7UL + +#define CRC32_LEN 4 + +static unsigned long crc_table[256U]; +static bool made_table; + +static void fw_upload_gen_crc32_table(void) +{ + int i, j; + unsigned long crc_accum; + + for (i = 0; i < 256; i++) { + crc_accum = ((unsigned long)i << 24); + for (j = 0; j < 8; j++) { + if (crc_accum & 0x80000000L) { + crc_accum = (crc_accum << 1) ^ POLYNOMIAL; + } else { + crc_accum = (crc_accum << 1); + } + } + crc_table[i] = crc_accum; + } +} + +static unsigned char fw_upload_crc8(unsigned char *array, unsigned char len) +{ + unsigned char crc_8 = 0xff; + + crc_8 = crc8(array, len, DI, crc_8, false); + + return crc_8; +} + +static unsigned long fw_upload_update_crc32(unsigned long crc_accum, char *data_blk_ptr, + int data_blk_size) +{ + unsigned int i, j; + + for (j = 0; j < data_blk_size; j++) { + i = ((unsigned int)(crc_accum >> 24) ^ *data_blk_ptr++) & 0xff; + crc_accum = (crc_accum << 8) ^ crc_table[i]; + } + return crc_accum; +} + +#define CMD4 0x4U +#define CMD6 0x6U +#define CMD7 0x7U + +#define V1_HEADER_DATA_REQ 0xa5U +#define V1_START_INDICATION 0xaaU +#define V1_REQUEST_ACK 0x5aU + +#define V3_START_INDICATION 0xabU +#define V3_HEADER_DATA_REQ 0xa7U +#define V3_REQUEST_ACK 0x7aU +#define V3_TIMEOUT_ACK 0x7bU +#define V3_CRC_ERROR 0x7cU + +#define REQ_HEADER_LEN 1U +#define A6REQ_PAYLOAD_LEN 8U +#define AbREQ_PAYLOAD_LEN 3U + +#define CRC_ERR_BIT BIT(0) +#define NAK_REC_BIT BIT(1) +#define TIMEOUT_REC_ACK_BIT BIT(2) +#define TIMEOUT_REC_HEAD_BIT BIT(3) +#define TIMEOUT_REC_DATA_BIT BIT(4) +#define INVALID_CMD_REC_BIT BIT(5) +#define WIFI_MIC_FAIL_BIT BIT(6) +#define BT_MIC_FAIL_BIT BIT(7) + +#define CMD_HDR_LEN 16 + +/* CMD5 Header to change bootloader baud rate */ +static uint8_t cmd5_hdrData[CMD_HDR_LEN] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x77, 0xdb, 0xfd, 0xe0}; +/* CMD7 Header to change timeout of bootloader */ +static uint8_t cmd7_hdrData[CMD_HDR_LEN] = {0x07, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x88, 0xf8, 0xba}; + +enum bt_nxp_ctlr_version { + VER1 = 1, + VER2, + VER3, +}; + +struct change_speed_config { + uint32_t clk_div_addr; + uint32_t clk_div_val; + uint32_t uart_clk_div_addr; + uint32_t uart_clk_div_val; + uint32_t mcr_addr; + uint32_t mcr_val; + uint32_t reinit_addr; + uint32_t reinit_val; + uint32_t icr_addr; + uint32_t icr_val; + uint32_t fcr_addr; + uint32_t fcr_val; +}; + +#define SEND_BUFFER_MAX_LENGTH 0xFFFFU /* Maximum 2 byte value */ +#define RECV_RING_BUFFER_LENGTH 1024 + +struct nxp_ctlr_fw_upload_state { + uint8_t version; + uint8_t hdr_sig; + + uint8_t buffer[A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN + 1]; + + uint8_t send_buffer[SEND_BUFFER_MAX_LENGTH + 1]; + + struct { + uint8_t buffer[RECV_RING_BUFFER_LENGTH]; + uint32_t head; + uint32_t tail; + struct k_sem sem; + } rx; + + uint16_t length; + uint32_t offset; + uint16_t error; + uint8_t crc8; + + uint32_t last_offset; + uint8_t change_speed_buffer[sizeof(struct change_speed_config) + CRC32_LEN]; + + uint32_t fw_length; + uint32_t current_length; + const uint8_t *fw; + + uint32_t cmd7_change_timeout_len; + uint32_t change_speed_buffer_len; + + bool wait_hdr_sig; + + bool is_hdr_data; + bool is_error_case; + bool is_cmd7_req; + bool is_entry_point_req; + + uint8_t last_5bytes_buffer[6]; +}; + +static struct nxp_ctlr_fw_upload_state fw_upload; + +static int fw_upload_read_data(uint8_t *buffer, uint32_t len) +{ + int err; + + while (len > 0) { + err = k_sem_take(&fw_upload.rx.sem, + K_MSEC(CONFIG_BT_H4_NXP_CTLR_WAIT_HDR_SIG_TIMEOUT)); + if (err < 0) { + LOG_ERR("Fail to read data"); + return err; + } + *buffer = fw_upload.rx.buffer[fw_upload.rx.tail]; + buffer++; + fw_upload.rx.tail++; + fw_upload.rx.tail = fw_upload.rx.tail % sizeof(fw_upload.rx.buffer); + len--; + } + return 0; +} + +static void fw_upload_read_to_clear(void) +{ + uint32_t key; + + key = irq_lock(); + k_sem_reset(&fw_upload.rx.sem); + fw_upload.rx.head = 0; + fw_upload.rx.tail = 0; + irq_unlock(key); +} + +static int fw_upload_wait_for_hdr_sig(void) +{ + int err; + int64_t end; + char c; + + end = k_uptime_get() + CONFIG_BT_H4_NXP_CTLR_WAIT_HDR_SIG_TIMEOUT; + fw_upload.hdr_sig = 0xFF; + + while (k_uptime_get() < end) { + err = fw_upload_read_data(&c, 1); + if (err < 0) { + k_msleep(1); + continue; + } + if ((c == V1_HEADER_DATA_REQ) || (c == V1_START_INDICATION) || + (c == V3_START_INDICATION) || (c == V3_HEADER_DATA_REQ)) { + LOG_DBG("HDR SIG found 0x%02X", c); + fw_upload.hdr_sig = c; + if (fw_upload.version == 0) { + if ((c == V3_START_INDICATION) || (c == V3_HEADER_DATA_REQ)) { + fw_upload.version = VER3; + } else { + fw_upload.version = VER1; + } + } + return 0; + } + } + LOG_ERR("HDR SIG not found"); + return -EIO; +} + +static void fw_upload_write_data(const uint8_t *buffer, uint32_t len) +{ + for (int i = 0; i < len; i++) { + uart_poll_out(uart_dev, buffer[i]); + } +} + +static int fw_upload_request_check_crc(uint8_t *buffer, uint8_t request) +{ + uint8_t crc; + + if (request == V3_HEADER_DATA_REQ) { + crc = fw_upload_crc8(buffer, A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN); + if (crc != buffer[A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN]) { + LOG_ERR("Request %d, CRC check failed", request); + return -EINVAL; + } + } else if (request == V3_START_INDICATION) { + crc = fw_upload_crc8(buffer, AbREQ_PAYLOAD_LEN + REQ_HEADER_LEN); + if (crc != buffer[AbREQ_PAYLOAD_LEN + REQ_HEADER_LEN]) { + LOG_ERR("Request %d, CRC check failed", request); + return -EINVAL; + } + } else { + LOG_ERR("Invalid request %d", request); + } + + return 0; +} + +static void fw_upload_send_ack(uint8_t ack) +{ + if ((ack == V3_REQUEST_ACK) || (ack == V3_CRC_ERROR)) { + /* prepare crc for 0x7A or 0x7C */ + fw_upload.buffer[0] = ack; + fw_upload.buffer[1] = fw_upload_crc8(fw_upload.buffer, 1); + fw_upload_write_data(fw_upload.buffer, 2); + LOG_DBG("ACK = %x, CRC = %x", ack, fw_upload.buffer[1]); + } else if (ack == V3_TIMEOUT_ACK) { + /* prepare crc for 0x7B */ + fw_upload.buffer[0] = ack; + sys_put_le32(fw_upload.offset, &fw_upload.buffer[1]); + fw_upload.buffer[5] = fw_upload_crc8(fw_upload.buffer, 5); + fw_upload_write_data(fw_upload.buffer, 6); + LOG_DBG("ACK = %x, CRC = %x", ack, fw_upload.buffer[5]); + } else { + LOG_ERR("Invalid ack"); + } +} + +static int fw_upload_wait_req(bool secondary_speed) +{ + int err; + uint32_t len; + uint8_t buffer[10]; + + buffer[0] = fw_upload.hdr_sig; + if (fw_upload.hdr_sig == V3_HEADER_DATA_REQ) { + /* CMD LINE: 0xA7 */ + len = A6REQ_PAYLOAD_LEN + 1; + } else if (fw_upload.hdr_sig == V3_START_INDICATION) { + /* CMD LINE: 0xAB */ + len = AbREQ_PAYLOAD_LEN + 1; + } else { + return -EINVAL; + } + + err = fw_upload_read_data(&buffer[1], len); + if (err < 0) { + LOG_ERR("Fail to read req"); + return err; + } + + err = fw_upload_request_check_crc(buffer, fw_upload.hdr_sig); + if (err != 0) { + LOG_ERR("Fail to check CRC"); + fw_upload_send_ack(V3_CRC_ERROR); + return err; + } + + if (fw_upload.hdr_sig == V3_HEADER_DATA_REQ) { + fw_upload.length = sys_get_le16(&buffer[1]); + fw_upload.offset = sys_get_le32(&buffer[3]); + fw_upload.error = sys_get_le16(&buffer[7]); + fw_upload.crc8 = buffer[9]; + LOG_DBG("Req: %hhd, %hd, %d, %hd, %hhd", fw_upload.hdr_sig, fw_upload.length, + fw_upload.offset, fw_upload.error, fw_upload.crc8); + } else if (fw_upload.hdr_sig == V3_START_INDICATION) { + uint16_t chip_id; + + fw_upload_send_ack(V3_REQUEST_ACK); + chip_id = sys_get_le16(&buffer[1]); + LOG_DBG("Indicate: %hhd, %hd, %hhd, %hhd", fw_upload.hdr_sig, chip_id, buffer[3], + buffer[4]); + + if (!secondary_speed) { + return -EINVAL; + } + } + + return 0; +} + +static int fw_upload_change_timeout(void) +{ + int err = 0; + bool first = true; + uint8_t retry = FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT; + + LOG_DBG(""); + + fw_upload_gen_crc32_table(); + + while (true) { + err = fw_upload_wait_for_hdr_sig(); + if (err) { + continue; + } + + if (fw_upload.version == VER1) { + return 0; + } else if (fw_upload.version == VER3) { + err = fw_upload_wait_req(true); + if (err) { + continue; + } + + if (fw_upload.length == 0) { + continue; + } + + if (fw_upload.error == 0) { + if (first || (fw_upload.last_offset == fw_upload.offset)) { + fw_upload_send_ack(V3_REQUEST_ACK); + fw_upload_write_data(cmd7_hdrData, + fw_upload.length > CMD_HDR_LEN + ? CMD_HDR_LEN + : fw_upload.length); + fw_upload.last_offset = fw_upload.offset; + first = false; + } else { + fw_upload.cmd7_change_timeout_len = CMD_HDR_LEN; + fw_upload.wait_hdr_sig = false; + return 0; + } + } else { + if (retry > 0) { + retry--; + fw_upload_send_ack(V3_TIMEOUT_ACK); + } else { + LOG_ERR("Fail to change timeout with response err %d", + fw_upload.error); + return -ENOTSUP; + } + } + } else { + LOG_ERR("Unsupported version %d", fw_upload.version); + return -ENOTSUP; + } + } + + return -EINVAL; +} + +typedef struct { + uint32_t uartBaudRate; + uint32_t uartDivisio; + uint32_t uartClkDivisor; +} uart_baudrate_clkDiv_map_t; + +static const uart_baudrate_clkDiv_map_t clk_div_map[] = { + {115200U, 16U, 0x0075F6FDU}, + {1000000U, 2U, 0x00800000U}, + {3000000U, 1U, 0x00C00000U}, +}; + +static int fw_upload_change_speed_config(struct change_speed_config *config, uint32_t speed) +{ + config->clk_div_addr = 0x7f00008fU; + config->uart_clk_div_addr = 0x7f000090U; + config->mcr_addr = 0x7f000091U; + config->reinit_addr = 0x7f000092U; + config->icr_addr = 0x7f000093U; + config->fcr_addr = 0x7f000094U; + + config->mcr_val = 0x00000022U; + config->reinit_val = 0x00000001U; + config->icr_val = 0x000000c7U; + config->fcr_val = 0x000000c7U; + + for (int i = 0; i < ARRAY_SIZE(clk_div_map); i++) { + if (speed == clk_div_map[i].uartBaudRate) { + config->clk_div_val = clk_div_map[i].uartClkDivisor; + config->uart_clk_div_val = clk_div_map[i].uartDivisio; + return 0; + } + } + return -ENOTSUP; +} + +static uint16_t fw_upload_wait_length(uint8_t flag) +{ + uint8_t buffer[4]; + uint16_t len; + uint16_t len_comp; + int err; + uint8_t ack; + + err = fw_upload_read_data(buffer, sizeof(buffer)); + if (err < 0) { + return 0; + } + + len = sys_get_le16(buffer); + len_comp = sys_get_le16(buffer); + + if ((len ^ len_comp) == 0xFFFF) { + LOG_DBG("remote asks for %d bytes", len); + + /* Successful. Send back the ack. */ + if ((fw_upload.hdr_sig == V1_HEADER_DATA_REQ) || + (fw_upload.hdr_sig == V1_START_INDICATION)) { + ack = V1_REQUEST_ACK; + fw_upload_write_data(&ack, 1); + if (fw_upload.hdr_sig == V1_START_INDICATION) { + /* Eliminated longjmp(resync, 1); returning restart status */ + return (uint16_t)V1_START_INDICATION; + } + } + } else { + LOG_ERR("remote asks len %d bytes", len); + LOG_ERR("remote asks len_comp %d bytes", len_comp); + /* Failure due to mismatch. */ + ack = 0xbf; + fw_upload_write_data(&ack, 1); + /* Start all over again. */ + if (flag) { + /* Eliminated longjmp(resync, 1); returning restart status */ + return (uint16_t)V1_START_INDICATION; + } + len = 0; + } + return len; +} + +static uint32_t fw_upload_get_payload_length(uint8_t *cmd) +{ + uint32_t len; + + len = sys_get_le32(&cmd[8]); + + return len; +} + +static void fw_upload_get_hdr_start(uint8_t *buffer) +{ + int err; + bool done = false; + uint32_t count = 0; + + while (!done) { + err = fw_upload_read_data(&fw_upload.hdr_sig, 1); + if (err >= 0) { + if (fw_upload.hdr_sig == V1_HEADER_DATA_REQ) { + buffer[count++] = fw_upload.hdr_sig; + done = true; + LOG_DBG("Found header %x", fw_upload.hdr_sig); + } + } else { + LOG_ERR("Fail to read HDR sig %d", err); + return; + } + } + err = fw_upload_read_data(&buffer[count], 4); + if (err < 0) { + LOG_ERR("Fail to read HDR payload %d", err); + } +} + +static int fw_upload_len_valid(uint8_t *buffer, uint16_t *length) +{ + uint16_t len; + uint16_t len_comp; + + len = sys_get_le16(&buffer[1]); + len_comp = sys_get_le16(&buffer[3]); + + if ((len ^ len_comp) == 0xFFFFU) { + *length = len; + return 0; + } else { + return -EINVAL; + } +} + +static int fw_upload_get_last_5bytes(uint8_t *buffer) +{ + int err; + uint32_t payload_len; + uint16_t len = 0; + + memset(fw_upload.last_5bytes_buffer, 0, sizeof(fw_upload.last_5bytes_buffer)); + + fw_upload_get_hdr_start(fw_upload.last_5bytes_buffer); + err = fw_upload_len_valid(fw_upload.last_5bytes_buffer, &len); + if (err >= 0) { + LOG_DBG("Valid len %d", len); + } else { + LOG_ERR("Invalid HDR"); + return err; + } + + payload_len = fw_upload_get_payload_length(buffer); + + if ((len == CMD_HDR_LEN) || ((uint32_t)len == payload_len)) { + LOG_DBG("Len valid"); + fw_upload.is_error_case = false; + return 0; + } + + LOG_DBG("Len invalid"); + fw_upload.is_error_case = true; + + return -EINVAL; +} + +static void fw_upload_update_result(uint32_t payload_len, uint16_t *sending_len, + bool *first_chunk_sent) +{ + if (fw_upload.is_cmd7_req || fw_upload.is_entry_point_req) { + *sending_len = CMD_HDR_LEN; + *first_chunk_sent = true; + } else { + *sending_len = payload_len; + *first_chunk_sent = false; + if (*sending_len == CMD_HDR_LEN) { + fw_upload.is_hdr_data = true; + } + } +} + +static int fw_upload_write_hdr_and_payload(uint16_t len_to_send, uint8_t *buffer, bool new_speed) +{ + int err; + uint32_t payload_len; + bool send_done = false; + uint16_t sending_len = CMD_HDR_LEN; + bool first_chunk_sent = false; + + LOG_DBG(""); + + payload_len = fw_upload_get_payload_length(buffer); + + while (!send_done) { + if (sending_len == len_to_send) { + if ((sending_len == CMD_HDR_LEN) && (!fw_upload.is_hdr_data)) { + if ((first_chunk_sent == false) || + (first_chunk_sent && fw_upload.is_error_case)) { + LOG_DBG("Send first chunk: len %d", sending_len); + fw_upload_write_data(buffer, sending_len); + fw_upload_update_result(payload_len, &sending_len, + &first_chunk_sent); + } else { + send_done = true; + break; + } + } else { + LOG_DBG("Send data: len %d", sending_len); + if (sending_len) { + fw_upload_write_data(&buffer[CMD_HDR_LEN], sending_len); + first_chunk_sent = true; + sending_len = CMD_HDR_LEN; + fw_upload.is_hdr_data = false; + if (new_speed) { + return 0; + } + } else { + LOG_DBG("Download Complete"); + return 0; + } + } + } else { + if ((len_to_send & 0x01) == 0x01) { + if (len_to_send == (CMD_HDR_LEN + 1)) { + LOG_DBG("Resending first chunk..."); + fw_upload_write_data(buffer, len_to_send - 1); + sending_len = payload_len; + first_chunk_sent = false; + } else if (len_to_send == (payload_len + 1)) { + LOG_DBG("Resending second chunk..."); + fw_upload_write_data(&buffer[CMD_HDR_LEN], len_to_send - 1); + sending_len = CMD_HDR_LEN; + first_chunk_sent = true; + } + } else if (len_to_send == CMD_HDR_LEN) { + LOG_DBG("Resending send buffer..."); + fw_upload_write_data(buffer, len_to_send); + sending_len = payload_len; + first_chunk_sent = false; + } else if (len_to_send == payload_len) { + LOG_DBG("Resending second chunk..."); + fw_upload_write_data(&buffer[CMD_HDR_LEN], len_to_send); + sending_len = CMD_HDR_LEN; + first_chunk_sent = true; + } + } + + err = fw_upload_get_last_5bytes(buffer); + if (err < 0) { + LOG_ERR("Fail to get response"); + return err; + } + + if (fw_upload_len_valid(fw_upload.last_5bytes_buffer, &len_to_send) == 0) { + fw_upload_send_ack(V1_REQUEST_ACK); + LOG_DBG("BOOT_HEADER_ACK 0x5a sent"); + } + } + return len_to_send; +} + +static int fw_upload_uart_reconfig(uint32_t speed, bool flow_control) +{ + struct uart_config config; + int err; + + config.baudrate = speed; + config.data_bits = UART_CFG_DATA_BITS_8; + config.flow_ctrl = flow_control ? UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE; + config.parity = UART_CFG_PARITY_NONE; + config.stop_bits = UART_CFG_STOP_BITS_1; + + uart_irq_rx_disable(uart_dev); + uart_irq_tx_disable(uart_dev); + fw_upload_read_to_clear(); + err = uart_configure(uart_dev, &config); + uart_irq_rx_enable(uart_dev); + + return err; +} + +static int fw_upload_change_speed(uint8_t hdr) +{ + int err; + uint32_t hdr_len; + bool load_payload = false; + bool recovery = false; + uint16_t len_to_send; + uint32_t crc; + + err = fw_upload_change_speed_config( + (struct change_speed_config *)fw_upload.change_speed_buffer, + uart_dev_data.secondary_speed); + if (err) { + return err; + } + + hdr_len = sizeof(fw_upload.change_speed_buffer); + + fw_upload_gen_crc32_table(); + crc = sys_cpu_to_le32(hdr_len); + memcpy(cmd5_hdrData + 8, &crc, 4); + crc = fw_upload_update_crc32(0, (char *)cmd5_hdrData, 12); + crc = sys_cpu_to_be32(crc); + memcpy(cmd5_hdrData + 12, &crc, CRC32_LEN); + crc = fw_upload_update_crc32(0, (char *)fw_upload.change_speed_buffer, + (int)sizeof(struct change_speed_config)); + crc = sys_cpu_to_be32(crc); + memcpy(&fw_upload.change_speed_buffer[sizeof(struct change_speed_config)], &crc, CRC32_LEN); + + while (true) { + err = fw_upload_wait_for_hdr_sig(); + + if (hdr && (err == 0)) { + if (load_payload) { + if (fw_upload.version == VER3) { + fw_upload.change_speed_buffer_len = + CMD_HDR_LEN + fw_upload.length; + } + return 0; + } + } else { + if (recovery) { + return -ETIME; + } + + if (load_payload) { + LOG_ERR("HDR cannot be received by using second speed. receovery " + "speed"); + + err = fw_upload_uart_reconfig(uart_dev_data.primary_speed, + uart_dev_data.primary_flowcontrol); + if (err) { + return err; + } + + load_payload = false; + recovery = true; + continue; + } + } + + if (fw_upload.version == VER1) { + len_to_send = fw_upload_wait_length(0); + if (len_to_send == V1_START_INDICATION) { + return -EINVAL; + } else if (len_to_send == 0) { + continue; + } else if (len_to_send == CMD_HDR_LEN) { + memcpy(fw_upload.send_buffer, cmd5_hdrData, CMD_HDR_LEN); + memcpy(&fw_upload.send_buffer[CMD_HDR_LEN], + fw_upload.change_speed_buffer, hdr_len); + + err = fw_upload_write_hdr_and_payload(len_to_send, + fw_upload.send_buffer, true); + if (err < 0) { + return err; + } + + LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed); + + err = fw_upload_uart_reconfig(uart_dev_data.secondary_speed, + uart_dev_data.secondary_flowcontrol); + if (err) { + return err; + } + load_payload = true; + } else { + fw_upload_write_data(fw_upload.change_speed_buffer, hdr_len); + + LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed); + + err = fw_upload_uart_reconfig(uart_dev_data.secondary_speed, + uart_dev_data.secondary_flowcontrol); + if (err) { + return err; + } + load_payload = true; + } + } else if (fw_upload.version == VER3) { + err = fw_upload_wait_req(true); + if (!(!hdr || (err == 0))) { + continue; + } + if (fw_upload.length && (fw_upload.hdr_sig == V3_HEADER_DATA_REQ)) { + if (fw_upload.error != 0) { + fw_upload_send_ack(V3_TIMEOUT_ACK); + continue; + } + + fw_upload_send_ack(V3_REQUEST_ACK); + hdr = true; + + if (fw_upload.length == CMD_HDR_LEN) { + LOG_DBG("Send CMD5"); + fw_upload_write_data(cmd5_hdrData, fw_upload.length); + fw_upload.last_offset = fw_upload.offset; + } else { + LOG_DBG("Send UA RT config"); + fw_upload_write_data(fw_upload.change_speed_buffer, + fw_upload.length); + + LOG_DBG("Change speed to %d", + uart_dev_data.secondary_speed); + + err = fw_upload_uart_reconfig( + uart_dev_data.secondary_speed, + uart_dev_data.secondary_flowcontrol); + if (err) { + return err; + } + load_payload = true; + } + } + } + } + + return 0; +} + +static int fw_upload_v1_send_data(uint16_t len) +{ + uint32_t cmd; + uint32_t data_len; + int ret_len; + + memset(fw_upload.send_buffer, 0, sizeof(fw_upload.send_buffer)); + + fw_upload.is_cmd7_req = false; + fw_upload.is_entry_point_req = false; + + if ((fw_upload.fw_length - fw_upload.current_length) < len) { + len = fw_upload.fw_length - fw_upload.current_length; + } + + memcpy(fw_upload.send_buffer, fw_upload.fw + fw_upload.current_length, len); + fw_upload.current_length += len; + cmd = sys_get_le32(fw_upload.send_buffer); + if (cmd == CMD7) { + fw_upload.is_cmd7_req = true; + data_len = 0; + } else { + data_len = fw_upload_get_payload_length(fw_upload.send_buffer); + if ((data_len > (sizeof(fw_upload.send_buffer) - len)) || + ((data_len + fw_upload.current_length) > fw_upload.fw_length)) { + LOG_ERR("Invalid FW at %d/%d", fw_upload.current_length, + fw_upload.fw_length); + return -EINVAL; + } + memcpy(&fw_upload.send_buffer[len], fw_upload.fw + fw_upload.current_length, + data_len); + fw_upload.current_length += data_len; + if ((fw_upload.current_length < fw_upload.fw_length) && + ((cmd == CMD6) || (cmd == CMD4))) { + fw_upload.is_entry_point_req = true; + } + } + + ret_len = fw_upload_write_hdr_and_payload(len, fw_upload.send_buffer, false); + LOG_DBG("FW upload %d/%d", fw_upload.current_length, fw_upload.fw_length); + + return ret_len; +} + +static int fw_upload_v3_send_data(void) +{ + uint32_t start; + + LOG_DBG("Sending offset %d", fw_upload.offset); + if (fw_upload.offset == fw_upload.last_offset) { + LOG_WRN("Resending offset %d ...", fw_upload.offset); + fw_upload_write_data(fw_upload.send_buffer, fw_upload.length); + return fw_upload.length; + } + memset(fw_upload.send_buffer, 0, sizeof(fw_upload.send_buffer)); + start = fw_upload.offset - fw_upload.cmd7_change_timeout_len - + fw_upload.change_speed_buffer_len; + if (start >= fw_upload.fw_length) { + LOG_ERR("Invalid fw offset"); + return -EINVAL; + } + + if ((fw_upload.length + start) > fw_upload.fw_length) { + fw_upload.length = fw_upload.fw_length - start; + } + memcpy(fw_upload.send_buffer, fw_upload.fw + start, fw_upload.length); + fw_upload.current_length = start + fw_upload.length; + + fw_upload_write_data(fw_upload.send_buffer, fw_upload.length); + fw_upload.last_offset = fw_upload.offset; + + return fw_upload.length; +} + +static int fw_uploading(const uint8_t *fw, uint32_t fw_length) +{ + int err; + bool secondary_speed = false; + uint16_t len_to_send; + + fw_upload.wait_hdr_sig = true; + fw_upload.is_hdr_data = false; + fw_upload.is_error_case = false; + fw_upload.is_cmd7_req = false; + fw_upload.is_entry_point_req = false; + fw_upload.last_offset = 0xFFFFU; + + err = fw_upload_change_timeout(); + LOG_DBG("Change timeout hdr flag %d (err %d)", fw_upload.wait_hdr_sig, err); + if (err) { + return err; + } + + fw_upload_read_to_clear(); + + if (uart_dev_data.secondary_speed && + (uart_dev_data.secondary_speed != uart_dev_data.primary_speed)) { + LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed); + err = fw_upload_change_speed(fw_upload.wait_hdr_sig); + if (err != 0) { + LOG_ERR("Fail to change speed"); + return err; + } + secondary_speed = true; + } + + fw_upload.fw_length = fw_length; + fw_upload.current_length = 0; + fw_upload.fw = fw; + + while (true) { + err = fw_upload_wait_for_hdr_sig(); + if (secondary_speed && (err != 0)) { + return -ETIME; + } + + secondary_speed = false; + + if (fw_upload.version == VER1) { + len_to_send = fw_upload_wait_length(true); + + if (len_to_send == V1_START_INDICATION) { + continue; + } + while (len_to_send > 0) { + len_to_send = fw_upload_v1_send_data(len_to_send); + } + if (fw_upload.current_length >= fw_upload.fw_length) { + LOG_DBG("FW download done"); + return 0; + } + LOG_ERR("FW download failed"); + return len_to_send; + } else if (fw_upload.version == VER3) { + if (fw_upload.hdr_sig == V3_START_INDICATION) { + fw_upload_wait_req(false); + continue; + } + err = fw_upload_wait_req(false); + if (err) { + LOG_ERR("Fail to wait req"); + return err; + } + if (fw_upload.length) { + if (fw_upload.error == 0) { + fw_upload_send_ack(V3_REQUEST_ACK); + err = fw_upload_v3_send_data(); + if (err < 0) { + LOG_ERR("FW download failed"); + return err; + } + } else { + LOG_ERR("Error occurs %d", fw_upload.error); + fw_upload_send_ack(V3_TIMEOUT_ACK); + if (fw_upload.error & BT_MIC_FAIL_BIT) { + fw_upload.change_speed_buffer_len = 0; + fw_upload.current_length = 0; + fw_upload.last_offset = 0; + } + } + } else { + if (fw_upload.error == 0) { + fw_upload_send_ack(V3_REQUEST_ACK); + LOG_DBG("FW download done"); + return 0; + } + LOG_ERR("Error occurs %d", fw_upload.error); + fw_upload_send_ack(V3_TIMEOUT_ACK); + if (fw_upload.error & BT_MIC_FAIL_BIT) { + fw_upload.change_speed_buffer_len = 0; + fw_upload.current_length = 0; + fw_upload.last_offset = 0; + } + } + } else { + return -ENOTSUP; + } + } + return -EINVAL; +} + +static void bt_nxp_ctlr_uart_isr(const struct device *unused, void *user_data) +{ + int err = 0; + int count = 0; + + ARG_UNUSED(unused); + ARG_UNUSED(user_data); + + while (uart_irq_update(uart_dev) && uart_irq_is_pending(uart_dev)) { + err = uart_poll_in(uart_dev, &fw_upload.rx.buffer[fw_upload.rx.head]); + if (err >= 0) { + fw_upload.rx.head++; + fw_upload.rx.head = fw_upload.rx.head % sizeof(fw_upload.rx.buffer); + count++; + } + } + + while (count > 0) { + k_sem_give(&fw_upload.rx.sem); + count--; + } +} + +static int bt_nxp_ctlr_init(void) +{ + int err; + uint32_t speed; + bool flowcontrol_of_hci; + + if (!device_is_ready(uart_dev)) { + return -ENODEV; + } + + speed = DT_PROP(DT_INST_GPARENT(0), current_speed); + speed = DT_PROP_OR(DT_DRV_INST(0), hci_operation_speed, speed); + uart_dev_data.primary_speed = DT_PROP_OR(DT_DRV_INST(0), fw_download_primary_speed, speed); + uart_dev_data.secondary_speed = + DT_PROP_OR(DT_DRV_INST(0), fw_download_secondary_speed, speed); + + flowcontrol_of_hci = (bool)DT_PROP_OR(DT_DRV_INST(0), hw_flow_control, false); + uart_dev_data.primary_flowcontrol = + (bool)DT_PROP_OR(DT_DRV_INST(0), fw_download_primary_flowcontrol, false); + uart_dev_data.secondary_flowcontrol = + (bool)DT_PROP_OR(DT_DRV_INST(0), fw_download_secondary_flowcontrol, false); + +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) || \ + DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) + /* Check BT REG_ON gpio instance */ + if (!gpio_is_ready_dt(&sdio_reset)) { + LOG_ERR("Error: failed to configure sdio_reset %s pin %d", sdio_reset.port->name, + sdio_reset.pin); + return -EIO; + } + + /* Configure sdio_reset as output */ + err = gpio_pin_configure_dt(&sdio_reset, GPIO_OUTPUT); + if (err) { + LOG_ERR("Error %d: failed to configure sdio_reset %s pin %d", err, + sdio_reset.port->name, sdio_reset.pin); + return err; + } + err = gpio_pin_set_dt(&sdio_reset, 0); + if (err) { + return err; + } +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */ + +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) + /* Check BT REG_ON gpio instance */ + if (!gpio_is_ready_dt(&w_disable)) { + LOG_ERR("Error: failed to configure w_disable %s pin %d", w_disable.port->name, + w_disable.pin); + return -EIO; + } + + /* Configure w_disable as output */ + err = gpio_pin_configure_dt(&w_disable, GPIO_OUTPUT); + if (err) { + LOG_ERR("Error %d: failed to configure w_disable %s pin %d", err, + w_disable.port->name, w_disable.pin); + return err; + } + err = gpio_pin_set_dt(&w_disable, 0); + if (err) { + return err; + } +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */ + + /* wait for reset done */ + k_sleep(K_MSEC(100)); + +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) + err = gpio_pin_set_dt(&sdio_reset, 1); + if (err) { + return err; + } +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */ + +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) + err = gpio_pin_set_dt(&w_disable, 1); + if (err) { + return err; + } +#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */ +#endif + + uart_irq_rx_disable(uart_dev); + uart_irq_tx_disable(uart_dev); + + fw_upload.rx.head = 0; + fw_upload.rx.tail = 0; + + k_sem_init(&fw_upload.rx.sem, 0, sizeof(fw_upload.rx.buffer)); + + uart_irq_callback_set(uart_dev, bt_nxp_ctlr_uart_isr); + + made_table = false; + + err = fw_upload_uart_reconfig(uart_dev_data.primary_speed, + uart_dev_data.primary_flowcontrol); + if (err) { + LOG_ERR("Fail to config uart"); + return err; + } + + uart_irq_rx_enable(uart_dev); + + err = fw_uploading(bt_fw_bin, bt_fw_bin_len); + + if (err) { + LOG_ERR("Fail to upload firmware"); + return err; + } + + (void)fw_upload_uart_reconfig(speed, flowcontrol_of_hci); + + uart_irq_rx_disable(uart_dev); + uart_irq_tx_disable(uart_dev); + + k_sleep(K_MSEC(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_UPLOAD)); + + return 0; +} + +int bt_hci_transport_setup(const struct device *dev) +{ + if (dev != uart_dev) { + return -EINVAL; + } + + return bt_nxp_ctlr_init(); +} diff --git a/drivers/bluetooth/hci/hci_spi_st.c b/drivers/bluetooth/hci/hci_spi_st.c index d45dbb592a1e8a..fcfe2f4b750243 100644 --- a/drivers/bluetooth/hci/hci_spi_st.c +++ b/drivers/bluetooth/hci/hci_spi_st.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL @@ -38,7 +38,7 @@ LOG_MODULE_REGISTER(bt_driver); #define READY_NOW 0x02 #define EVT_BLUE_INITIALIZED 0x01 - +#define FW_STARTED_PROPERLY 0X01 /* Offsets */ #define STATUS_HEADER_READY 0 #define STATUS_HEADER_TOREAD 3 @@ -51,6 +51,7 @@ LOG_MODULE_REGISTER(bt_driver); #define EVT_LE_META_SUBEVENT 3 #define EVT_VENDOR_CODE_LSB 3 #define EVT_VENDOR_CODE_MSB 4 +#define REASON_CODE 5 #define CMD_OGF 1 #define CMD_OCF 2 @@ -89,7 +90,9 @@ static struct k_thread spi_rx_thread_data; #define BLUENRG_CONFIG_LL_ONLY_OFFSET 0x2C #define BLUENRG_CONFIG_LL_ONLY_LEN 0x01 -static int bt_spi_send_aci_config(uint8_t offset, const uint8_t *value, size_t value_len); +struct bt_spi_data { + bt_hci_recv_t recv; +}; static const struct spi_dt_spec bus = SPI_DT_SPEC_INST_GET( 0, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_LOCK_ON, 0); @@ -110,6 +113,43 @@ struct bt_hci_ext_evt_hdr { uint16_t len; } __packed; +int bluenrg_bt_reset(bool updater_mode) +{ + int err = 0; + /* Assert reset */ + if (!updater_mode) { + gpio_pin_set_dt(&rst_gpio, 1); + k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); + gpio_pin_set_dt(&rst_gpio, 0); + } else { +#if DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2) + return -ENOTSUP; +#else /* DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) */ + gpio_pin_set_dt(&rst_gpio, 1); + gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_DISABLE); + /* Configure IRQ pin as output and force it high */ + err = gpio_pin_configure_dt(&irq_gpio, GPIO_OUTPUT_ACTIVE); + if (err) { + return err; + } + /* Add reset delay and release reset */ + k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); + gpio_pin_set_dt(&rst_gpio, 0); + /* Give firmware some time to read the IRQ high */ + k_sleep(K_MSEC(5)); + gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + /* Reconfigure IRQ pin as input */ + err = gpio_pin_configure_dt(&irq_gpio, GPIO_INPUT); + if (err) { + return err; + } + /* Emulate possibly missed rising edge IRQ by signaling the IRQ semaphore */ + k_sem_give(&sem_request); +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2) */ + } + return err; +} + static inline int bt_spi_transceive(void *tx, uint32_t tx_len, void *rx, uint32_t rx_len) { @@ -142,13 +182,17 @@ static void bt_spi_isr(const struct device *unused1, static bool bt_spi_handle_vendor_evt(uint8_t *msg) { bool handled = false; + uint8_t reset_reason; switch (bt_spi_get_evt(msg)) { case EVT_BLUE_INITIALIZED: { - k_sem_give(&sem_initialised); + reset_reason = msg[REASON_CODE]; + if (reset_reason == FW_STARTED_PROPERLY) { + k_sem_give(&sem_initialised); #if defined(CONFIG_BT_BLUENRG_ACI) - handled = true; + handled = true; #endif + } } default: break; @@ -311,7 +355,8 @@ static int bt_spi_send_aci_config(uint8_t offset, const uint8_t *value, size_t v } #if !defined(CONFIG_BT_HCI_RAW) -static int bt_spi_bluenrg_setup(const struct bt_hci_setup_params *params) +static int bt_spi_bluenrg_setup(const struct device *dev, + const struct bt_hci_setup_params *params) { int ret; const bt_addr_t *addr = ¶ms->public_addr; @@ -456,7 +501,9 @@ static int bt_spi_rx_buf_construct(uint8_t *msg, struct net_buf **bufp, uint16_t static void bt_spi_rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct bt_spi_data *hci = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -499,14 +546,14 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3) ret = bt_spi_rx_buf_construct(rxmsg, &buf, size); if (!ret) { /* Handle the received HCI data */ - bt_recv(buf); + hci->recv(dev, buf); buf = NULL; } } while (READ_CONDITION); } } -static int bt_spi_send(struct net_buf *buf) +static int bt_spi_send(const struct device *dev, struct net_buf *buf) { uint16_t size; uint8_t rx_first[1]; @@ -592,8 +639,9 @@ static int bt_spi_send(struct net_buf *buf) return ret; } -static int bt_spi_open(void) +static int bt_spi_open(const struct device *dev, bt_hci_recv_t recv) { + struct bt_spi_data *hci = dev->data; int err; /* Configure RST pin and hold BLE in Reset */ @@ -620,6 +668,8 @@ static int bt_spi_open(void) return err; } + hci->recv = recv; + /* Take BLE out of reset */ k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); gpio_pin_set_dt(&rst_gpio, 0); @@ -627,7 +677,7 @@ static int bt_spi_open(void) /* Start RX thread */ k_thread_create(&spi_rx_thread_data, spi_rx_stack, K_KERNEL_STACK_SIZEOF(spi_rx_stack), - bt_spi_rx_thread, NULL, NULL, NULL, + bt_spi_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); @@ -643,10 +693,7 @@ static int bt_spi_open(void) return 0; } -static const struct bt_hci_driver drv = { - .name = DEVICE_DT_NAME(DT_DRV_INST(0)), - .bus = BT_HCI_DRIVER_BUS_SPI, - .quirks = BT_QUIRK_NO_RESET, +static const struct bt_hci_driver_api drv = { #if defined(CONFIG_BT_BLUENRG_ACI) && !defined(CONFIG_BT_HCI_RAW) .setup = bt_spi_bluenrg_setup, #endif /* CONFIG_BT_BLUENRG_ACI && !CONFIG_BT_HCI_RAW */ @@ -654,7 +701,7 @@ static const struct bt_hci_driver drv = { .send = bt_spi_send, }; -static int bt_spi_init(void) +static int bt_spi_init(const struct device *dev) { if (!spi_is_ready_dt(&bus)) { @@ -672,12 +719,16 @@ static int bt_spi_init(void) return -ENODEV; } - bt_hci_driver_register(&drv); - - LOG_DBG("BT SPI initialized"); return 0; } -SYS_INIT(bt_spi_init, POST_KERNEL, CONFIG_BT_SPI_INIT_PRIORITY); +#define HCI_DEVICE_INIT(inst) \ + static struct bt_spi_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, bt_spi_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_BT_SPI_INIT_PRIORITY, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index 67b87a5aa25dd4..34e2385b2414d7 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -7,11 +7,10 @@ * SPDX-License-Identifier: Apache-2.0 */ - #include #include #include -#include +#include #include #include #include @@ -27,6 +26,12 @@ #include LOG_MODULE_REGISTER(hci_wba); +#define DT_DRV_COMPAT st_hci_stm32wba + +struct hci_data { + bt_hci_recv_t recv; +}; + static K_SEM_DEFINE(hci_sem, 1, 1); #define BLE_CTRLR_STACK_BUFFER_SIZE 300 @@ -39,9 +44,16 @@ static K_SEM_DEFINE(hci_sem, 1, 1); #define BLE_DYN_ALLOC_SIZE \ (BLE_TOTAL_BUFFER_SIZE(CFG_BLE_NUM_LINK, MBLOCK_COUNT)) +/* GATT buffer size (in bytes)*/ +#define BLE_GATT_BUF_SIZE \ + BLE_TOTAL_BUFFER_SIZE_GATT(CFG_BLE_NUM_GATT_ATTRIBUTES, \ + CFG_BLE_NUM_GATT_SERVICES, \ + CFG_BLE_ATT_VALUE_ARRAY_SIZE) + #define DIVC(x, y) (((x)+(y)-1)/(y)) static uint32_t __noinit buffer[DIVC(BLE_DYN_ALLOC_SIZE, 4)]; +static uint32_t __noinit gatt_buffer[DIVC(BLE_GATT_BUF_SIZE, 4)]; extern uint8_t ll_state_busy; @@ -205,9 +217,10 @@ static struct net_buf *treat_iso(const uint8_t *data, size_t len, return buf; } -static int receive_data(const uint8_t *data, size_t len, +static int receive_data(const struct device *dev, const uint8_t *data, size_t len, const uint8_t *ext_data, size_t ext_len) { + struct hci_data *hci = dev->data; uint8_t pkt_indicator; struct net_buf *buf; int err = 0; @@ -235,7 +248,7 @@ static int receive_data(const uint8_t *data, size_t len, } if (buf) { - bt_recv(buf); + hci->recv(dev, buf); } else { err = -ENOMEM; ll_state_busy = 1; @@ -247,6 +260,7 @@ static int receive_data(const uint8_t *data, size_t len, uint8_t BLECB_Indication(const uint8_t *data, uint16_t length, const uint8_t *ext_data, uint16_t ext_length) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); int ret = 0; int err; @@ -257,7 +271,7 @@ uint8_t BLECB_Indication(const uint8_t *data, uint16_t length, k_sem_take(&hci_sem, K_FOREVER); - err = receive_data(data, (size_t)length - 1, + err = receive_data(dev, data, (size_t)length - 1, ext_data, (size_t)ext_length); k_sem_give(&hci_sem); @@ -271,12 +285,14 @@ uint8_t BLECB_Indication(const uint8_t *data, uint16_t length, return ret; } -static int bt_hci_stm32wba_send(struct net_buf *buf) +static int bt_hci_stm32wba_send(const struct device *dev, struct net_buf *buf) { uint16_t event_length; uint8_t pkt_indicator; uint8_t tx_buffer[BLE_CTRLR_STACK_BUFFER_SIZE]; + ARG_UNUSED(dev); + k_sem_take(&hci_sem, K_FOREVER); LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); @@ -304,7 +320,7 @@ static int bt_hci_stm32wba_send(struct net_buf *buf) LOG_DBG("event_length: %u", event_length); if (event_length) { - receive_data((uint8_t *)&tx_buffer, (size_t)event_length, NULL, 0); + receive_data(dev, (uint8_t *)&tx_buffer, (size_t)event_length, NULL, 0); } k_sem_give(&hci_sem); @@ -330,8 +346,8 @@ static int bt_ble_ctlr_init(void) init_params_p.mblockCount = CFG_BLE_MBLOCK_COUNT; init_params_p.bleStartRamAddress = (uint8_t *)buffer; init_params_p.total_buffer_size = BLE_DYN_ALLOC_SIZE; - init_params_p.bleStartRamAddress_GATT = NULL; - init_params_p.total_buffer_size_GATT = 0; + init_params_p.bleStartRamAddress_GATT = (uint8_t *)gatt_buffer; + init_params_p.total_buffer_size_GATT = BLE_GATT_BUF_SIZE; init_params_p.options = CFG_BLE_OPTIONS; init_params_p.debug = 0U; @@ -342,8 +358,9 @@ static int bt_ble_ctlr_init(void) return 0; } -static int bt_hci_stm32wba_open(void) +static int bt_hci_stm32wba_open(const struct device *dev, bt_hci_recv_t recv) { + struct hci_data *data = dev->data; int ret = 0; link_layer_register_isr(); @@ -351,6 +368,9 @@ static int bt_hci_stm32wba_open(void) ll_sys_config_params(); ret = bt_ble_ctlr_init(); + if (ret == 0) { + data->recv = recv; + } /* TODO. Enable Flash manager once available */ if (IS_ENABLED(CONFIG_FLASH)) { @@ -360,18 +380,16 @@ static int bt_hci_stm32wba_open(void) return ret; } -static const struct bt_hci_driver drv = { - .name = "BT IPM", - .bus = BT_HCI_DRIVER_BUS_IPM, +static const struct bt_hci_driver_api drv = { .open = bt_hci_stm32wba_open, .send = bt_hci_stm32wba_send, }; -static int bt_stm32wba_hci_init(void) -{ - bt_hci_driver_register(&drv); - - return 0; -} +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) -SYS_INIT(bt_stm32wba_hci_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +/* Only one instance supported */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/ipc.c b/drivers/bluetooth/hci/ipc.c index 54a8556d1384af..9d63d12ec3286d 100644 --- a/drivers/bluetooth/hci/ipc.c +++ b/drivers/bluetooth/hci/ipc.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -18,10 +18,17 @@ #include LOG_MODULE_REGISTER(bt_hci_driver); +#define DT_DRV_COMPAT zephyr_bt_hci_ipc + #define IPC_BOUND_TIMEOUT_IN_MS K_MSEC(1000) -static struct ipc_ept hci_ept; -static K_SEM_DEFINE(ipc_bound_sem, 0, 1); +struct ipc_data { + bt_hci_recv_t recv; + struct ipc_ept hci_ept; + struct ipc_ept_cfg hci_ept_cfg; + struct k_sem bound_sem; + const struct device *ipc; +}; static bool is_hci_event_discardable(const uint8_t *evt_data) { @@ -200,8 +207,9 @@ static struct net_buf *bt_ipc_iso_recv(const uint8_t *data, size_t remaining) return buf; } -static void bt_ipc_rx(const uint8_t *data, size_t len) +static void bt_ipc_rx(const struct device *dev, const uint8_t *data, size_t len) { + struct ipc_data *ipc = dev->data; uint8_t pkt_indicator; struct net_buf *buf = NULL; size_t remaining = len; @@ -231,14 +239,15 @@ static void bt_ipc_rx(const uint8_t *data, size_t len) if (buf) { LOG_DBG("Calling bt_recv(%p)", buf); - bt_recv(buf); + ipc->recv(dev, buf); LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:"); } } -static int bt_ipc_send(struct net_buf *buf) +static int bt_ipc_send(const struct device *dev, struct net_buf *buf) { + struct ipc_data *data = dev->data; int err; uint8_t pkt_indicator; @@ -261,7 +270,7 @@ static int bt_ipc_send(struct net_buf *buf) net_buf_push_u8(buf, pkt_indicator); LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:"); - err = ipc_service_send(&hci_ept, buf->data, buf->len); + err = ipc_service_send(&data->hci_ept, buf->data, buf->len); if (err < 0) { LOG_ERR("Failed to send (err %d)", err); } @@ -273,21 +282,18 @@ static int bt_ipc_send(struct net_buf *buf) static void hci_ept_bound(void *priv) { - k_sem_give(&ipc_bound_sem); + const struct device *dev = priv; + struct ipc_data *ipc = dev->data; + + k_sem_give(&ipc->bound_sem); } static void hci_ept_recv(const void *data, size_t len, void *priv) { - bt_ipc_rx(data, len); -} + const struct device *dev = priv; -static struct ipc_ept_cfg hci_ept_cfg = { - .name = "nrf_bt_hci", - .cb = { - .bound = hci_ept_bound, - .received = hci_ept_recv, - }, -}; + bt_ipc_rx(dev, data, len); +} int __weak bt_hci_transport_setup(const struct device *dev) { @@ -301,13 +307,11 @@ int __weak bt_hci_transport_teardown(const struct device *dev) return 0; } -static int bt_ipc_open(void) +static int bt_ipc_open(const struct device *dev, bt_hci_recv_t recv) { + struct ipc_data *ipc = dev->data; int err; - const struct device *hci_ipc_instance = - DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc)); - err = bt_hci_transport_setup(NULL); if (err) { LOG_ERR("HCI transport setup failed with: %d\n", err); @@ -316,29 +320,32 @@ static int bt_ipc_open(void) LOG_DBG(""); - err = ipc_service_open_instance(hci_ipc_instance); + err = ipc_service_open_instance(ipc->ipc); if (err && (err != -EALREADY)) { LOG_ERR("IPC service instance initialization failed: %d\n", err); return err; } - err = ipc_service_register_endpoint(hci_ipc_instance, &hci_ept, &hci_ept_cfg); + err = ipc_service_register_endpoint(ipc->ipc, &ipc->hci_ept, &ipc->hci_ept_cfg); if (err) { LOG_ERR("Registering endpoint failed with %d", err); return err; } - err = k_sem_take(&ipc_bound_sem, IPC_BOUND_TIMEOUT_IN_MS); + err = k_sem_take(&ipc->bound_sem, IPC_BOUND_TIMEOUT_IN_MS); if (err) { LOG_ERR("Endpoint binding failed with %d", err); return err; } + ipc->recv = recv; + return 0; } -static int bt_ipc_close(void) +static int bt_ipc_close(const struct device *dev) { + struct ipc_data *ipc = dev->data; int err; if (IS_ENABLED(CONFIG_BT_HCI_HOST)) { @@ -349,16 +356,13 @@ static int bt_ipc_close(void) } } - err = ipc_service_deregister_endpoint(&hci_ept); + err = ipc_service_deregister_endpoint(&ipc->hci_ept); if (err) { LOG_ERR("Deregistering HCI endpoint failed with: %d", err); return err; } - const struct device *hci_ipc_instance = - DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_ipc)); - - err = ipc_service_close_instance(hci_ipc_instance); + err = ipc_service_close_instance(ipc->ipc); if (err) { LOG_ERR("Closing IPC service failed with: %d", err); return err; @@ -370,31 +374,31 @@ static int bt_ipc_close(void) return err; } + ipc->recv = NULL; + return 0; } -static const struct bt_hci_driver drv = { - .name = "IPC", +static const struct bt_hci_driver_api drv = { .open = bt_ipc_open, .close = bt_ipc_close, .send = bt_ipc_send, - .bus = BT_HCI_DRIVER_BUS_IPM, -#if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE) - .quirks = BT_QUIRK_NO_AUTO_DLE, -#endif }; -static int bt_ipc_init(void) -{ - - int err; - - err = bt_hci_driver_register(&drv); - if (err < 0) { - LOG_ERR("Failed to register BT HIC driver (err %d)", err); - } - - return err; -} - -SYS_INIT(bt_ipc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#define IPC_DEVICE_INIT(inst) \ + static struct ipc_data ipc_data_##inst = { \ + .bound_sem = Z_SEM_INITIALIZER(ipc_data_##inst.bound_sem, 0, 1), \ + .hci_ept_cfg = { \ + .name = DT_INST_PROP(inst, bt_hci_ipc_name), \ + .cb = { \ + .bound = hci_ept_bound, \ + .received = hci_ept_recv, \ + }, \ + .priv = (void *)DEVICE_DT_INST_GET(inst), \ + }, \ + .ipc = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &ipc_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +DT_INST_FOREACH_STATUS_OKAY(IPC_DEVICE_INIT) diff --git a/drivers/bluetooth/hci/ipm_stm32wb.c b/drivers/bluetooth/hci/ipm_stm32wb.c index 48c5dd0a99caeb..df83ee36d54c9f 100644 --- a/drivers/bluetooth/hci/ipm_stm32wb.c +++ b/drivers/bluetooth/hci/ipm_stm32wb.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -21,7 +21,11 @@ #include "shci.h" #include "shci_tl.h" -static const struct stm32_pclken clk_cfg[] = STM32_DT_CLOCKS(DT_NODELABEL(ble_rf)); +struct hci_data { + bt_hci_recv_t recv; +}; + +static const struct stm32_pclken clk_cfg[] = STM32_DT_CLOCKS(DT_DRV_INST(0)); #define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * \ DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4)) @@ -156,7 +160,9 @@ void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt) static void bt_ipm_rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct hci_data *hci = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -245,7 +251,7 @@ static void bt_ipm_rx_thread(void *p1, void *p2, void *p3) TL_MM_EvtDone(hcievt); - bt_recv(buf); + hci->recv(dev, buf); end_loop: k_sem_give(&ipm_busy); } @@ -347,10 +353,12 @@ void transport_init(void) TL_Enable(); } -static int bt_ipm_send(struct net_buf *buf) +static int bt_ipm_send(const struct device *dev, struct net_buf *buf) { TL_CmdPacket_t *ble_cmd_buff = &BleCmdBuffer; + ARG_UNUSED(dev); + k_sem_take(&ipm_busy, K_FOREVER); switch (bt_buf_get_type(buf)) { @@ -534,8 +542,9 @@ static int c2_reset(void) return 0; } -static int bt_ipm_open(void) +static int bt_ipm_open(const struct device *dev, bt_hci_recv_t recv) { + struct hci_data *hci = dev->data; int err; if (!c2_started_flag) { @@ -553,7 +562,7 @@ static int bt_ipm_open(void) /* Start RX thread */ k_thread_create(&ipm_rx_thread_data, ipm_rx_stack, K_KERNEL_STACK_SIZEOF(ipm_rx_stack), - bt_ipm_rx_thread, NULL, NULL, NULL, + bt_ipm_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); @@ -564,14 +573,17 @@ static int bt_ipm_open(void) } #endif /* CONFIG_BT_HCI_HOST */ + hci->recv = recv; + LOG_DBG("IPM Channel Open Completed"); return 0; } #ifdef CONFIG_BT_HCI_HOST -static int bt_ipm_close(void) +static int bt_ipm_close(const struct device *dev) { + struct hci_data *hci = dev->data; int err; struct net_buf *rsp; @@ -590,15 +602,15 @@ static int bt_ipm_close(void) k_thread_abort(&ipm_rx_thread_data); + hci->recv = NULL; + LOG_DBG("IPM Channel Close Completed"); return err; } #endif /* CONFIG_BT_HCI_HOST */ -static const struct bt_hci_driver drv = { - .name = "BT IPM", - .bus = BT_HCI_DRIVER_BUS_IPM, +static const struct bt_hci_driver_api drv = { .open = bt_ipm_open, #ifdef CONFIG_BT_HCI_HOST .close = bt_ipm_close, @@ -606,12 +618,11 @@ static const struct bt_hci_driver drv = { .send = bt_ipm_send, }; -static int _bt_ipm_init(void) +static int _bt_ipm_init(const struct device *dev) { int err; - - bt_hci_driver_register(&drv); + ARG_UNUSED(dev); err = c2_reset(); if (err) { @@ -621,4 +632,11 @@ static int _bt_ipm_init(void) return 0; } -SYS_INIT(_bt_ipm_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, _bt_ipm_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/slz_hci.c b/drivers/bluetooth/hci/slz_hci.c index a3daf334607118..1dcb0278fd7e0b 100644 --- a/drivers/bluetooth/hci/slz_hci.c +++ b/drivers/bluetooth/hci/slz_hci.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include @@ -16,6 +16,12 @@ #include LOG_MODULE_REGISTER(bt_hci_driver_slz); +#define DT_DRV_COMPAT silabs_bt_hci + +struct hci_data { + bt_hci_recv_t recv; +}; + #define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 #define SL_BT_CONFIG_MAX_CONNECTIONS 1 #define SL_BT_CONFIG_USER_ADVERTISERS 1 @@ -53,6 +59,8 @@ void rail_isr_installer(void) */ uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len) { + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct hci_data *hci = dev->data; struct net_buf *buf; uint8_t packet_type = data[0]; uint8_t event_code; @@ -77,17 +85,19 @@ uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len) } net_buf_add_mem(buf, data, len); - bt_recv(buf); + hci->recv(dev, buf); sl_btctrl_hci_transmit_complete(0); return 0; } -static int slz_bt_send(struct net_buf *buf) +static int slz_bt_send(const struct device *dev, struct net_buf *buf) { int rv = 0; + ARG_UNUSED(dev); + switch (bt_buf_get_type(buf)) { case BT_BUF_ACL_OUT: net_buf_push_u8(buf, h4_acl); @@ -119,8 +129,9 @@ static void slz_thread_func(void *p1, void *p2, void *p3) slz_ll_thread_func(); } -static int slz_bt_open(void) +static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) { + struct hci_data *hci = dev->data; int ret; /* Start RX thread */ @@ -185,6 +196,8 @@ static int slz_bt_open(void) } #endif + hci->recv = recv; + LOG_DBG("SiLabs BT HCI started"); return 0; @@ -193,24 +206,16 @@ static int slz_bt_open(void) return ret; } -static const struct bt_hci_driver drv = { - .name = "sl:bt", - .bus = BT_HCI_DRIVER_BUS_UART, +static const struct bt_hci_driver_api drv = { .open = slz_bt_open, .send = slz_bt_send, - .quirks = BT_QUIRK_NO_RESET }; -static int slz_bt_init(void) -{ - int ret; - - ret = bt_hci_driver_register(&drv); - if (ret) { - LOG_ERR("Failed to register SiLabs BT HCI %d", ret); - } - - return ret; -} +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) -SYS_INIT(slz_bt_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 26d8f32afd0a7f..05e46a1d182cfa 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -15,7 +15,7 @@ #include #include -#include +#include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL #include @@ -66,6 +66,10 @@ LOG_MODULE_REGISTER(bt_driver); be transmitted across this HCI link #endif /* CONFIG_BT_L2CAP_TX_MTU > MAX_MTU */ +struct bt_spi_data { + bt_hci_recv_t recv; +}; + static uint8_t __noinit rxmsg[SPI_MAX_MSG_LEN]; static uint8_t __noinit txmsg[SPI_MAX_MSG_LEN]; @@ -236,7 +240,9 @@ static struct net_buf *bt_spi_rx_buf_construct(uint8_t *msg) static void bt_spi_rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct bt_spi_data *hci = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -288,17 +294,19 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3) buf = bt_spi_rx_buf_construct(rxmsg); if (buf) { /* Handle the received HCI data */ - bt_recv(buf); + hci->recv(dev, buf); } } } -static int bt_spi_send(struct net_buf *buf) +static int bt_spi_send(const struct device *dev, struct net_buf *buf) { uint16_t size; uint8_t rx_first[1]; int ret; + ARG_UNUSED(dev); + LOG_DBG(""); /* Buffer needs an additional byte for type */ @@ -364,8 +372,9 @@ static int bt_spi_send(struct net_buf *buf) return ret; } -static int bt_spi_open(void) +static int bt_spi_open(const struct device *dev, bt_hci_recv_t recv) { + struct bt_spi_data *hci = dev->data; int err; /* Configure RST pin and hold BLE in Reset */ @@ -392,6 +401,8 @@ static int bt_spi_open(void) return err; } + hci->recv = recv; + /* Take BLE out of reset */ k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); gpio_pin_set_dt(&rst_gpio, 0); @@ -399,7 +410,7 @@ static int bt_spi_open(void) /* Start RX thread */ k_thread_create(&spi_rx_thread_data, spi_rx_stack, K_KERNEL_STACK_SIZEOF(spi_rx_stack), - bt_spi_rx_thread, NULL, NULL, NULL, + bt_spi_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); @@ -409,15 +420,14 @@ static int bt_spi_open(void) return 0; } -static const struct bt_hci_driver drv = { - .name = DEVICE_DT_NAME(DT_DRV_INST(0)), - .bus = BT_HCI_DRIVER_BUS_SPI, +static const struct bt_hci_driver_api drv = { .open = bt_spi_open, .send = bt_spi_send, }; -static int bt_spi_init(void) +static int bt_spi_init(const struct device *dev) { + ARG_UNUSED(dev); if (!spi_is_ready_dt(&bus)) { LOG_ERR("SPI device not ready"); @@ -434,12 +444,16 @@ static int bt_spi_init(void) return -ENODEV; } - bt_hci_driver_register(&drv); - - LOG_DBG("BT SPI initialized"); return 0; } -SYS_INIT(bt_spi_init, POST_KERNEL, CONFIG_BT_SPI_INIT_PRIORITY); +#define HCI_DEVICE_INIT(inst) \ + static struct bt_spi_data hci_data_##inst = { \ + }; \ + DEVICE_DT_INST_DEFINE(inst, bt_spi_init, NULL, &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_BT_SPI_INIT_PRIORITY, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/userchan.c b/drivers/bluetooth/hci/userchan.c index 8a1ae24127496c..a5f6810b82b7e5 100644 --- a/drivers/bluetooth/hci/userchan.c +++ b/drivers/bluetooth/hci/userchan.c @@ -30,12 +30,20 @@ #include #include -#include +#include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_driver); +#define DT_DRV_COMPAT zephyr_bt_hci_userchan + +struct uc_data { + int fd; + bt_hci_recv_t recv; + +}; + #define BTPROTO_HCI 1 struct sockaddr_hci { sa_family_t hci_family; @@ -50,8 +58,6 @@ static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE); static struct k_thread rx_thread_data; -static int uc_fd = -1; - static unsigned short bt_dev_index; #define TCP_ADDR_BUFF_SIZE 16 @@ -158,16 +164,18 @@ static int32_t hci_packet_complete(const uint8_t *buf, uint16_t buf_len) return (int32_t)header_len + payload_len; } -static bool uc_ready(void) +static bool uc_ready(int fd) { - struct pollfd pollfd = { .fd = uc_fd, .events = POLLIN }; + struct pollfd pollfd = { .fd = fd, .events = POLLIN }; return (poll(&pollfd, 1, 0) == 1); } static void rx_thread(void *p1, void *p2, void *p3) { - ARG_UNUSED(p1); + const struct device *dev = p1; + struct uc_data *uc = dev->data; + ARG_UNUSED(p2); ARG_UNUSED(p3); @@ -183,14 +191,14 @@ static void rx_thread(void *p1, void *p2, void *p3) ssize_t len; const uint8_t *frame_start = frame; - if (!uc_ready()) { + if (!uc_ready(uc->fd)) { k_sleep(K_MSEC(1)); continue; } LOG_DBG("calling read()"); - len = read(uc_fd, frame + frame_size, sizeof(frame) - frame_size); + len = read(uc->fd, frame + frame_size, sizeof(frame) - frame_size); if (len < 0) { if (errno == EINTR) { k_yield(); @@ -198,8 +206,8 @@ static void rx_thread(void *p1, void *p2, void *p3) } LOG_ERR("Reading socket failed, errno %d", errno); - close(uc_fd); - uc_fd = -1; + close(uc->fd); + uc->fd = -1; return; } @@ -256,18 +264,20 @@ static void rx_thread(void *p1, void *p2, void *p3) LOG_DBG("Calling bt_recv(%p)", buf); - bt_recv(buf); + uc->recv(dev, buf); } k_yield(); } } -static int uc_send(struct net_buf *buf) +static int uc_send(const struct device *dev, struct net_buf *buf) { + struct uc_data *uc = dev->data; + LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); - if (uc_fd < 0) { + if (uc->fd < 0) { LOG_ERR("User channel not open"); return -EIO; } @@ -290,7 +300,7 @@ static int uc_send(struct net_buf *buf) return -EINVAL; } - if (write(uc_fd, buf->data, buf->len) < 0) { + if (write(uc->fd, buf->data, buf->len) < 0) { return -errno; } @@ -350,25 +360,28 @@ static int user_chan_open(void) return fd; } -static int uc_open(void) +static int uc_open(const struct device *dev, bt_hci_recv_t recv) { + struct uc_data *uc = dev->data; + if (hci_socket) { LOG_DBG("hci%d", bt_dev_index); } else { LOG_DBG("hci %s:%d", ip_addr, port); } - - uc_fd = user_chan_open(); - if (uc_fd < 0) { - return uc_fd; + uc->fd = user_chan_open(); + if (uc->fd < 0) { + return uc->fd; } - LOG_DBG("User Channel opened as fd %d", uc_fd); + uc->recv = recv; + + LOG_DBG("User Channel opened as fd %d", uc->fd); k_thread_create(&rx_thread_data, rx_thread_stack, K_KERNEL_STACK_SIZEOF(rx_thread_stack), - rx_thread, NULL, NULL, NULL, + rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); @@ -377,22 +390,31 @@ static int uc_open(void) return 0; } -static const struct bt_hci_driver drv = { - .name = "HCI User Channel", - .bus = BT_HCI_DRIVER_BUS_UART, - .open = uc_open, - .send = uc_send, +static const struct bt_hci_driver_api uc_drv_api = { + .open = uc_open, + .send = uc_send, }; -static int bt_uc_init(void) +static int uc_init(const struct device *dev) { - - bt_hci_driver_register(&drv); + if (!arg_found) { + posix_print_warning("Warning: Bluetooth device missing.\n" + "Specify either a local hci interface --bt-dev=hciN\n" + "or a valid hci tcp server --bt-dev=ip_address:port\n"); + return -ENODEV; + } return 0; } -SYS_INIT(bt_uc_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#define UC_DEVICE_INIT(inst) \ + static struct uc_data uc_data_##inst = { \ + .fd = -1, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, uc_init, NULL, &uc_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uc_drv_api) + +DT_INST_FOREACH_STATUS_OKAY(UC_DEVICE_INIT) static void cmd_bt_dev_found(char *argv, int offset) { @@ -446,14 +468,4 @@ static void add_btuserchan_arg(void) native_add_command_line_opts(btuserchan_args); } -static void btuserchan_check_arg(void) -{ - if (!arg_found) { - posix_print_error_and_exit("Error: Bluetooth device missing.\n" - "Specify either a local hci interface --bt-dev=hciN\n" - "or a valid hci tcp server --bt-dev=ip_address:port\n"); - } -} - NATIVE_TASK(add_btuserchan_arg, PRE_BOOT_1, 10); -NATIVE_TASK(btuserchan_check_arg, PRE_BOOT_2, 10); diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index df1bf5f7f6c57f..5aa956353dc21c 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -28,7 +28,7 @@ config CAN_DEFAULT_BITRATE default 125000 help Default initial CAN bitrate in bits/s. This can be overridden per CAN controller using the - "bus-speed" devicetree property. + "bitrate" devicetree property. config CAN_DEFAULT_BITRATE_DATA int "Default CAN data phase bitrate" @@ -36,7 +36,7 @@ config CAN_DEFAULT_BITRATE_DATA depends on CAN_FD_MODE help Default initial CAN data phase bitrate in bits/s. This can be overridden per CAN controller - using the "bus-speed-data" devicetree property. + using the "bitrate-data" devicetree property. config CAN_SHELL bool "CAN shell" diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index 56ac2225b89a35..c4a94d49cfaa4b 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -1466,7 +1466,7 @@ int can_mcan_init(const struct device *dev) return err; } - err = can_calc_timing(dev, &timing, config->common.bus_speed, + err = can_calc_timing(dev, &timing, config->common.bitrate, config->common.sample_point); if (err == -EINVAL) { LOG_ERR("Can't find timing for given param"); @@ -1477,7 +1477,7 @@ int can_mcan_init(const struct device *dev) timing.phase_seg2); LOG_DBG("Sample-point err : %d", err); #ifdef CONFIG_CAN_FD_MODE - err = can_calc_timing_data(dev, &timing_data, config->common.bus_speed_data, + err = can_calc_timing_data(dev, &timing_data, config->common.bitrate_data, config->common.sample_point_data); if (err == -EINVAL) { LOG_ERR("Can't find timing for given dataphase param"); diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index b7720a7ab47ae4..791f548cec5b43 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -972,7 +972,7 @@ static int mcp2515_init(const struct device *dev) (void)memset(dev_data->filter, 0, sizeof(dev_data->filter)); dev_data->old_state = CAN_STATE_ERROR_ACTIVE; - ret = can_calc_timing(dev, &timing, dev_cfg->common.bus_speed, + ret = can_calc_timing(dev, &timing, dev_cfg->common.bitrate, dev_cfg->common.sample_point); if (ret == -EINVAL) { LOG_ERR("Can't find timing for given param"); diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c index 8e1fef06168ee7..ae347296eeb3af 100644 --- a/drivers/can/can_mcp251xfd.c +++ b/drivers/can/can_mcp251xfd.c @@ -1576,7 +1576,7 @@ static int mcp251xfd_init(const struct device *dev) goto done; } - ret = can_calc_timing(dev, &timing, dev_cfg->common.bus_speed, + ret = can_calc_timing(dev, &timing, dev_cfg->common.bitrate, dev_cfg->common.sample_point); if (ret < 0) { LOG_ERR("Can't find timing for given param"); @@ -1588,7 +1588,7 @@ static int mcp251xfd_init(const struct device *dev) LOG_DBG("Sample-point err : %d", ret); #if defined(CONFIG_CAN_FD_MODE) - ret = can_calc_timing_data(dev, &timing_data, dev_cfg->common.bus_speed_data, + ret = can_calc_timing_data(dev, &timing_data, dev_cfg->common.bitrate_data, dev_cfg->common.sample_point_data); if (ret < 0) { LOG_ERR("Can't find data timing for given param"); diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index c4109c89c610da..cc11dadf962471 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -305,6 +305,12 @@ static int mcux_flexcan_start(const struct device *dev) timing.fphaseSeg2 = data->timing_data.phase_seg2 - 1U; timing.fpropSeg = data->timing_data.prop_seg; FLEXCAN_SetFDTimingConfig(config->base, &timing); + + FLEXCAN_EnterFreezeMode(config->base); + config->base->FDCTRL &= ~(CAN_FDCTRL_TDCOFF_MASK); + config->base->FDCTRL |= FIELD_PREP(CAN_FDCTRL_TDCOFF_MASK, + CAN_CALC_TDCO((&data->timing_data), 1U, 31U)); + FLEXCAN_ExitFreezeMode(config->base); } #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ @@ -1139,7 +1145,7 @@ static int mcux_flexcan_init(const struct device *dev) k_sem_init(&data->tx_allocs_sem, MCUX_FLEXCAN_MAX_TX, MCUX_FLEXCAN_MAX_TX); - err = can_calc_timing(dev, &data->timing, config->common.bus_speed, + err = can_calc_timing(dev, &data->timing, config->common.bitrate, config->common.sample_point); if (err == -EINVAL) { LOG_ERR("Can't find timing for given param"); @@ -1160,7 +1166,7 @@ static int mcux_flexcan_init(const struct device *dev) #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD if (config->flexcan_fd) { err = can_calc_timing_data(dev, &data->timing_data, - config->common.bus_speed_data, + config->common.bitrate_data, config->common.sample_point_data); if (err == -EINVAL) { LOG_ERR("Can't find timing for given param"); diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index 9d1e2626ab010e..010f291ce160b8 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -43,6 +43,8 @@ #define CAN_NXP_S32_MAX_BITRATE 8000000 #define CAN_NXP_S32_DATA_LENGTH 64 +#define CAN_NXP_S32_TDCO_MAX FIELD_GET(CANXL_SIC_BTDCC_FTDCOFF_MASK, CANXL_SIC_BTDCC_FTDCOFF_MASK) + #ifdef CONFIG_CAN_NXP_S32_RX_FIFO /* RX FIFO depth is fixed to the maximum value */ #define CAN_NXP_S32_RX_FIFO_DEPTH 32 @@ -706,6 +708,9 @@ static int can_nxp_s32_set_timing_data(const struct device *dev, /* Set timing for CAN FD instance*/ CanXL_SetFDBaudRate(config->base_sic, &can_fd_time_segment); + Canexcel_Ip_SetTDCOffsetFD(config->instance, true, false, + CAN_CALC_TDCO((timing_data), 0U, CAN_NXP_S32_TDCO_MAX)); + return 0; } #endif @@ -931,7 +936,7 @@ static int can_nxp_s32_init(const struct device *dev) IP_MC_RGM->PRST_0[0].PRST_0 &= ~(MC_RGM_PRST_0_PERIPH_16_RST_MASK | MC_RGM_PRST_0_PERIPH_24_RST_MASK); - err = can_calc_timing(dev, &data->timing, config->common.bus_speed, + err = can_calc_timing(dev, &data->timing, config->common.bitrate, config->common.sample_point); if (err == -EINVAL) { LOG_ERR("Can't find timing for given param"); @@ -942,11 +947,11 @@ static int can_nxp_s32_init(const struct device *dev) LOG_WRN("Sample-point error : %d", err); } - LOG_DBG("Setting CAN bitrate %d:", config->common.bus_speed); + LOG_DBG("Setting CAN bitrate %d:", config->common.bitrate); nxp_s32_zcan_timing_to_canxl_timing(&data->timing, &config->can_cfg->bitrate); #ifdef CAN_NXP_S32_FD_MODE - err = can_calc_timing_data(dev, &data->timing_data, config->common.bus_speed_data, + err = can_calc_timing_data(dev, &data->timing_data, config->common.bitrate_data, config->common.sample_point_data); if (err == -EINVAL) { LOG_ERR("Can't find timing data for given param"); @@ -957,13 +962,18 @@ static int can_nxp_s32_init(const struct device *dev) LOG_WRN("Sample-point-data err : %d", err); } - LOG_DBG("Setting CAN FD bitrate %d:", config->common.bus_speed_data); + LOG_DBG("Setting CAN FD bitrate %d:", config->common.bitrate_data); nxp_s32_zcan_timing_to_canxl_timing(&data->timing_data, &config->can_cfg->Fd_bitrate); #endif /* Initialize CAN structure */ Canexcel_Ip_Init(config->instance, config->can_cfg, data->can_state); +#ifdef CAN_NXP_S32_FD_MODE + Canexcel_Ip_SetTDCOffsetFD(config->instance, true, false, + CAN_CALC_TDCO((&data->timing_data), 0U, CAN_NXP_S32_TDCO_MAX)); +#endif + /* Configure time stamp */ #ifdef CONFIG_CAN_RX_TIMESTAMP Canexcel_Ip_ConfigTimeStamp(config->instance, &time_stamp); diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index d1607a6797a935..23bd82896cbe81 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -1075,7 +1075,7 @@ static int can_rcar_init(const struct device *dev) return ret; } - ret = can_calc_timing(dev, &timing, config->common.bus_speed, + ret = can_calc_timing(dev, &timing, config->common.bitrate, config->common.sample_point); if (ret == -EINVAL) { LOG_ERR("Can't find timing for given param"); diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index 871f0fdb00ddd9..758715bb443034 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -781,7 +781,7 @@ int can_sja1000_init(const struct device *dev) can_sja1000_write_reg(dev, CAN_SJA1000_AMR2, 0xFF); can_sja1000_write_reg(dev, CAN_SJA1000_AMR3, 0xFF); - err = can_calc_timing(dev, &timing, config->common.bus_speed, + err = can_calc_timing(dev, &timing, config->common.bitrate, config->common.sample_point); if (err == -EINVAL) { LOG_ERR("bitrate/sample point cannot be met (err %d)", err); diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index c21099c04b3a0c..5c3e44dfd0c3c6 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -659,7 +659,7 @@ static int can_stm32_init(const struct device *dev) /* Enable automatic bus-off recovery */ can->MCR |= CAN_MCR_ABOM; - ret = can_calc_timing(dev, &timing, cfg->common.bus_speed, + ret = can_calc_timing(dev, &timing, cfg->common.bitrate, cfg->common.sample_point); if (ret == -EINVAL) { LOG_ERR("Can't find timing for given param"); diff --git a/drivers/can/can_xmc4xxx.c b/drivers/can/can_xmc4xxx.c index 8eddf05b96ea9f..2704ef1b44edb5 100644 --- a/drivers/can/can_xmc4xxx.c +++ b/drivers/can/can_xmc4xxx.c @@ -869,7 +869,7 @@ static int can_xmc4xxx_init(const struct device *dev) } #endif - ret = can_calc_timing(dev, &timing, dev_cfg->common.bus_speed, + ret = can_calc_timing(dev, &timing, dev_cfg->common.bitrate, dev_cfg->common.sample_point); if (ret < 0) { return ret; diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 949d87d1a666d5..43f86e8c7d38cf 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -38,6 +38,8 @@ if(CONFIG_SOC_SERIES_STM32MP1X) zephyr_library_sources(clock_stm32_ll_mp1.c) elseif(CONFIG_SOC_SERIES_STM32H7X) zephyr_library_sources(clock_stm32_ll_h7.c) +elseif(CONFIG_SOC_SERIES_STM32H7RSX) + zephyr_library_sources(clock_stm32_ll_h7.c) elseif(CONFIG_SOC_SERIES_STM32H5X) zephyr_library_sources(clock_stm32_ll_h5.c) elseif(CONFIG_SOC_SERIES_STM32U5X) diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index 725a76949869fd..37e09ce21a9980 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -132,7 +132,7 @@ choice CLOCK_CONTROL_NRF_ACCURACY_PPM prompt "32KHz clock accuracy" default CLOCK_CONTROL_NRF_K32SRC_500PPM if CLOCK_CONTROL_NRF_K32SRC_RC && SOC_COMPATIBLE_NRF52X default CLOCK_CONTROL_NRF_K32SRC_250PPM if CLOCK_CONTROL_NRF_K32SRC_RC - default CLOCK_CONTROL_NRF_K32SRC_150PPM if CLOCK_CONTROL_NRF_K32SRC_XTAL && SOC_SERIES_NRF54LX + default CLOCK_CONTROL_NRF_K32SRC_150PPM if CLOCK_CONTROL_NRF_K32SRC_XTAL && SOC_COMPATIBLE_NRF54LX default CLOCK_CONTROL_NRF_K32SRC_50PPM config CLOCK_CONTROL_NRF_K32SRC_500PPM diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 index c5f4f27364622a..484b331db7c241 100644 --- a/drivers/clock_control/Kconfig.stm32 +++ b/drivers/clock_control/Kconfig.stm32 @@ -9,7 +9,7 @@ menuconfig CLOCK_CONTROL_STM32_CUBE depends on SOC_FAMILY_STM32 select USE_STM32_LL_UTILS select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X) + SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X) select RUNTIME_NMI if ($(dt_nodelabel_enabled,clk_hse) && \ $(dt_nodelabel_has_prop,clk_hse,css-enabled)) help @@ -69,6 +69,7 @@ config CLOCK_STM32_MCO1_SRC_LSE SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32L4X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use LSE as source of MCO1 @@ -80,6 +81,7 @@ config CLOCK_STM32_MCO1_SRC_HSE SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32L4X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use HSE as source of MCO1 @@ -102,6 +104,7 @@ config CLOCK_STM32_MCO1_SRC_HSI SOC_SERIES_STM32F4X || \ SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use HSI as source of MCO1 @@ -116,6 +119,7 @@ config CLOCK_STM32_MCO1_SRC_HSI48 bool "HSI48" depends on SOC_SERIES_STM32L4X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use HSI48 as source of MCO1 @@ -129,6 +133,7 @@ config CLOCK_STM32_MCO1_SRC_PLLCLK config CLOCK_STM32_MCO1_SRC_PLLQCLK bool "PLLQ" depends on SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use PLLQ as source of MCO1 @@ -171,11 +176,12 @@ config CLOCK_STM32_MCO1_DIV SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32L4X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X \ ) default 1 range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X + range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X range 1 16 if SOC_SERIES_STM32L4X help Prescaler for MCO1 output clock @@ -194,6 +200,7 @@ config CLOCK_STM32_MCO2_SRC_SYSCLK depends on SOC_SERIES_STM32F4X || \ SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use SYSCLK as source of MCO2 @@ -209,6 +216,7 @@ config CLOCK_STM32_MCO2_SRC_HSE depends on SOC_SERIES_STM32F4X || \ SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use HSE as source of MCO2 @@ -216,6 +224,7 @@ config CLOCK_STM32_MCO2_SRC_HSE config CLOCK_STM32_MCO2_SRC_LSI bool "LSI" depends on SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use LSI as source of MCO2 @@ -223,6 +232,7 @@ config CLOCK_STM32_MCO2_SRC_LSI config CLOCK_STM32_MCO2_SRC_CSI bool "CSI" depends on SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use CSI as source of MCO2 @@ -236,6 +246,7 @@ config CLOCK_STM32_MCO2_SRC_PLLCLK config CLOCK_STM32_MCO2_SRC_PLLPCLK bool "PLLPCLK" depends on SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use PLLPCLK as source of MC02 @@ -243,6 +254,7 @@ config CLOCK_STM32_MCO2_SRC_PLLPCLK config CLOCK_STM32_MCO2_SRC_PLL2PCLK bool "PLL2PCLK" depends on SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX || \ SOC_SERIES_STM32H5X help Use PLL2PCLK as source of MC02 @@ -254,11 +266,12 @@ config CLOCK_STM32_MCO2_DIV SOC_SERIES_STM32F4X || \ SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32H7X \ + SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32H7RSX \ ) default 1 range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X + range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X help Prescaler for MCO2 output clock diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index c62402ed665ca9..3dd40792486ee8 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -53,95 +53,84 @@ #include LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL); -static enum clock_control_status clock_control_esp32_get_status(const struct device *dev, - clock_control_subsys_t sys) -{ - ARG_UNUSED(dev); - uint32_t clk_en_reg = periph_ll_get_clk_en_reg((periph_module_t)sys); - uint32_t clk_en_mask = periph_ll_get_clk_en_mask((periph_module_t)sys); - - if (DPORT_GET_PERI_REG_MASK(clk_en_reg, clk_en_mask)) { - return CLOCK_CONTROL_STATUS_ON; - } - return CLOCK_CONTROL_STATUS_OFF; -} - -static int clock_control_esp32_on(const struct device *dev, clock_control_subsys_t sys) -{ - enum clock_control_status status = clock_control_esp32_get_status(dev, sys); - - if (status == CLOCK_CONTROL_STATUS_ON) { - return -EALREADY; - } - - periph_module_enable((periph_module_t)sys); - - return 0; -} - -static int clock_control_esp32_off(const struct device *dev, clock_control_subsys_t sys) +static bool reset_reason_is_cpu_reset(void) { - enum clock_control_status status = clock_control_esp32_get_status(dev, sys); - - if (status == CLOCK_CONTROL_STATUS_ON) { - periph_module_disable((periph_module_t)sys); - } - - return 0; -} - -static int clock_control_esp32_get_rate(const struct device *dev, clock_control_subsys_t sys, - uint32_t *rate) -{ - ARG_UNUSED(dev); + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - switch ((int)sys) { - case ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST: - *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); - break; - case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW: - *rate = clk_hal_lp_slow_get_freq_hz(); - break; - default: - *rate = clk_hal_cpu_get_freq_hz(); + if ((rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || + rst_reason == RESET_REASON_CPU0_RTC_WDT +#if !defined(CONFIG_SOC_SERIES_ESP32) + || rst_reason == RESET_REASON_CPU0_MWDT1 +#endif + )) { + return true; } - - return 0; + return false; } -#if defined(CONFIG_SOC_SERIES_ESP32) static void esp32_clock_perip_init(void) { uint32_t common_perip_clk; uint32_t hwcrypto_perip_clk; uint32_t wifi_bt_sdio_clk; - -#if !CONFIG_SMP - soc_reset_reason_t rst_reas[1]; -#else - soc_reset_reason_t rst_reas[2]; -#endif - - rst_reas[0] = esp_rom_get_reset_reason(0); -#if CONFIG_SMP - rst_reas[1] = esp_rom_get_reset_reason(1); +#if !defined(CONFIG_SOC_SERIES_ESP32) + uint32_t common_perip_clk1; #endif /* For reason that only reset CPU, do not disable the clocks * that have been enabled before reset. */ - if ((rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_SW || - rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) -#if CONFIG_SMP - || (rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_SW || - rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) -#endif - ) { + if (reset_reason_is_cpu_reset()) { +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) + common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); + hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); + wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERI_CLK_EN_REG); wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG); +#endif + +#if defined(CONFIG_SOC_SERIES_ESP32S2) + hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN1_REG); +#endif } else { - common_perip_clk = DPORT_WDG_CLK_EN | + common_perip_clk = +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) + SYSTEM_WDG_CLK_EN | + SYSTEM_I2S0_CLK_EN | +#if ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if ESP_CONSOLE_UART_NUM != 1 + SYSTEM_UART1_CLK_EN | +#endif +#if defined(CONFIG_SOC_SERIES_ESP32S3) +#if ESP_CONSOLE_UART_NUM != 2 + SYSTEM_UART2_CLK_EN | +#endif + SYSTEM_USB_CLK_EN | + SYSTEM_PCNT_CLK_EN | + SYSTEM_LEDC_CLK_EN | + SYSTEM_PWM0_CLK_EN | + SYSTEM_PWM1_CLK_EN | + SYSTEM_PWM2_CLK_EN | + SYSTEM_PWM3_CLK_EN | +#endif /* CONFIG_SOC_SERIES_ESP32S3 */ + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_LEDC_CLK_EN | + SYSTEM_TIMERGROUP1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_TWAI_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_WDG_CLK_EN | DPORT_PCNT_CLK_EN | DPORT_LEDC_CLK_EN | DPORT_TIMERGROUP1_CLK_EN | @@ -149,228 +138,77 @@ static void esp32_clock_perip_init(void) DPORT_TWAI_CLK_EN | DPORT_PWM1_CLK_EN | DPORT_PWM2_CLK_EN | - DPORT_PWM3_CLK_EN; - - hwcrypto_perip_clk = DPORT_PERI_EN_AES | - DPORT_PERI_EN_SHA | - DPORT_PERI_EN_RSA | - DPORT_PERI_EN_SECUREBOOT; - - wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN | - DPORT_WIFI_CLK_BT_EN_M | - DPORT_WIFI_CLK_UNUSED_BIT5 | - DPORT_WIFI_CLK_UNUSED_BIT12 | - DPORT_WIFI_CLK_SDIOSLAVE_EN | - DPORT_WIFI_CLK_SDIO_HOST_EN | - DPORT_WIFI_CLK_EMAC_EN; - } - - /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */ - common_perip_clk |= DPORT_I2S0_CLK_EN | - DPORT_UART_CLK_EN | - DPORT_SPI2_CLK_EN | - DPORT_I2C_EXT0_CLK_EN | - DPORT_UHCI0_CLK_EN | - DPORT_RMT_CLK_EN | - DPORT_UHCI1_CLK_EN | - DPORT_SPI3_CLK_EN | - DPORT_I2C_EXT1_CLK_EN | - DPORT_I2S1_CLK_EN | - DPORT_SPI_DMA_CLK_EN; - - common_perip_clk &= ~DPORT_SPI01_CLK_EN; - common_perip_clk &= ~DPORT_SPI2_CLK_EN; - common_perip_clk &= ~DPORT_SPI3_CLK_EN; - - /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, - * the current is not reduced when disable I2S clock. - */ - DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA); - DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA); - - /* Disable some peripheral clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk); - - /* Disable hardware crypto clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk); - DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk); - - /* Disable WiFi/BT/SDIO clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); - - /* Enable RNG clock. */ - periph_module_enable(PERIPH_RNG_MODULE); -} -#endif /* CONFIG_SOC_SERIES_ESP32 */ - #if defined(CONFIG_SOC_SERIES_ESP32S2) -static void esp32_clock_perip_init(void) -{ - uint32_t common_perip_clk; - uint32_t hwcrypto_perip_clk; - uint32_t wifi_bt_sdio_clk; - uint32_t common_perip_clk1; - - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - - /* For reason that only reset CPU, do not disable the clocks - * that have been enabled before reset. - */ - if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || - rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { - common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); - hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN1_REG); - wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG); - } else { - common_perip_clk = DPORT_WDG_CLK_EN | DPORT_I2S0_CLK_EN | - DPORT_UART1_CLK_EN | DPORT_SPI2_CLK_EN | DPORT_I2C_EXT0_CLK_EN | DPORT_UHCI0_CLK_EN | DPORT_RMT_CLK_EN | - DPORT_PCNT_CLK_EN | - DPORT_LEDC_CLK_EN | - DPORT_TIMERGROUP1_CLK_EN | DPORT_SPI3_CLK_EN | - DPORT_PWM0_CLK_EN | - DPORT_TWAI_CLK_EN | - DPORT_PWM1_CLK_EN | DPORT_I2S1_CLK_EN | DPORT_SPI2_DMA_CLK_EN | DPORT_SPI3_DMA_CLK_EN | - DPORT_PWM2_CLK_EN | +#endif /* CONFIG_SOC_SERIES_ESP32S2 */ DPORT_PWM3_CLK_EN; +#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */ +#if !defined(CONFIG_SOC_SERIES_ESP32) common_perip_clk1 = 0; - - hwcrypto_perip_clk = DPORT_CRYPTO_AES_CLK_EN | - DPORT_CRYPTO_SHA_CLK_EN | - DPORT_CRYPTO_RSA_CLK_EN; - - wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN | +#endif + hwcrypto_perip_clk = +#if defined(CONFIG_SOC_SERIES_ESP32) + DPORT_PERI_EN_AES | + DPORT_PERI_EN_SHA | + DPORT_PERI_EN_RSA | + DPORT_PERI_EN_SECUREBOOT; +#endif /* CONFIG_SOC_SERIES_ESP32 */ +#if defined(CONFIG_SOC_SERIES_ESP32S2) + DPORT_CRYPTO_AES_CLK_EN | + DPORT_CRYPTO_SHA_CLK_EN | + DPORT_CRYPTO_RSA_CLK_EN; +#endif /* CONFIG_SOC_SERIES_ESP32S2 */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) + SYSTEM_CRYPTO_AES_CLK_EN | + SYSTEM_CRYPTO_SHA_CLK_EN | + SYSTEM_CRYPTO_RSA_CLK_EN; +#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */ + + wifi_bt_sdio_clk = +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) + SYSTEM_WIFI_CLK_WIFI_EN | + SYSTEM_WIFI_CLK_BT_EN_M | + SYSTEM_WIFI_CLK_I2C_CLK_EN | +#if defined(CONFIG_SOC_SERIES_ESP32S3) + SYSTEM_WIFI_CLK_SDIO_HOST_EN | +#endif /* CONFIG_SOC_SERIES_ESP32S3 */ + SYSTEM_WIFI_CLK_UNUSED_BIT12; +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_WIFI_CLK_WIFI_EN | DPORT_WIFI_CLK_BT_EN_M | DPORT_WIFI_CLK_UNUSED_BIT5 | DPORT_WIFI_CLK_UNUSED_BIT12 | DPORT_WIFI_CLK_SDIOSLAVE_EN | DPORT_WIFI_CLK_SDIO_HOST_EN | DPORT_WIFI_CLK_EMAC_EN; +#endif /* CONFIG_SOC_SERIES_ESP32C3 */ } /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */ - common_perip_clk |= DPORT_I2S0_CLK_EN | - DPORT_UART1_CLK_EN | - DPORT_USB_CLK_EN | - DPORT_SPI2_CLK_EN | - DPORT_I2C_EXT0_CLK_EN | - DPORT_UHCI0_CLK_EN | - DPORT_RMT_CLK_EN | - DPORT_UHCI1_CLK_EN | - DPORT_SPI3_CLK_EN | - DPORT_I2C_EXT1_CLK_EN | - DPORT_I2S1_CLK_EN | - DPORT_SPI2_DMA_CLK_EN | - DPORT_SPI3_DMA_CLK_EN; - - common_perip_clk1 = 0; - - /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, - * the current is not reduced when disable I2S clock. - */ - REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); - - /* Disable some peripheral clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk); - - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, common_perip_clk1); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, common_perip_clk1); - - /* Disable hardware crypto clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, hwcrypto_perip_clk); - - /* Disable WiFi/BT/SDIO clocks. */ - DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); - - /* Enable WiFi MAC and POWER clocks */ - DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN); - - /* Set WiFi light sleep clock source to RTC slow clock */ - DPORT_REG_SET_FIELD(DPORT_BT_LPCK_DIV_INT_REG, DPORT_BT_LPCK_DIV_NUM, 0); - DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M); - DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW); - - /* Enable RNG clock. */ - periph_module_enable(PERIPH_RNG_MODULE); -} -#endif /* CONFIG_SOC_SERIES_ESP32S2 */ - -#if defined(CONFIG_SOC_SERIES_ESP32S3) -static void esp32_clock_perip_init(void) -{ -#if defined(CONFIG_SOC_ESP32S3_APPCPU) - /* skip APPCPU configuration */ - return; -#endif - - uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; - uint32_t common_perip_clk1 = 0; - - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - - /* For reason that only reset CPU, do not disable the clocks - * that have been enabled before reset. - */ - if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || - rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { - common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); - wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); - } else { - common_perip_clk = SYSTEM_WDG_CLK_EN | + common_perip_clk |= +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) SYSTEM_I2S0_CLK_EN | +#if ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if ESP_CONSOLE_UART_NUM != 1 SYSTEM_UART1_CLK_EN | +#endif +#if defined(CONFIG_SOC_SERIES_ESP32S3) +#if ESP_CONSOLE_UART_NUM != 2 SYSTEM_UART2_CLK_EN | +#endif SYSTEM_USB_CLK_EN | - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_PCNT_CLK_EN | - SYSTEM_LEDC_CLK_EN | - SYSTEM_TIMERGROUP1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_PWM0_CLK_EN | - SYSTEM_TWAI_CLK_EN | - SYSTEM_PWM1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN | - SYSTEM_PWM2_CLK_EN | - SYSTEM_PWM3_CLK_EN; - - common_perip_clk1 = 0; - - hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | - SYSTEM_CRYPTO_SHA_CLK_EN | - SYSTEM_CRYPTO_RSA_CLK_EN; - - wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | - SYSTEM_WIFI_CLK_BT_EN_M | - SYSTEM_WIFI_CLK_I2C_CLK_EN | - SYSTEM_WIFI_CLK_UNUSED_BIT12 | - SYSTEM_WIFI_CLK_SDIO_HOST_EN; - } - - /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */ - common_perip_clk |= SYSTEM_I2S0_CLK_EN | - SYSTEM_UART1_CLK_EN | - SYSTEM_UART2_CLK_EN | - SYSTEM_USB_CLK_EN | +#endif SYSTEM_SPI2_CLK_EN | SYSTEM_I2C_EXT0_CLK_EN | SYSTEM_UHCI0_CLK_EN | @@ -382,131 +220,172 @@ static void esp32_clock_perip_init(void) SYSTEM_I2S1_CLK_EN | SYSTEM_SPI2_DMA_CLK_EN | SYSTEM_SPI3_DMA_CLK_EN; +#else + DPORT_I2S0_CLK_EN | + DPORT_SPI2_CLK_EN | + DPORT_I2C_EXT0_CLK_EN | + DPORT_UHCI0_CLK_EN | + DPORT_RMT_CLK_EN | + DPORT_UHCI1_CLK_EN | + DPORT_SPI3_CLK_EN | + DPORT_I2C_EXT1_CLK_EN | +#if ESP_CONSOLE_UART_NUM != 0 + DPORT_UART_CLK_EN | +#endif +#if ESP_CONSOLE_UART_NUM != 1 + DPORT_UART1_CLK_EN | +#endif +#if defined(CONFIG_SOC_SERIES_ESP32) + DPORT_SPI_DMA_CLK_EN | +#if ESP_CONSOLE_UART_NUM != 2 + DPORT_UART2_CLK_EN | +#endif +#endif /* CONFIG_SOC_SERIES_ESP32 */ +#if defined(CONFIG_SOC_SERIES_ESP32S2) + DPORT_USB_CLK_EN | + DPORT_SPI2_DMA_CLK_EN | + DPORT_SPI3_DMA_CLK_EN | +#endif /* CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_I2S1_CLK_EN; +#endif /* CONFIG_SOC_SERIES_ESP32C3 */ +#if !defined(CONFIG_SOC_SERIES_ESP32) common_perip_clk1 = 0; +#endif + +#if defined(CONFIG_SOC_SERIES_ESP32) + common_perip_clk &= ~DPORT_SPI01_CLK_EN; +#if defined(CONFIG_SPIRAM_SPEED_80M) + /* + * 80MHz SPIRAM uses SPI2/SPI3 as well; it's initialized before this is called. Because it + * is used in a weird mode where clock to the peripheral is disabled but reset is also + * disabled, it 'hangs' in a state where it outputs a continuous 80MHz signal. Mask its bit + * here because we should not modify that state, regardless of what we calculated earlier. + */ + common_perip_clk &= ~DPORT_SPI2_CLK_EN; + common_perip_clk &= ~DPORT_SPI3_CLK_EN; +#endif +#endif /* CONFIG_SOC_SERIES_ESP32 */ + + /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, + * the current is not reduced when disable I2S clock. + */ +#if defined(CONFIG_SOC_SERIES_ESP32) + DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA); + DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA); +#endif /* CONFIG_SOC_SERIES_ESP32 */ +#if defined(CONFIG_SOC_SERIES_ESP32S2) + REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); + REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); +#endif /* CONFIG_SOC_SERIES_ESP32S2 */ /* Disable some peripheral clocks. */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk); + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk); +#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */ /* Disable hardware crypto clocks. */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk); + DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk); +#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */ + +#if defined(CONFIG_SOC_SERIES_ESP32S3) + /* Force clear backup dma reset signal. This is a fix to the backup dma + * implementation in the ROM, the reset signal was not cleared when the + * backup dma was started, which caused the backup dma operation to fail. + */ + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_PERI_BACKUP_RST); +#endif /* CONFIG_SOC_SERIES_ESP32S3 */ /* Disable WiFi/BT/SDIO clocks. */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); +#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */ + DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); +#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); +#endif /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); - /* Enable TimerGroup 0 clock to ensure its reference counter will never - * be decremented to 0 during normal operation and preventing it from - * being disabled. - * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog - * registers (Flashboot protection included) will be reenabled, and some - * seconds later, will trigger an unintended reset. - */ +#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) periph_module_enable(PERIPH_TIMG0_MODULE); +#endif } -#endif /* CONFIG_SOC_SERIES_ESP32S3 */ -#if defined(CONFIG_SOC_SERIES_ESP32C3) -static void esp32_clock_perip_init(void) +static enum clock_control_status clock_control_esp32_get_status(const struct device *dev, + clock_control_subsys_t sys) { - uint32_t common_perip_clk; - uint32_t hwcrypto_perip_clk; - uint32_t wifi_bt_sdio_clk; - uint32_t common_perip_clk1; - - soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - - /* For reason that only reset CPU, do not disable the clocks - * that have been enabled before reset. - */ - if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || - rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { - common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); - wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); - } else { - common_perip_clk = SYSTEM_WDG_CLK_EN | - SYSTEM_I2S0_CLK_EN | - SYSTEM_UART1_CLK_EN | - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_LEDC_CLK_EN | - SYSTEM_TIMERGROUP1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_TWAI_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; + ARG_UNUSED(dev); + uint32_t clk_en_reg = periph_ll_get_clk_en_reg((periph_module_t)sys); + uint32_t clk_en_mask = periph_ll_get_clk_en_mask((periph_module_t)sys); - common_perip_clk1 = 0; + if (DPORT_GET_PERI_REG_MASK(clk_en_reg, clk_en_mask)) { + return CLOCK_CONTROL_STATUS_ON; + } + return CLOCK_CONTROL_STATUS_OFF; +} - hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | - SYSTEM_CRYPTO_SHA_CLK_EN | - SYSTEM_CRYPTO_RSA_CLK_EN; +static int clock_control_esp32_on(const struct device *dev, clock_control_subsys_t sys) +{ + enum clock_control_status status = clock_control_esp32_get_status(dev, sys); - wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | - SYSTEM_WIFI_CLK_BT_EN_M | - SYSTEM_WIFI_CLK_I2C_CLK_EN | - SYSTEM_WIFI_CLK_UNUSED_BIT12; + if (status == CLOCK_CONTROL_STATUS_ON && !reset_reason_is_cpu_reset()) { + return -EALREADY; } - /* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */ - common_perip_clk |= SYSTEM_I2S0_CLK_EN | - SYSTEM_UART1_CLK_EN | - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_UHCI1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_I2C_EXT1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; + periph_module_enable((periph_module_t)sys); - common_perip_clk1 = 0; + return 0; +} - /* Disable some peripheral clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); +static int clock_control_esp32_off(const struct device *dev, clock_control_subsys_t sys) +{ + enum clock_control_status status = clock_control_esp32_get_status(dev, sys); - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); + if (status == CLOCK_CONTROL_STATUS_ON) { + periph_module_disable((periph_module_t)sys); + } - /* Disable hardware crypto clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); + return 0; +} - /* Disable WiFi/BT/SDIO clocks. */ - CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); - SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); +static int clock_control_esp32_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + ARG_UNUSED(dev); - /* Set WiFi light sleep clock source to RTC slow clock */ - REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); - SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); + switch ((int)sys) { + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST: + *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + break; + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW: + *rate = clk_hal_lp_slow_get_freq_hz(); + break; + default: + *rate = clk_hal_cpu_get_freq_hz(); + } - /* Enable RNG clock. */ - periph_module_enable(PERIPH_RNG_MODULE); + return 0; } -#endif /* CONFIG_SOC_SERIES_ESP32C3 */ static int esp32_select_rtc_slow_clk(uint8_t slow_clk) { @@ -619,7 +498,12 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * rtc_clk_cfg.cpu_freq_mhz / old_config.freq_mhz); +#if ESP_ROM_UART_CLK_IS_XTAL + uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); +#else uart_clock_src_hz = esp_clk_apb_freq(); +#endif + #if !defined(ESP_CONSOLE_UART_NONE) esp_rom_uart_set_clock_baudrate(ESP_CONSOLE_UART_NUM, uart_clock_src_hz, ESP_CONSOLE_UART_BAUDRATE); @@ -666,7 +550,6 @@ static int clock_control_esp32_init(const struct device *dev) soc_reset_reason_t rst_reas; rtc_config_t rtc_cfg = RTC_CONFIG_DEFAULT(); bool ret; - uint32_t uart_clock_src_hz; rst_reas = esp_rom_get_reset_reason(0); #if !defined(CONFIG_SOC_SERIES_ESP32) @@ -686,14 +569,6 @@ static int clock_control_esp32_init(const struct device *dev) return ret; } -#if defined(CONFIG_SOC_SERIES_ESP32S3) - uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); -#if !defined(ESP_CONSOLE_UART_NONE) - esp_rom_uart_set_clock_baudrate(ESP_CONSOLE_UART_NUM, uart_clock_src_hz, - ESP_CONSOLE_UART_BAUDRATE); -#endif -#endif - rtc_clk_fast_src_set(cfg->rtc.rtc_fast_clock_src); ret = esp32_select_rtc_slow_clk(cfg->rtc.rtc_slow_clock_src); diff --git a/drivers/clock_control/clock_control_gd32.c b/drivers/clock_control/clock_control_gd32.c index e7f1f739a8be3f..1a20d5e4ab2105 100644 --- a/drivers/clock_control/clock_control_gd32.c +++ b/drivers/clock_control/clock_control_gd32.c @@ -198,7 +198,7 @@ clock_control_gd32_get_status(const struct device *dev, return CLOCK_CONTROL_STATUS_OFF; } -static struct clock_control_driver_api clock_control_gd32_api = { +static const struct clock_control_driver_api clock_control_gd32_api = { .on = clock_control_gd32_on, .off = clock_control_gd32_off, .get_rate = clock_control_gd32_get_rate, diff --git a/drivers/clock_control/clock_control_litex.c b/drivers/clock_control/clock_control_litex.c index 2eb0c6b358981f..06d3d1264baaa2 100644 --- a/drivers/clock_control/clock_control_litex.c +++ b/drivers/clock_control/clock_control_litex.c @@ -26,7 +26,7 @@ static struct litex_clk_device *ldev; /* global struct for whole driver */ static struct litex_clk_clkout *clkouts;/* clkout array for whole driver */ /* All DRP regs addresses and sizes */ -static struct litex_drp_reg drp[] = { +static const struct litex_drp_reg drp[] = { {DRP_ADDR_RESET, 1}, {DRP_ADDR_LOCKED, 1}, {DRP_ADDR_READ, 1}, @@ -905,11 +905,15 @@ static int litex_clk_calc_duty_normal(struct litex_clk_clkout *lcko, uint32_t ht_aprox, synth_duty, min_d; uint8_t high_time_it, edge_it, high_duty, divider = lcko->config.div; + int err; if (calc_new) { duty = lcko->ts_config.duty; } else { - litex_clk_get_duty_cycle(lcko, &duty); + err = litex_clk_get_duty_cycle(lcko, &duty); + if (err != 0) { + return err; + } } high_duty = litex_clk_calc_duty_percent(&duty); @@ -1127,9 +1131,13 @@ int litex_clk_get_phase(struct litex_clk_clkout *lcko) uint32_t divider = 0, fract_cnt, post_glob_div_f, pm, global_period, clkout_period, period; uint8_t phase_mux = 0, delay_time = 0; + int err = 0; litex_clk_get_phase_data(lcko, &phase_mux, &delay_time); - litex_clk_get_clkout_divider(lcko, ÷r, &fract_cnt); + err = litex_clk_get_clkout_divider(lcko, ÷r, &fract_cnt); + if (err != 0) { + return err; + } post_glob_div_f = (uint32_t)litex_clk_get_real_global_frequency(); period_buff = PICOS_IN_SEC; diff --git a/drivers/clock_control/clock_control_mchp_xec.c b/drivers/clock_control/clock_control_mchp_xec.c index 11b0b54ac41fc1..c3ff0bbb78f2c4 100644 --- a/drivers/clock_control/clock_control_mchp_xec.c +++ b/drivers/clock_control/clock_control_mchp_xec.c @@ -1014,7 +1014,7 @@ void mchp_xec_clk_ctrl_sys_sleep_disable(void) #endif /* Clock controller driver registration */ -static struct clock_control_driver_api xec_clock_control_api = { +static const struct clock_control_driver_api xec_clock_control_api = { .on = xec_clock_control_on, .off = xec_clock_control_off, .get_rate = xec_clock_control_get_subsys_rate, diff --git a/drivers/clock_control/clock_control_mcux_ccm_rev2.c b/drivers/clock_control/clock_control_mcux_ccm_rev2.c index f3e7c59aea36c1..188fe976df4f9a 100644 --- a/drivers/clock_control/clock_control_mcux_ccm_rev2.c +++ b/drivers/clock_control/clock_control_mcux_ccm_rev2.c @@ -20,6 +20,10 @@ static int mcux_ccm_on(const struct device *dev, #ifdef CONFIG_ETH_NXP_ENET if ((uint32_t)sub_system == IMX_CCM_ENET_CLK) { CLOCK_EnableClock(kCLOCK_Enet); +#ifdef CONFIG_ETH_NXP_ENET_1G + } else if ((uint32_t)sub_system == IMX_CCM_ENET1G_CLK) { + CLOCK_EnableClock(kCLOCK_Enet_1g); +#endif } #endif return 0; @@ -111,6 +115,7 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, #ifdef CONFIG_ETH_NXP_ENET case IMX_CCM_ENET_CLK: + case IMX_CCM_ENET1G_CLK: clock_root = kCLOCK_Root_Bus; break; #endif @@ -139,6 +144,15 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, break; #endif +#ifdef CONFIG_PWM_MCUX_QTMR + case IMX_CCM_QTMR1_CLK: + case IMX_CCM_QTMR2_CLK: + case IMX_CCM_QTMR3_CLK: + case IMX_CCM_QTMR4_CLK: + clock_root = kCLOCK_Root_Bus; + break; +#endif + #ifdef CONFIG_MEMC_MCUX_FLEXSPI case IMX_CCM_FLEXSPI_CLK: clock_root = kCLOCK_Root_Flexspi1; diff --git a/drivers/clock_control/clock_control_mcux_scg.c b/drivers/clock_control/clock_control_mcux_scg.c index 0a88fc9066697c..2898766e452cd5 100644 --- a/drivers/clock_control/clock_control_mcux_scg.c +++ b/drivers/clock_control/clock_control_mcux_scg.c @@ -46,7 +46,7 @@ static int mcux_scg_get_rate(const struct device *dev, case KINETIS_SCG_BUS_CLK: clock_name = kCLOCK_BusClk; break; -#if !defined(CONFIG_SOC_MKE17Z7) +#if !(defined(CONFIG_SOC_MKE17Z7) || defined(CONFIG_SOC_MKE17Z9)) case KINETIS_SCG_FLEXBUS_CLK: clock_name = kCLOCK_FlexBusClk; break; diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 93a9f1db4ac71f..d0d881541e1821 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -71,6 +71,29 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, } #endif +#if defined(CONFIG_CAN_MCUX_FLEXCAN) + switch ((uint32_t)sub_system) { + case MCUX_FLEXCAN0_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan0); + break; + case MCUX_FLEXCAN1_CLK: + CLOCK_EnableClock(kCLOCK_Flexcan1); + break; + default: + break; + } +#endif /* defined(CONFIG_CAN_MCUX_MCAN) */ + +#ifdef CONFIG_ETH_NXP_ENET + if ((uint32_t)sub_system == MCUX_ENET_CLK) { +#ifdef CONFIG_SOC_SERIES_RW6XX + CLOCK_EnableClock(kCLOCK_TddrMciEnetClk); + CLOCK_EnableClock(kCLOCK_EnetIpg); + CLOCK_EnableClock(kCLOCK_EnetIpgS); +#endif + } +#endif + return 0; } @@ -292,6 +315,14 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate( break; #endif +#ifdef CONFIG_ETH_NXP_ENET + case MCUX_ENET_CLK: +#ifdef CONFIG_SOC_SERIES_RW6XX + *rate = CLOCK_GetTddrMciEnetClkFreq(); +#endif + break; +#endif + #if defined(CONFIG_MIPI_DBI_NXP_LCDIC) case MCUX_LCDIC_CLK: *rate = CLOCK_GetLcdClkFreq(); @@ -312,6 +343,15 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate( break; #endif #endif /* CONFIG_ADC_MCUX_LPADC */ + +#if defined(CONFIG_CAN_MCUX_FLEXCAN) + case MCUX_FLEXCAN0_CLK: + *rate = CLOCK_GetFlexcanClkFreq(0); + break; + case MCUX_FLEXCAN1_CLK: + *rate = CLOCK_GetFlexcanClkFreq(1); + break; +#endif /* defined(CONFIG_CAN_MCUX_FLEXCAN) */ } return 0; diff --git a/drivers/clock_control/clock_control_npcx.c b/drivers/clock_control/clock_control_npcx.c index eec3604aa7713c..3875b28da70594 100644 --- a/drivers/clock_control/clock_control_npcx.c +++ b/drivers/clock_control/clock_control_npcx.c @@ -147,7 +147,7 @@ void npcx_clock_control_turn_off_system_sleep(void) #endif /* CONFIG_PM */ /* Clock controller driver registration */ -static struct clock_control_driver_api npcx_clock_control_api = { +static const struct clock_control_driver_api npcx_clock_control_api = { .on = npcx_clock_control_on, .off = npcx_clock_control_off, .get_rate = npcx_clock_control_get_subsys_rate, diff --git a/drivers/clock_control/clock_control_nrf_auxpll.c b/drivers/clock_control/clock_control_nrf_auxpll.c index dc5ca849be0b83..e313b5c0560464 100644 --- a/drivers/clock_control/clock_control_nrf_auxpll.c +++ b/drivers/clock_control/clock_control_nrf_auxpll.c @@ -99,7 +99,7 @@ static enum clock_control_status clock_control_nrf_auxpll_get_status(const struc return CLOCK_CONTROL_STATUS_OFF; } -static struct clock_control_driver_api clock_control_nrf_auxpll_api = { +static const struct clock_control_driver_api clock_control_nrf_auxpll_api = { .on = clock_control_nrf_auxpll_on, .off = clock_control_nrf_auxpll_off, .get_rate = clock_control_nrf_auxpll_get_rate, diff --git a/drivers/clock_control/clock_control_numaker_scc.c b/drivers/clock_control/clock_control_numaker_scc.c index f33d2da120a863..af36931e00dc2a 100644 --- a/drivers/clock_control/clock_control_numaker_scc.c +++ b/drivers/clock_control/clock_control_numaker_scc.c @@ -95,7 +95,7 @@ static inline int numaker_scc_configure(const struct device *dev, clock_control_ } /* System clock controller driver registration */ -static struct clock_control_driver_api numaker_scc_api = { +static const struct clock_control_driver_api numaker_scc_api = { .on = numaker_scc_on, .off = numaker_scc_off, .get_rate = numaker_scc_get_rate, diff --git a/drivers/clock_control/clock_control_pwm.c b/drivers/clock_control/clock_control_pwm.c index 1936e3ab6cce25..92bcd31c91fe2b 100644 --- a/drivers/clock_control/clock_control_pwm.c +++ b/drivers/clock_control/clock_control_pwm.c @@ -129,7 +129,7 @@ static int clock_control_pwm_init(const struct device *dev) return 0; } -static struct clock_control_driver_api clock_control_pwm_api = { +static const struct clock_control_driver_api clock_control_pwm_api = { .on = clock_control_pwm_on, .get_rate = clock_control_pwm_get_rate, .set_rate = clock_control_pwm_set_rate, diff --git a/drivers/clock_control/clock_control_rv32m1_pcc.c b/drivers/clock_control/clock_control_rv32m1_pcc.c index e7ea06986aae79..9d22b9efae0d7d 100644 --- a/drivers/clock_control/clock_control_rv32m1_pcc.c +++ b/drivers/clock_control/clock_control_rv32m1_pcc.c @@ -58,7 +58,7 @@ static const struct clock_control_driver_api rv32m1_pcc_api = { }; #define RV32M1_PCC_INIT(inst) \ - static struct rv32m1_pcc_config rv32m1_pcc##inst##_config = { \ + static const struct rv32m1_pcc_config rv32m1_pcc##inst##_config = { \ .base_address = DT_INST_REG_ADDR(inst) \ }; \ \ diff --git a/drivers/clock_control/clock_control_sam_pmc.c b/drivers/clock_control/clock_control_sam_pmc.c index 801f5c37e87314..6c43e142a9cf63 100644 --- a/drivers/clock_control/clock_control_sam_pmc.c +++ b/drivers/clock_control/clock_control_sam_pmc.c @@ -129,7 +129,7 @@ atmel_sam_clock_control_get_status(const struct device *dev, return status; } -static struct clock_control_driver_api atmel_sam_clock_control_api = { +static const struct clock_control_driver_api atmel_sam_clock_control_api = { .on = atmel_sam_clock_control_on, .off = atmel_sam_clock_control_off, .get_rate = atmel_sam_clock_control_get_rate, diff --git a/drivers/clock_control/clock_control_smartbond.c b/drivers/clock_control/clock_control_smartbond.c index e049c67c638b15..536b83b414d34f 100644 --- a/drivers/clock_control/clock_control_smartbond.c +++ b/drivers/clock_control/clock_control_smartbond.c @@ -582,7 +582,7 @@ int smartbond_clocks_init(const struct device *dev) return 0; } -static struct clock_control_driver_api smartbond_clock_control_api = { +static const struct clock_control_driver_api smartbond_clock_control_api = { .on = smartbond_clock_control_on, .off = smartbond_clock_control_off, .get_rate = smartbond_clock_control_get_rate, diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index e816a5f792ef1c..be4c30a5aba0a0 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -35,6 +35,28 @@ #define apb2_prescaler(v) fn_apb2_prescaler(v) #endif +#if defined(RCC_CFGR_ADCPRE) +#define z_adc12_prescaler(v) LL_RCC_ADC_CLKSRC_PCLK2_DIV_ ## v +#define adc12_prescaler(v) z_adc12_prescaler(v) +#elif defined(RCC_CFGR2_ADC1PRES) +#define z_adc12_prescaler(v) \ + COND_CODE_1(IS_EQ(v, 0), \ + LL_RCC_ADC1_CLKSRC_HCLK, \ + LL_RCC_ADC1_CLKSRC_PLL_DIV_ ## v) +#define adc12_prescaler(v) z_adc12_prescaler(v) +#else +#define z_adc12_prescaler(v) \ + COND_CODE_1(IS_EQ(v, 0), \ + (LL_RCC_ADC12_CLKSRC_HCLK), \ + (LL_RCC_ADC12_CLKSRC_PLL_DIV_ ## v)) +#define adc12_prescaler(v) z_adc12_prescaler(v) +#define z_adc34_prescaler(v) \ + COND_CODE_1(IS_EQ(v, 0), \ + (LL_RCC_ADC34_CLKSRC_HCLK), \ + (LL_RCC_ADC34_CLKSRC_PLL_DIV_ ## v)) +#define adc34_prescaler(v) z_adc34_prescaler(v) +#endif + #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler) #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler @@ -451,7 +473,7 @@ static enum clock_control_status stm32_clock_control_get_status(const struct dev } } -static struct clock_control_driver_api stm32_clock_control_api = { +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, @@ -814,13 +836,13 @@ int stm32_clock_control_init(const struct device *dev) LL_RCC_SetAHB4Prescaler(ahb_prescaler(STM32_AHB4_PRESCALER)); #endif #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc_prescaler) - LL_RCC_SetADCClockSource(adc_prescaler(STM32_ADC_PRESCALER)); + LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC_PRESCALER)); #endif #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc12_prescaler) - LL_RCC_SetADCClockSource(adc_prescaler(STM32_ADC12_PRESCALER)); + LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC12_PRESCALER)); #endif #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc34_prescaler) - LL_RCC_SetADCClockSource(adc_prescaler(STM32_ADC34_PRESCALER)); + LL_RCC_SetADCClockSource(adc34_prescaler(STM32_ADC34_PRESCALER)); #endif /* configure MCO1/MCO2 based on Kconfig */ diff --git a/drivers/clock_control/clock_stm32_ll_h5.c b/drivers/clock_control/clock_stm32_ll_h5.c index 6ad08d1ee3b933..5f9ffdcc5b8dd5 100644 --- a/drivers/clock_control/clock_stm32_ll_h5.c +++ b/drivers/clock_control/clock_stm32_ll_h5.c @@ -338,7 +338,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return 0; } -static struct clock_control_driver_api stm32_clock_control_api = { +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index b11e2b5c9f5b6b..bdbdf860e227fd 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -21,7 +21,11 @@ /* Macros to fill up prescaler values */ +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) +#define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v +#else #define z_hsi_divider(v) LL_RCC_HSI_DIV ## v +#endif #define hsi_divider(v) z_hsi_divider(v) #define z_sysclk_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v @@ -42,6 +46,9 @@ #define z_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v #define apb4_prescaler(v) z_apb4_prescaler(v) +#define z_apb5_prescaler(v) LL_RCC_APB5_DIV_ ## v +#define apb5_prescaler(v) z_apb5_prescaler(v) + /* Macro to check for clock feasibility */ /* It is Cortex M7's responsibility to setup clock tree */ /* This check should only be performed for the M7 core code */ @@ -81,12 +88,21 @@ #endif /* ARM Sys CPU Clock before HPRE prescaler */ +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) +#define SYSCLK_FREQ ((SYSCLKSRC_FREQ)/(STM32_D1CPRE)) +#define AHB_FREQ ((SYSCLK_FREQ)/(STM32_HPRE)) +#define APB1_FREQ ((AHB_FREQ)/(STM32_PPRE1)) +#define APB2_FREQ ((AHB_FREQ)/(STM32_PPRE2)) +#define APB4_FREQ ((AHB_FREQ)/(STM32_PPRE4)) +#define APB5_FREQ ((AHB_FREQ)/(STM32_PPRE5)) +#else #define SYSCLK_FREQ ((SYSCLKSRC_FREQ)/(STM32_D1CPRE)) #define AHB_FREQ ((SYSCLK_FREQ)/(STM32_HPRE)) #define APB1_FREQ ((AHB_FREQ)/(STM32_D2PPRE1)) #define APB2_FREQ ((AHB_FREQ)/(STM32_D2PPRE2)) #define APB3_FREQ ((AHB_FREQ)/(STM32_D1PPRE)) #define APB4_FREQ ((AHB_FREQ)/(STM32_D3PPRE)) +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ /* Datasheet maximum frequency definitions */ #if defined(CONFIG_SOC_STM32H743XX) ||\ @@ -112,6 +128,11 @@ #define SYSCLK_FREQ_MAX 280000000UL #define AHB_FREQ_MAX 280000000UL #define APBx_FREQ_MAX 140000000UL +#elif defined(CONFIG_SOC_SERIES_STM32H7RSX) +/* All h7RS SoC with maximum 500MHz SYSCLK (refer to Datasheet DS14359 rev 1) */ +#define SYSCLK_FREQ_MAX 500000000UL +#define AHB_FREQ_MAX 250000000UL +#define APBx_FREQ_MAX 125000000UL #else /* Default: All h7 SoC with maximum 280MHz SYSCLK */ #define SYSCLK_FREQ_MAX 280000000UL @@ -154,7 +175,7 @@ * So, changing this prescaler is not allowed until it is made possible to * use them independently in zephyr clock subsystem. */ -#error "D1CPRE presacler can't be higher than 1" +#error "D1CPRE prescaler can't be higher than 1" #endif #endif /* CONFIG_CPU_CORTEX_M7 */ @@ -255,7 +276,11 @@ static int32_t prepare_regulator_voltage_scale(void) /* Make sure to put the CPU in highest Voltage scale during clock configuration */ /* Highest voltage is SCALE0 */ LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0); +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + while (LL_PWR_IsActiveFlag_VOSRDY() == 0) { +#else while (LL_PWR_IsActiveFlag_VOS() == 0) { +#endif } return 0; } @@ -290,8 +315,12 @@ static int32_t optimize_regulator_voltage_scale(uint32_t sysclk_freq) LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY); #endif LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0); +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + while (LL_PWR_IsActiveFlag_VOSRDY() == 0) { +#else while (LL_PWR_IsActiveFlag_VOS() == 0) { - } +#endif + }; return 0; } @@ -448,10 +477,17 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, #else uint32_t ahb_clock = get_bus_clock(SystemCoreClock, STM32_HPRE); #endif +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_PPRE1); + uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_PPRE2); + uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_PPRE4); + uint32_t apb5_clock = get_bus_clock(ahb_clock, STM32_PPRE5); +#else uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_D2PPRE1); uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_D2PPRE2); uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_D1PPRE); uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_D3PPRE); +#endif ARG_UNUSED(clock); @@ -469,12 +505,22 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, case STM32_CLOCK_BUS_APB2: *rate = apb2_clock; break; +#if !defined(CONFIG_SOC_SERIES_STM32H7RSX) case STM32_CLOCK_BUS_APB3: *rate = apb3_clock; break; +#endif /* !CONFIG_SOC_SERIES_STM32H7RSX */ case STM32_CLOCK_BUS_APB4: *rate = apb4_clock; break; +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + case STM32_CLOCK_BUS_APB5: + *rate = apb5_clock; + break; + case STM32_CLOCK_BUS_AHB5: + *rate = ahb_clock; + break; +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ case STM32_SRC_SYSCLK: *rate = get_hclk_frequency(); break; @@ -522,6 +568,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLL_N_MULTIPLIER, STM32_PLL_R_DIVISOR); break; +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + case STM32_SRC_PLL1_S: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_S_DIVISOR); + break; + /* PLL 1 has no T-divider */ +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ #endif /* STM32_PLL_ENABLED */ #if defined(STM32_PLL2_ENABLED) case STM32_SRC_PLL2_P: @@ -542,6 +597,20 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLL2_N_MULTIPLIER, STM32_PLL2_R_DIVISOR); break; +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + case STM32_SRC_PLL2_S: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL2_M_DIVISOR, + STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_S_DIVISOR); + break; + case STM32_SRC_PLL2_T: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL2_M_DIVISOR, + STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_T_DIVISOR); + break; +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ #endif /* STM32_PLL2_ENABLED */ #if defined(STM32_PLL3_ENABLED) case STM32_SRC_PLL3_P: @@ -562,6 +631,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLL3_N_MULTIPLIER, STM32_PLL3_R_DIVISOR); break; +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + case STM32_SRC_PLL3_S: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL3_M_DIVISOR, + STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_S_DIVISOR); + break; + /* PLL 3 has no T-divider */ +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ #endif /* STM32_PLL3_ENABLED */ default: return -ENOTSUP; @@ -570,7 +648,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, return 0; } -static struct clock_control_driver_api stm32_clock_control_api = { +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, @@ -739,6 +817,12 @@ static int set_up_plls(void) LL_RCC_PLL1R_Enable(); } +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + if (IS_ENABLED(STM32_PLL_S_ENABLED)) { + LL_RCC_PLL1_SetS(STM32_PLL_S_DIVISOR); + LL_RCC_PLL1S_Enable(); + } +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ LL_RCC_PLL1_Enable(); while (LL_RCC_PLL1_IsReady() != 1U) { } @@ -777,6 +861,18 @@ static int set_up_plls(void) LL_RCC_PLL2R_Enable(); } +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + if (IS_ENABLED(STM32_PLL2_S_ENABLED)) { + LL_RCC_PLL2_SetS(STM32_PLL2_S_DIVISOR); + LL_RCC_PLL2S_Enable(); + } + + if (IS_ENABLED(STM32_PLL2_T_ENABLED)) { + LL_RCC_PLL2_SetT(STM32_PLL2_T_DIVISOR); + LL_RCC_PLL2T_Enable(); + } + +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ LL_RCC_PLL2_Enable(); while (LL_RCC_PLL2_IsReady() != 1U) { } @@ -815,6 +911,13 @@ static int set_up_plls(void) LL_RCC_PLL3R_Enable(); } +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + if (IS_ENABLED(STM32_PLL3_S_ENABLED)) { + LL_RCC_PLL3_SetS(STM32_PLL3_S_DIVISOR); + LL_RCC_PLL3S_Enable(); + } + +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ LL_RCC_PLL3_Enable(); while (LL_RCC_PLL3_IsReady() != 1U) { } @@ -830,6 +933,91 @@ static int set_up_plls(void) return 0; } +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) +/* adapted from the stm32cube SystemCoreClockUpdate*/ +void stm32_system_clock_update(void) +{ + uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc; + float_t pllfracn, pllvco; + + /* Get SYSCLK source */ + switch (RCC->CFGR & RCC_CFGR_SWS) { + case 0x00: /* HSI used as system clock source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) + >> RCC_CR_HSIDIV_Pos)); + break; + + case 0x08: /* CSI used as system clock source */ + sysclk = CSI_VALUE; + break; + + case 0x10: /* HSE used as system clock source */ + sysclk = HSE_VALUE; + break; + + case 0x18: /* PLL1 used as system clock source */ + /* + * PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + * SYSCLK = PLL1_VCO / PLL1R + */ + pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); + pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos); + + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) { + pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) + >> RCC_PLL1FRACR_FRACN_Pos)); + } else { + pllfracn = (float_t)0U; + } + + if (pllm != 0U) { + switch (pllsource) { + case 0x02: /* HSE used as PLL1 clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * + ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + + (pllfracn/(float_t)0x2000) + (float_t)1); + break; + + case 0x01: /* CSI used as PLL1 clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * + ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + + (pllfracn/(float_t)0x2000) + (float_t)1); + break; + + case 0x00: /* HSI used as PLL1 clock source */ + default: + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> + RCC_CR_HSIDIV_Pos)); + pllvco = ((float_t)hsivalue / (float_t)pllm) * + ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + + (pllfracn/(float_t)0x2000) + (float_t)1); + break; + } + + pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> + RCC_PLL1DIVR1_DIVP_Pos) + 1U); + sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp); + } else { + sysclk = 0U; + } + break; + + default: /* Unexpected, default to HSI used as system clk source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + break; + } + + /* system clock frequency : CM7 CPU frequency */ + core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE); + + if (core_presc >= 8U) { + SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U)); + } else { + SystemCoreClock = sysclk; + } +} +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ + int stm32_clock_control_init(const struct device *dev) { int r = 0; @@ -843,10 +1031,10 @@ int stm32_clock_control_init(const struct device *dev) defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) || \ defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ) LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_HSEM); -#else +#elif !defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* The stm32h7RS serie has no HSEM peripheral */ LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_HSEM); #endif - z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); /* Configure MCO1/MCO2 based on Kconfig */ @@ -871,22 +1059,38 @@ int stm32_clock_control_init(const struct device *dev) STM32_HPRE); /* Set flash latency */ + /* AHB/AXI/HCLK clock is SYSCLK / HPRE */ /* If freq increases, set flash latency before any clock setting */ if (new_hclk_freq > old_hclk_freq) { LL_SetFlashLatency(new_hclk_freq); } +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* + * The default Flash latency is 3 WS which is not enough, + * set higher and correct later if needed + */ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_6); +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ /* Preset the prescalers prior to choosing SYSCLK */ /* Prevents APB clock to go over limits */ /* Set buses (Sys,AHB, APB1, APB2 & APB4) prescalers */ LL_RCC_SetSysPrescaler(sysclk_prescaler(STM32_D1CPRE)); LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_HPRE)); +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_PPRE1)); + LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_PPRE2)); + LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_PPRE4)); + LL_RCC_SetAPB5Prescaler(apb5_prescaler(STM32_PPRE5)); + +#else LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_D2PPRE1)); LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_D2PPRE2)); LL_RCC_SetAPB3Prescaler(apb3_prescaler(STM32_D1PPRE)); LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_D3PPRE)); +#endif /* Set up sys clock */ if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) { /* Set PLL1 as System Clock Source */ diff --git a/drivers/clock_control/clock_stm32_ll_mco.h b/drivers/clock_control/clock_stm32_ll_mco.h index d98c4a116e8e1e..b526f13a1b22d1 100644 --- a/drivers/clock_control/clock_stm32_ll_mco.h +++ b/drivers/clock_control/clock_stm32_ll_mco.h @@ -33,7 +33,8 @@ #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLQCLK #if (CONFIG_SOC_SERIES_STM32G0X || CONFIG_SOC_SERIES_STM32WLX) #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLQCLK - #elif (CONFIG_SOC_SERIES_STM32H5X || CONFIG_SOC_SERIES_STM32H7X) + #elif (CONFIG_SOC_SERIES_STM32H5X || \ + CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32H7RSX) #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL1QCLK #else #error "PLLQCLK is not a valid clock source on your SOC" diff --git a/drivers/clock_control/clock_stm32_ll_mp1.c b/drivers/clock_control/clock_stm32_ll_mp1.c index 6a8e1978f84f56..e0ffedda3a86aa 100644 --- a/drivers/clock_control/clock_stm32_ll_mp1.c +++ b/drivers/clock_control/clock_stm32_ll_mp1.c @@ -393,7 +393,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, return 0; } -static struct clock_control_driver_api stm32_clock_control_api = { +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index fc16b5e46e47b0..2c7e12f287255e 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -351,10 +351,36 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return 0; } -static struct clock_control_driver_api stm32_clock_control_api = { +static enum clock_control_status stm32_clock_control_get_status(const struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; + + ARG_UNUSED(dev); + + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == true) { + /* Gated clocks */ + if ((sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus) & pclken->enr) + == pclken->enr) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } + } else { + /* Domain clock sources */ + if (enabled_clock(pclken->bus) == 0) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } + } +} + +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .get_status = stm32_clock_control_get_status, .configure = stm32_clock_control_configure, }; diff --git a/drivers/clock_control/clock_stm32_ll_wba.c b/drivers/clock_control/clock_stm32_ll_wba.c index 36cf52064dac51..ceb528ccd702e4 100644 --- a/drivers/clock_control/clock_stm32_ll_wba.c +++ b/drivers/clock_control/clock_stm32_ll_wba.c @@ -290,7 +290,7 @@ static enum clock_control_status stm32_clock_control_get_status(const struct dev } } -static struct clock_control_driver_api stm32_clock_control_api = { +static const struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, diff --git a/drivers/clock_control/clock_stm32f0_f3.c b/drivers/clock_control/clock_stm32f0_f3.c index a4843782dfdcb0..2557355a6f4190 100644 --- a/drivers/clock_control/clock_stm32f0_f3.c +++ b/drivers/clock_control/clock_stm32f0_f3.c @@ -15,28 +15,6 @@ #include #include "clock_stm32_ll_common.h" -#if defined(RCC_CFGR_ADCPRE) -#define z_adc_prescaler(v) LL_RCC_ADC_CLKSRC_PCLK2_DIV_ ## v -#define adc_prescaler(v) z_adc_prescaler(v) -#elif defined(RCC_CFGR2_ADC1PRES) -#define z_adc12_prescaler(v) \ - COND_CODE_1(IS_EQ(v, 0), \ - LL_RCC_ADC1_CLKSRC_HCLK, \ - LL_RCC_ADC1_CLKSRC_PLL_DIV_ ## v) -#define adc12_prescaler(v) z_adc12_prescaler(v) -#else -#define z_adc12_prescaler(v) \ - COND_CODE_1(IS_EQ(v, 0), \ - LL_RCC_ADC12_CLKSRC_HCLK, \ - LL_RCC_ADC12_CLKSRC_PLL_DIV_ ## v) -#define adc12_prescaler(v) z_adc12_prescaler(v) -#define z_adc34_prescaler(v) \ - COND_CODE_1(IS_EQ(v, 0), \ - LL_RCC_ADC34_CLKSRC_HCLK, \ - LL_RCC_ADC34_CLKSRC_PLL_DIV_ ## v) -#define adc34_prescaler(v) z_adc34_prescaler(v) -#endif - #if defined(STM32_PLL_ENABLED) /** diff --git a/drivers/clock_control/clock_stm32f1.c b/drivers/clock_control/clock_stm32f1.c index c882fcc40df724..760e417eaab0e3 100644 --- a/drivers/clock_control/clock_stm32f1.c +++ b/drivers/clock_control/clock_stm32f1.c @@ -21,9 +21,6 @@ #define STM32_USB_PRE_ENABLED RCC_CFGR_OTGFSPRE #endif -#define z_adc_prescaler(v) LL_RCC_ADC_CLKSRC_PCLK2_DIV_ ## v -#define adc_prescaler(v) z_adc_prescaler(v) - #if defined(STM32_PLL_ENABLED) /* diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index 6acef7a63dd871..2fd0111a9dd52b 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -95,21 +95,37 @@ config JAILHOUSE_DEBUG_CONSOLE Useful in board bring-up if there aren't any working serial drivers. +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_RAM_CONSOLE := zephyr,ram-console + config RAM_CONSOLE bool "Use RAM console" select CONSOLE_HAS_DRIVER + select RAM_CONSOLE_BUFFER_SECTION if $(dt_chosen_enabled,$(DT_CHOSEN_Z_RAM_CONSOLE)) help Emit console messages to a RAM buffer "ram_console" which can be examined at runtime with a debugger. Useful in board bring-up if there aren't any working serial drivers. +config RAM_CONSOLE_BUFFER_SECTION + bool "Use dedicated section as RAM console buffer" + depends on RAM_CONSOLE && $(dt_chosen_enabled,$(DT_CHOSEN_Z_RAM_CONSOLE)) + select KERNEL_DIRECT_MAP if MMU + help + Use a dedicated section as the RAM console buffer, whose address is + known before build so that the console output messages can be easily + examined by a debugger or software tool from a parallel-running OS. + config RAM_CONSOLE_BUFFER_SIZE int "Ram Console buffer size" + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_RAM_CONSOLE)) if RAM_CONSOLE_BUFFER_SECTION default 1024 depends on RAM_CONSOLE help - Size of the RAM console buffer. Messages will wrap around if the - length is exceeded. + Total size of the RAM console buffer, to ensure it's always + NULL-terminated leave one byte unused, the actual length is + one byte less. Messages will wrap around if the actual length + is exceeded. config RTT_CONSOLE bool "Use RTT console" diff --git a/drivers/console/ram_console.c b/drivers/console/ram_console.c index 4ace56f963043c..fdb71b8bda0a70 100644 --- a/drivers/console/ram_console.c +++ b/drivers/console/ram_console.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2015 Intel Corporation + * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,23 +12,47 @@ #include #include #include +#include + +#ifdef CONFIG_RAM_CONSOLE_BUFFER_SECTION +#if !DT_HAS_CHOSEN(zephyr_ram_console) +#error "Lack of chosen property zephyr,ram_console!" +#elif (CONFIG_RAM_CONSOLE_BUFFER_SIZE > DT_REG_SIZE(DT_CHOSEN(zephyr_ram_console))) +#error "Custom RAM console buffer exceeds the section size!" +#endif + +#define RAM_CONSOLE_BUF_ATTR \ + __attribute__((__section__(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ram_console))))) +#else +#define RAM_CONSOLE_BUF_ATTR +#endif extern void __printk_hook_install(int (*fn)(int)); extern void __stdout_hook_install(int (*fn)(int)); -/* Extra byte to ensure we're always NULL-terminated */ -char ram_console[CONFIG_RAM_CONSOLE_BUFFER_SIZE + 1]; +char ram_console_buf[CONFIG_RAM_CONSOLE_BUFFER_SIZE] RAM_CONSOLE_BUF_ATTR; +char *ram_console; static int pos; static int ram_console_out(int character) { ram_console[pos] = (char)character; - pos = (pos + 1) % CONFIG_RAM_CONSOLE_BUFFER_SIZE; + /* Leave one byte to ensure we're always NULL-terminated */ + pos = (pos + 1) % (CONFIG_RAM_CONSOLE_BUFFER_SIZE - 1); return character; } static int ram_console_init(void) { +#ifdef CONFIG_RAM_CONSOLE_BUFFER_SECTION + mm_reg_t ram_console_va; + + device_map((mm_reg_t *)&ram_console_va, DT_REG_ADDR(DT_CHOSEN(zephyr_ram_console)), + CONFIG_RAM_CONSOLE_BUFFER_SIZE, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + ram_console = (char *)ram_console_va, +#else + ram_console = ram_console_buf, +#endif __printk_hook_install(ram_console_out); __stdout_hook_install(ram_console_out); diff --git a/drivers/console/xtensa_sim_console.c b/drivers/console/xtensa_sim_console.c index 1d52f93af73e23..316162ddc0c1af 100644 --- a/drivers/console/xtensa_sim_console.c +++ b/drivers/console/xtensa_sim_console.c @@ -25,14 +25,6 @@ int arch_printk_char_out(int c) register int ret_err __asm__ ("a3"); buf[0] = (char)c; - - if (buf[0] == '\n') { - buf[1] = buf[0]; - buf[0] = '\r'; - a3++; - a5++; - } - __asm__ volatile ("simcall" : "=a" (ret_val), "=a" (ret_err) : "a" (a2), "a" (a3), "a" (a4), "a" (a5) diff --git a/drivers/counter/Kconfig.mcux_lptmr b/drivers/counter/Kconfig.mcux_lptmr index d6847a3ffbb4bf..af961c790e1d43 100644 --- a/drivers/counter/Kconfig.mcux_lptmr +++ b/drivers/counter/Kconfig.mcux_lptmr @@ -12,7 +12,7 @@ config COUNTER_MCUX_LPTMR Enable support for the MCUX Low Power Timer (LPTMR). config COUNTER_MCUX_KINETIS_LPTMR - bool "Deprecated DT compatible" + bool default y depends on DT_HAS_NXP_KINETIS_LPTMR_ENABLED select DEPRECATED diff --git a/drivers/counter/counter_mcux_lptmr.c b/drivers/counter/counter_mcux_lptmr.c index c24e60a2e0659d..878a14c196005c 100644 --- a/drivers/counter/counter_mcux_lptmr.c +++ b/drivers/counter/counter_mcux_lptmr.c @@ -142,6 +142,8 @@ static int mcux_lptmr_init(const struct device *dev) LPTMR_Init(config->base, &lptmr_config); + LPTMR_SetTimerPeriod(config->base, config->info.max_top_value); + config->irq_config_func(dev); return 0; @@ -210,7 +212,8 @@ static void mcux_lptmr_irq_config_0(const struct device *dev); static struct mcux_lptmr_config mcux_lptmr_config_0 = { .info = { - .max_top_value = UINT16_MAX, + .max_top_value = ((DT_INST_PROP(0, resolution) == 32) + ? UINT32_MAX : UINT16_MAX), .freq = DT_INST_PROP(0, clock_frequency) / DT_INST_PROP(0, prescaler), .flags = COUNTER_CONFIG_INFO_COUNT_UP, diff --git a/drivers/counter/counter_smartbond_timer.c b/drivers/counter/counter_smartbond_timer.c index 3e42f10b8fd26a..c15bdfad86e059 100644 --- a/drivers/counter/counter_smartbond_timer.c +++ b/drivers/counter/counter_smartbond_timer.c @@ -105,6 +105,8 @@ static uint8_t counter_smartbond_pdc_trigger_get(const struct device *dev) return MCU_PDC_TRIGGER_TIMER3; case (uint32_t)TIMER4: return MCU_PDC_TRIGGER_TIMER4; + default: + return 0; } } diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index f65c554cf989ac..81a404a51208c5 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -159,7 +159,7 @@ static inline void dai_dmic_release_ownership(const struct dai_intel_dmic *dmic) static inline uint32_t dai_dmic_base(const struct dai_intel_dmic *dmic) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) return dmic->hdamldmic_base; #else return dmic->shim_base; @@ -172,7 +172,7 @@ static inline void dai_dmic_set_sync_period(uint32_t period, const struct dai_in uint32_t val = CONFIG_DAI_DMIC_HW_IOCLK / period - 1; uint32_t base = dai_dmic_base(dmic); /* DMIC Change sync period */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) sys_write32(sys_read32(base + DMICSYNC_OFFSET) | FIELD_PREP(DMICSYNC_SYNCPRD, val), base + DMICSYNC_OFFSET); sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPU, @@ -286,7 +286,7 @@ static void dai_dmic_irq_handler(const void *data) static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) { /* Disable DMIC clock gating */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if (CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) | DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); #else @@ -298,10 +298,10 @@ static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) static inline void dai_dmic_en_clk_gating(const struct dai_intel_dmic *dmic) { /* Enable DMIC clock gating */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if (CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) & ~DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); -#else +#else /* All other CAVS and ACE platforms */ sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & ~DMICLCTL_DCGD), dmic->shim_base + DMICLCTL_OFFSET); #endif @@ -312,7 +312,7 @@ static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmi const struct dai_config *cfg, uint32_t index) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint16_t pcmsycm = cfg->link_config; uint32_t reg_add = dmic->shim_base + DMICXPCMSyCM_OFFSET + 0x0004*index; @@ -321,7 +321,7 @@ static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmi ARG_UNUSED(dmic); ARG_UNUSED(cfg); ARG_UNUSED(index); -#endif /* defined(CONFIG_SOC_INTEL_ACE20_LNL) */ +#endif /* defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) */ } static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) @@ -331,7 +331,7 @@ static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) sys_write32((sys_read32(base + DMICLCTL_OFFSET) | DMICLCTL_SPA), base + DMICLCTL_OFFSET); -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) while (!(sys_read32(base + DMICLCTL_OFFSET) & DMICLCTL_CPA)) { k_sleep(K_USEC(100)); } diff --git a/drivers/dai/intel/dmic/dmic.h b/drivers/dai/intel/dmic/dmic.h index e06ed80daed75f..d690c0cd21a1ca 100644 --- a/drivers/dai/intel/dmic/dmic.h +++ b/drivers/dai/intel/dmic/dmic.h @@ -173,7 +173,7 @@ struct dai_intel_dmic { /* hardware parameters */ uint32_t reg_base; uint32_t shim_base; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint32_t hdamldmic_base; uint32_t vshim_base; #endif diff --git a/drivers/dai/intel/dmic/dmic_nhlt.c b/drivers/dai/intel/dmic/dmic_nhlt.c index c7fe48e1432da7..5f150e6d0375c5 100644 --- a/drivers/dai/intel/dmic/dmic_nhlt.c +++ b/drivers/dai/intel/dmic/dmic_nhlt.c @@ -279,7 +279,7 @@ static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic, const int c static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, uint32_t source) { uint32_t val; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) /* ACE 2.0,3.0 */ val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET); val &= ~DMICLVSCTL_MLCS; val |= FIELD_PREP(DMICLVSCTL_MLCS, source); @@ -300,7 +300,7 @@ static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, static inline uint32_t dai_dmic_clock_select_get(const struct dai_intel_dmic *dmic) { uint32_t val; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) /* ACE 2.0,3.0 */ val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET); return FIELD_GET(DMICLVSCTL_MLCS, val); #else @@ -322,7 +322,7 @@ static int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t c return -ENOTSUP; } -#ifndef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */ +#if defined(CONFIG_SOC_INTEL_ACE15_MTPM) if (clock_source && !(sys_read32(dmic->shim_base + DMICLCAP_OFFSET) & DMICLCAP_MLCS)) { return -ENOTSUP; } diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 215f9912d57740..a7e83f7a07f9eb 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -74,11 +74,11 @@ static struct dai_intel_ssp_mn ssp_mn_divider = { .irq = DT_NUM_IRQS(node_id), \ .irq_name = irq_name_level5_z, \ .fifo[DAI_DIR_PLAYBACK].offset = \ - DT_REG_ADDR_BY_IDX(node_id, 0) + SSDR, \ + DT_REG_ADDR_BY_IDX(node_id, 0) + OUT_FIFO, \ .fifo[DAI_DIR_PLAYBACK].handshake = \ DT_DMAS_CELL_BY_NAME(node_id, tx, channel), \ .fifo[DAI_DIR_CAPTURE].offset = \ - DT_REG_ADDR_BY_IDX(node_id, 0) + SSDR, \ + DT_REG_ADDR_BY_IDX(node_id, 0) + IN_FIFO, \ .fifo[DAI_DIR_CAPTURE].handshake = \ DT_DMAS_CELL_BY_NAME(node_id, rx, channel), \ .mn_inst = &ssp_mn_divider, \ @@ -817,7 +817,7 @@ static void dai_ssp_pm_runtime_en_ssp_power(struct dai_intel_ssp *dp, uint32_t s ret = dai_ssp_poll_for_register_delay(dai_ip_base(dp) + I2SLCTL_OFFSET, I2SLCTL_CPA(ssp_index), I2SLCTL_CPA(ssp_index), DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); -#elif CONFIG_SOC_INTEL_ACE20_LNL +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_hdamlssp_base(dp) + I2SLCTL_OFFSET) | I2SLCTL_SPA(ssp_index), dai_hdamlssp_base(dp) + I2SLCTL_OFFSET); @@ -851,7 +851,8 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t ret = dai_ssp_poll_for_register_delay(dai_ip_base(dp) + I2SLCTL_OFFSET, I2SLCTL_CPA(ssp_index), 0, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); -#elif CONFIG_SOC_INTEL_ACE20_LNL + +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_hdamlssp_base(dp) + I2SLCTL_OFFSET) & (~I2SLCTL_SPA(ssp_index)), dai_hdamlssp_base(dp) + I2SLCTL_OFFSET); @@ -874,7 +875,7 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp, const struct dai_config *cfg, uint32_t ssp_index) { -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint16_t pcmsycm = cfg->link_config; /* Set upper slot number from configuration */ pcmsycm = pcmsycm | (dp->ssp_plat_data->params.tdm_slots - 1) << 4; @@ -905,11 +906,21 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) * SSSR_TNF is cleared when TX FIFO is empty or full, * so wait for set TNF then for TFL zero - order matter. */ +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0), + SSMODyCS_TNF, SSMODyCS_TNF, + DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); + + ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0), SSMODyCS_TFL, 0, + DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE * + (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); +#else ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSSR, SSSR_TNF, SSSR_TNF, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE); ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSCR3, SSCR3_TFL_MASK, 0, DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE * (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); +#endif if (ret) { LOG_WRN("timeout"); @@ -923,6 +934,81 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp) } } +#ifdef CONFIG_SOC_INTEL_ACE30_PTL +static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) +{ + uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; + uint32_t i, sssr; + + sssr = sys_read32(dai_base(dp) + SSSR); + + if (sssr & SSSR_ROR) { + /* The RX FIFO is in overflow condition, empty it */ + for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + + /* Clear the overflow status */ + dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); + /* Re-read the SSSR register */ + sssr = sys_read32(dai_base(dp) + SSSR); + } + + while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) { + uint32_t entries = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + + /* Empty the RX FIFO (the DMA is not running at this point) */ + for (i = 0; i < entries + 1; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + + sssr = sys_read32(dai_base(dp) + SSSR); + } +} + +static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) +{ + struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp); + uint64_t sample_ticks = ssp_plat_data->params.fsync_rate ? + 1000000 / ssp_plat_data->params.fsync_rate : 0; + + uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; + uint32_t i, sssr, ssmidycs; + uint32_t entries[2]; + + sssr = sys_read32(dai_base(dp) + SSSR); + entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + + while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) { + /* Wait one sample time */ + k_busy_wait(sample_ticks); + + entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0))); + sssr = sys_read32(dai_base(dp) + SSSR); + ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(0)); + + if (entries[0] > entries[1]) { + /* + * The DMA is reading the FIFO, check the status in the + * next loop + */ + entries[0] = entries[1]; + } else if (!(ssmidycs & SSMIDyCS_RFS)) { + /* + * The DMA request is not asserted, read the FIFO + * directly, otherwise let the next loop iteration to + * check the status + */ + for (i = 0; i < entries[1] + 1; i++) + sys_read32(dai_base(dp) + SSMIDyD(0)); + } + + sssr = sys_read32(dai_base(dp) + SSSR); + } + + /* Just in case clear the overflow status */ + dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); +} + +#else static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) { uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; @@ -994,21 +1080,20 @@ static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp) dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); } +#endif + static int dai_ssp_mclk_prepare_enable(struct dai_intel_ssp *dp) { struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp); - int ret = 0; + int ret; if (ssp_plat_data->clk_active & SSP_CLK_MCLK_ACTIVE) { return 0; } /* MCLK config */ - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - ret = dai_ssp_mn_set_mclk(dp, ssp_plat_data->params.mclk_id, - ssp_plat_data->params.mclk_rate); - } - + ret = dai_ssp_mn_set_mclk(dp, ssp_plat_data->params.mclk_id, + ssp_plat_data->params.mclk_rate); if (ret < 0) { LOG_ERR("invalid mclk_rate = %d for mclk_id = %d", ssp_plat_data->params.mclk_rate, ssp_plat_data->params.mclk_id); @@ -1027,9 +1112,7 @@ static void dai_ssp_mclk_disable_unprepare(struct dai_intel_ssp *dp) return; } - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - dai_ssp_mn_release_mclk(dp, ssp_plat_data->params.mclk_id); - } + dai_ssp_mn_release_mclk(dp, ssp_plat_data->params.mclk_id); ssp_plat_data->clk_active &= ~SSP_CLK_MCLK_ACTIVE; } @@ -1049,10 +1132,6 @@ static int dai_ssp_bclk_prepare_enable(struct dai_intel_ssp *dp) return 0; } - if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_IS_NEEDED)) { - goto out; - } - sscr0 = sys_read32(dai_base(dp) + SSCR0); #if CONFIG_INTEL_MN @@ -1075,9 +1154,11 @@ static int dai_ssp_bclk_prepare_enable(struct dai_intel_ssp *dp) mdiv = ft[DAI_INTEL_SSP_DEFAULT_IDX].freq / ssp_plat_data->params.bclk_rate; #endif +#ifndef CONFIG_SOC_INTEL_ACE30_PTL if (need_ecs) { sscr0 |= SSCR0_ECS; } +#endif /* clock divisor is SCR + 1 */ mdiv -= 1; @@ -1112,9 +1193,7 @@ static void dai_ssp_bclk_disable_unprepare(struct dai_intel_ssp *dp) return; } #if CONFIG_INTEL_MN - if (ssp_plat_data->clk_active & SSP_CLK_BCLK_IS_NEEDED) { - dai_ssp_mn_release_bclk(dp, ssp_plat_data->ssp_index); - } + dai_ssp_mn_release_bclk(dp, ssp_plat_data->ssp_index); #endif ssp_plat_data->clk_active &= ~SSP_CLK_BCLK_ACTIVE; } @@ -1237,19 +1316,16 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR; break; case DAI_INTEL_IPC3_SSP_FMT_CBC_CFC: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED | SSP_CLK_BCLK_IS_NEEDED; sscr1 |= SSCR1_SCFR; cfs = true; break; case DAI_INTEL_IPC3_SSP_FMT_CBP_CFC: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED; sscr1 |= SSCR1_SCLKDIR; /* FIXME: this mode has not been tested */ cfs = true; break; case DAI_INTEL_IPC3_SSP_FMT_CBC_CFP: - ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED | SSP_CLK_BCLK_IS_NEEDED; sscr1 |= SSCR1_SCFR | SSCR1_SFRMDIR; /* FIXME: this mode has not been tested */ break; @@ -1611,8 +1687,13 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co sys_write32(sspsp2, dai_base(dp) + SSPSP2); sys_write32(ssioc, dai_base(dp) + SSIOC); sys_write32(ssto, dai_base(dp) + SSTO); +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0)); + sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0)); +#else sys_write32(sstsa, dai_base(dp) + SSTSA); sys_write32(ssrsa, dai_base(dp) + SSRSA); +#endif LOG_INF("sscr0 = 0x%08x, sscr1 = 0x%08x, ssto = 0x%08x, sspsp = 0x%0x", sscr0, sscr1, ssto, sspsp); @@ -1825,7 +1906,7 @@ static int dai_ssp_parse_aux_data(struct dai_intel_ssp *dp, const void *spec_con sys_write32(sys_read32(dai_ip_base(dp) + I2SLCTL_OFFSET) | I2CLCTL_MLCS(link->clock_source), dai_ip_base(dp) + I2SLCTL_OFFSET); -#elif CONFIG_SOC_INTEL_ACE20_LNL +#elif CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30_PTL sys_write32(sys_read32(dai_i2svss_base(dp) + I2SLCTL_OFFSET) | I2CLCTL_MLCS(link->clock_source), dai_i2svss_base(dp) + I2SLCTL_OFFSET); @@ -1876,14 +1957,20 @@ static int dai_ssp_set_clock_control_ver_1(struct dai_intel_ssp *dp, static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_config *cfg, const struct dai_intel_ipc4_ssp_config *regs) { - uint32_t ssc0, sstsa, ssrsa, sscr1; + uint32_t ssc0, sstsa, ssrsa; + uint32_t sscr1 = regs->ssc1; +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sscr1 = regs->ssc1 & ~(SSCR1_RSVD21); +#else + sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE); +#endif ssc0 = regs->ssc0; sstsa = SSTSA_GET(regs->sstsa); ssrsa = SSRSA_GET(regs->ssrsa); - sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE); LOG_INF("SSP%d configuration:", dp->dai_index); +#ifndef CONFIG_SOC_INTEL_ACE30_PTL if (regs->sstsa & SSTSA_TXEN || regs->ssrsa & SSRSA_RXEN || regs->ssc1 & (SSCR1_RSRE | SSCR1_TSRE)) { LOG_INF(" Ignoring %s%s%s%sfrom blob", @@ -1892,6 +1979,7 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co regs->ssc1 & SSCR1_TSRE ? "SSCR1:TSRE " : "", regs->ssc1 & SSCR1_RSRE ? "SSCR1:RSRE " : ""); } +#endif sys_write32(ssc0, dai_base(dp) + SSCR0); sys_write32(regs->ssc2 & ~SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ @@ -1903,8 +1991,13 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co sys_write32(regs->sspsp2, dai_base(dp) + SSPSP2); sys_write32(regs->ssioc, dai_base(dp) + SSIOC); sys_write32(regs->sscto, dai_base(dp) + SSTO); +#ifdef CONFIG_SOC_INTEL_ACE30_PTL + sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0)); + sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0)); +#else sys_write32(sstsa, dai_base(dp) + SSTSA); sys_write32(ssrsa, dai_base(dp) + SSRSA); +#endif LOG_INF(" sscr0 = 0x%08x, sscr1 = 0x%08x, ssto = 0x%08x, sspsp = 0x%0x", ssc0, sscr1, regs->sscto, regs->sspsp); @@ -1923,15 +2016,6 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co dp->ssp_plat_data->params.rx_slots = SSRSA_GET(ssrsa); dp->ssp_plat_data->params.fsync_rate = cfg->rate; - /* MCLK is needed if SSP is FS and/or BCLK provider */ - if (!(regs->ssc1 & (SSCR1_SCLKDIR | SSCR1_SFRMDIR))) { - dp->ssp_plat_data->clk_active |= SSP_CLK_MCLK_IS_NEEDED; - /* BCLK is only needed if SSP is BCLK provider */ - if (!(regs->ssc1 & SSCR1_SCLKDIR)) { - dp->ssp_plat_data->clk_active |= SSP_CLK_BCLK_IS_NEEDED; - } - } - dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; } @@ -1956,19 +2040,14 @@ static int dai_ssp_set_config_blob(struct dai_intel_ssp *dp, const struct dai_co if (err) return err; dai_ssp_set_reg_config(dp, cfg, &blob15->i2s_ssp_config); - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - err = dai_ssp_set_clock_control_ver_1_5(dp, &blob15->i2s_mclk_control); - if (err) - return err; - } + err = dai_ssp_set_clock_control_ver_1_5(dp, &blob15->i2s_mclk_control); + if (err) + return err; } else { dai_ssp_set_reg_config(dp, cfg, &blob->i2s_driver_config.i2s_config); - if (ssp_plat_data->clk_active & SSP_CLK_MCLK_IS_NEEDED) { - err = dai_ssp_set_clock_control_ver_1(dp, - &blob->i2s_driver_config.mclk_config); - if (err) - return err; - } + err = dai_ssp_set_clock_control_ver_1(dp, &blob->i2s_driver_config.mclk_config); + if (err) + return err; } ssp_plat_data->clk_active |= SSP_CLK_MCLK_ES_REQ; @@ -2070,6 +2149,15 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction) /* enable DMA */ +#if CONFIG_SOC_INTEL_ACE30_PTL + if (direction == DAI_DIR_PLAYBACK) { + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, SSMODyCS_TSRE); + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, SSMODyCS_TXEN); + } else { + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, SSMIDyCS_RSRE); + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, SSMIDyCS_RXEN); + } +#else if (direction == DAI_DIR_PLAYBACK) { LOG_INF("SSP%d TX", dp->dai_index); dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, SSCR1_TSRE); @@ -2079,6 +2167,7 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction) dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, SSCR1_RSRE); dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, SSRSA_RXEN); } +#endif dp->state[direction] = DAI_STATE_RUNNING; ssp_acquire_port(dp->ssp_plat_data); @@ -2128,8 +2217,13 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_CAPTURE && dp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { LOG_INF("SSP%d RX", dp->dai_index); +#if CONFIG_SOC_INTEL_ACE30_PTL + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, 0); + dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, 0); +#else dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0); dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, 0); +#endif ssp_empty_rx_fifo_on_stop(dp); dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; ssp_release_port(ssp_plat_data); @@ -2139,9 +2233,15 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction) if (direction == DAI_DIR_PLAYBACK && dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_PRE_RUNNING) { LOG_INF("SSP%d TX", dp->dai_index); +#if CONFIG_SOC_INTEL_ACE30_PTL + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, 0); + dai_ssp_empty_tx_fifo(dp); + dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, 0); +#else dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, 0); dai_ssp_empty_tx_fifo(dp); dai_ssp_update_bits(dp, SSTSA, SSTSA_TXEN, 0); +#endif dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; ssp_release_port(ssp_plat_data); } diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index 8c3e248a0d9b7a..877ff75e532400 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -48,234 +48,16 @@ #define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1 #define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2 -/* SSP register offsets */ -#define SSCR0 0x00 -#define SSCR1 0x04 -#define SSSR 0x08 -#define SSITR 0x0C -#define SSDR 0x10 -#define SSTO 0x28 -#define SSPSP 0x2C -#define SSTSA 0x30 -#define SSRSA 0x34 -#define SSTSS 0x38 -#define SSCR2 0x40 - -/* SSCR0 bits */ -#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) -#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) -#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) -#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) -#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) -#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) -#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) -#define SSCR0_ECS BIT(6) -#define SSCR0_SSE BIT(7) -#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) -#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) -#define SSCR0_EDSS BIT(20) -#define SSCR0_NCS BIT(21) -#define SSCR0_RIM BIT(22) -#define SSCR0_TIM BIT(23) -#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) -#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) -#define SSCR0_ACS BIT(30) -#define SSCR0_MOD BIT(31) - -/* SSCR1 bits */ -#define SSCR1_RIE BIT(0) -#define SSCR1_TIE BIT(1) -#define SSCR1_LBM BIT(2) -#define SSCR1_SPO BIT(3) -#define SSCR1_SPH BIT(4) -#define SSCR1_MWDS BIT(5) -#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) -#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) -#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) -#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) -#define SSCR1_EFWR BIT(14) -#define SSCR1_STRF BIT(15) -#define SSCR1_IFS BIT(16) -#define SSCR1_PINTE BIT(18) -#define SSCR1_TINTE BIT(19) -#define SSCR1_RSRE BIT(20) -#define SSCR1_TSRE BIT(21) -#define SSCR1_TRAIL BIT(22) -#define SSCR1_RWOT BIT(23) -#define SSCR1_SFRMDIR BIT(24) -#define SSCR1_SCLKDIR BIT(25) -#define SSCR1_ECRB BIT(26) -#define SSCR1_ECRA BIT(27) -#define SSCR1_SCFR BIT(28) -#define SSCR1_EBCEI BIT(29) -#define SSCR1_TTE BIT(30) -#define SSCR1_TTELP BIT(31) - -#define SSCR2_TURM1 BIT(1) -#define SSCR2_PSPSRWFDFD BIT(3) -#define SSCR2_PSPSTWFDFD BIT(4) -#define SSCR2_SDFD BIT(14) -#define SSCR2_SDPM BIT(16) -#define SSCR2_LJDFD BIT(17) -#define SSCR2_MMRATF BIT(18) -#define SSCR2_SMTATF BIT(19) -#define SSCR2_SFRMEN BIT(20) -#define SSCR2_ACIOLBS BIT(21) - -/* SSR bits */ -#define SSSR_TNF BIT(2) -#define SSSR_RNE BIT(3) -#define SSSR_BSY BIT(4) -#define SSSR_TFS BIT(5) -#define SSSR_RFS BIT(6) -#define SSSR_ROR BIT(7) -#define SSSR_TUR BIT(21) - -/* SSPSP bits */ -#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) -#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) -#define SSPSP_ETDS BIT(3) -#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) -#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) -#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) -#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) -#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) -#define SSPSP_DMYSTOP_BITS 2 -#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) -#define SSPSP_FSRT BIT(25) -#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) - -#define SSPSP2 0x44 -#define SSPSP2_FEP_MASK 0xff - -#define SSCR3 0x48 -#define SSIOC 0x4C -#define SSP_REG_MAX SSIOC - -/* SSTSA bits */ -#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) -#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) -#define SSTSA_TXEN BIT(8) - -/* SSRSA bits */ -#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) -#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) -#define SSRSA_RXEN BIT(8) - -/* SSCR3 bits */ -#define SSCR3_FRM_MST_EN BIT(0) -#define SSCR3_I2S_MODE_EN BIT(1) -#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) -#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) -#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) -#define SSCR3_I2S_TX_EN BIT(9) -#define SSCR3_I2S_RX_EN BIT(10) -#define SSCR3_CLK_EDGE_SEL BIT(12) -#define SSCR3_STRETCH_TX BIT(14) -#define SSCR3_STRETCH_RX BIT(15) -#define SSCR3_MST_CLK_EN BIT(16) -#define SSCR3_SYN_FIX_EN BIT(17) - -/* SSCR4 bits */ -#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) - -/* SSCR5 bits */ -#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) -#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) - -/* SFIFOTT bits */ -#define SFIFOTT_TX(x) ((x) - 1) -#define SFIFOTT_RX(x) (((x) - 1) << 16) - -/* SFIFOL bits */ -#define SFIFOL_TFL(x) ((x) & 0xFFFF) -#define SFIFOL_RFL(x) ((x) >> 16) - -#define SSTSA_TSEN BIT(8) -#define SSRSA_RSEN BIT(8) - -#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) -#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) -#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) -#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) -#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) -#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) - -#define SSIOC_TXDPDEB BIT(1) -#define SSIOC_SFCR BIT(4) -#define SSIOC_SCOE BIT(5) - -/* For 8000 Hz rate one sample is transmitted within 125us */ -#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 - -/* SSP flush retry counts maximum */ -#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 - -#define SSP_CLK_MCLK_IS_NEEDED BIT(0) -#define SSP_CLK_MCLK_ES_REQ BIT(1) -#define SSP_CLK_MCLK_ACTIVE BIT(2) -#define SSP_CLK_BCLK_IS_NEEDED BIT(3) -#define SSP_CLK_BCLK_ES_REQ BIT(4) -#define SSP_CLK_BCLK_ACTIVE BIT(5) - -#define I2SLCTL_OFFSET 0x04 - #if defined(CONFIG_SOC_INTEL_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) -#define I2SLCTL_SPA(x) BIT(0 + x) -#define I2SLCTL_CPA(x) BIT(8 + x) +#include "ssp_regs_v1.h" #elif defined(CONFIG_SOC_INTEL_ACE20_LNL) -#define I2SLCTL_OFLEN BIT(4) -#define I2SLCTL_SPA(x) BIT(16 + x) -#define I2SLCTL_CPA(x) BIT(23 + x) -#define PCMS0CM_OFFSET 0x16 -#define PCMS1CM_OFFSET 0x1A +#include "ssp_regs_v2.h" +#elif defined(CONFIG_SOC_INTEL_ACE30_PTL) +#include "ssp_regs_v3.h" #else #error "Missing ssp definitions" #endif -#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) -#define SHIM_CLKCTL 0x78 -#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) -#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) - -#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE -/** \brief Offset of MCLK Divider Control Register. */ -#define MN_MDIVCTRL 0x100 - -/** \brief Offset of MCLK Divider x Ratio Register. */ -#define MN_MDIVR(x) (0x180 + (x) * 0x4) - -/** \brief Enables the output of MCLK Divider. - * On ACE+ there is a single divider for all MCLKs - */ -#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(0) - -#else -#define MN_MDIVCTRL 0x0 -#define MN_MDIVR(x) (0x80 + (x) * 0x4) - -/** \brief Enables the output of MCLK Divider. - * Each MCLK divider can be enabled separately. - */ -#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) - -#endif - -/** \brief Bits for setting MCLK source clock. */ -#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) - -/** \brief Offset of BCLK x M/N Divider M Value Register. */ -#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) - -/** \brief Offset of BCLK x M/N Divider N Value Register. */ -#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) - -/** \brief Bits for setting M/N source clock. */ -#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) - -/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ -#define MN_SOURCE_CLKS_MASK 0x3 - #if CONFIG_INTEL_MN /** \brief BCLKs can be driven by multiple sources - M/N or XTAL directly. * Even in the case of M/N, the actual clock source can be XTAL, @@ -334,7 +116,7 @@ struct dai_intel_ssp_plat_data { uint32_t base; uint32_t ip_base; uint32_t shim_base; -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) uint32_t hdamlssp_base; uint32_t i2svss_base; #endif diff --git a/drivers/dai/intel/ssp/ssp_regs_v1.h b/drivers/dai/intel/ssp/ssp_regs_v1.h new file mode 100644 index 00000000000000..a821ab8733a63e --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v1.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV1_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV1_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 +#define SSIOC 0x4C +#define SSGFS 0x50 +#define SSDR 0x10 /* Not PTL */ +#define SSTSA 0x30 /* Not PTL */ +#define SSRSA 0x34 /* Not PTL */ + +#define OUT_FIFO SSDR +#define IN_FIFO SSDR + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_ECS BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_NCS BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_ACS BIT(30) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_SPO BIT(3) +#define SSCR1_SPH BIT(4) +#define SSCR1_MWDS BIT(5) +#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) +#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) +#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) +#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) +#define SSCR1_EFWR BIT(14) +#define SSCR1_STRF BIT(15) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSRE BIT(20) +#define SSCR1_TSRE BIT(21) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_ECRB BIT(26) +#define SSCR1_ECRA BIT(27) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_TNF BIT(2) +#define SSSR_RNE BIT(3) +#define SSSR_BSY BIT(4) +#define SSSR_TFS BIT(5) +#define SSSR_RFS BIT(6) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_ETDS BIT(3) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSTSA_TXEN BIT(8) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSRSA_RXEN BIT(8) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 + +#define I2SLCTL_SPA(x) BIT(0 + x) +#define I2SLCTL_CPA(x) BIT(8 + x) + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) +#else +#define MN_MDIVCTRL 0x0 +#define MN_MDIVR(x) (0x80 + (x) * 0x4) +#endif + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV1_H__ */ diff --git a/drivers/dai/intel/ssp/ssp_regs_v2.h b/drivers/dai/intel/ssp/ssp_regs_v2.h new file mode 100644 index 00000000000000..e2d1c826d075c3 --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v2.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV2_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV2_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 + +#define SSIOC 0x4C +#define SSGFS 0x50 +#define SSDR 0x10 /* Not PTL */ +#define SSTSA 0x30 /* Not PTL */ +#define SSRSA 0x34 /* Not PTL */ + +#define OUT_FIFO SSDR +#define IN_FIFO SSDR + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_ECS BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_NCS BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_ACS BIT(30) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_SPO BIT(3) +#define SSCR1_SPH BIT(4) +#define SSCR1_MWDS BIT(5) +#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6) +#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1) +#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10) +#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1) +#define SSCR1_EFWR BIT(14) +#define SSCR1_STRF BIT(15) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSRE BIT(20) +#define SSCR1_TSRE BIT(21) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_ECRB BIT(26) +#define SSCR1_ECRA BIT(27) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_TNF BIT(2) +#define SSSR_RNE BIT(3) +#define SSSR_BSY BIT(4) +#define SSSR_TFS BIT(5) +#define SSSR_RFS BIT(6) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_ETDS BIT(3) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSTSA_TXEN BIT(8) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSRSA_RXEN BIT(8) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 +#define I2SLCTL_OFLEN BIT(4) +#define I2SLCTL_SPA(x) BIT(16 + x) +#define I2SLCTL_CPA(x) BIT(23 + x) +#define PCMS0CM_OFFSET 0x16 +#define PCMS1CM_OFFSET 0x1A + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV2_H__ */ diff --git a/drivers/dai/intel/ssp/ssp_regs_v3.h b/drivers/dai/intel/ssp/ssp_regs_v3.h new file mode 100644 index 00000000000000..958c3919c6051b --- /dev/null +++ b/drivers/dai/intel/ssp/ssp_regs_v3.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DAI_DRIVER_SSP_REGSV3_H__ +#define __INTEL_DAI_DRIVER_SSP_REGSV3_H__ + +/* SSP register offsets */ +#define SSCR0 0x00 +#define SSCR1 0x04 +#define SSSR 0x08 +#define SSITR 0x0C +#define SSTO 0x28 +#define SSPSP 0x2C +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 + +#define SSIOC 0x4C +#define SSGFS 0x50 + +#define I2SIPCMC 8 +#define SSMIDyCS(y) 0x60 + 0x10*y +#define SSMIDyD(y) 0x64 + 0x10*y +#define SSMIDyTSA(y) 0x68 + 0x10*y +#define SSMODyCS(y) 0x60 + 0x10*I2SIPCMC + 0x10*y +#define SSMODyD(y) 0x64 + 0x10*I2SIPCMC + 0x10*y +#define SSMODyTSA(y) 0x68 + 0x10*I2SIPCMC + 0x10*y + +#define OUT_FIFO SSMODyD(0) +#define IN_FIFO SSMIDyD(0) + +/* SSCR0 bits */ +#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1) +#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1) +#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4) +#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0) +#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1) +#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2) +#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3) +#define SSCR0_RSVD1 BIT(6) +#define SSCR0_SSE BIT(7) +#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8) +#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x) +#define SSCR0_EDSS BIT(20) +#define SSCR0_RSVD2 BIT(21) +#define SSCR0_RIM BIT(22) +#define SSCR0_TIM BIT(23) +#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1) +#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1) +#define SSCR0_EFRDC BIT(27) +#define SSCR0_EFRDC2 BIT(28) +#define SSCR0_DLE DAI_INTEL_SSP_SET_BITS(30, 29, 0) +#define SSCR0_MOD BIT(31) + +/* SSCR1 bits */ +#define SSCR1_RIE BIT(0) +#define SSCR1_TIE BIT(1) +#define SSCR1_LBM BIT(2) +#define SSCR1_RSVD1 DAI_INTEL_SSP_MASK(15, 3) +#define SSCR1_IFS BIT(16) +#define SSCR1_PINTE BIT(18) +#define SSCR1_TINTE BIT(19) +#define SSCR1_RSVD21 DAI_INTEL_SSP_MASK(21, 20) +#define SSCR1_TRAIL BIT(22) +#define SSCR1_RWOT BIT(23) +#define SSCR1_SFRMDIR BIT(24) +#define SSCR1_SCLKDIR BIT(25) +#define SSCR1_SCFR BIT(28) +#define SSCR1_EBCEI BIT(29) +#define SSCR1_TTE BIT(30) +#define SSCR1_TTELP BIT(31) + +#define SSCR2_TURM1 BIT(1) +#define SSCR2_PSPSRWFDFD BIT(3) +#define SSCR2_PSPSTWFDFD BIT(4) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#define SSCR2_MMRATF BIT(18) +#define SSCR2_SMTATF BIT(19) +#define SSCR2_SFRMEN BIT(20) +#define SSCR2_ACIOLBS BIT(21) + +/* SSR bits */ +#define SSSR_BSY BIT(4) +#define SSSR_ROR BIT(7) +#define SSSR_TUR BIT(21) + +/* SSPSP bits */ +#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x) +#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x) +#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x) +#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x) +#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x) +#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x) +#define SSPSP_DMYSTOP_BITS 2 +#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0) +#define SSPSP_FSRT BIT(25) +#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x) + +#define SSPSP2 0x44 +#define SSPSP2_FEP_MASK 0xff + +#define SSPSP2_RFAC DAI_INTEL_SSP_MASK(9, 8) +#define SSPSP2_TFAC DAI_INTEL_SSP_MASK(11, 10) +#define SSPSP2_EFEP DAI_INTEL_SSP_MASK(13, 12) +#define SSPSP2_ESFRMDW DAI_INTEL_SSP_MASK(15, 14) + + +#define SSCR3 0x48 +#define SSIOC 0x4C +#define SSP_REG_MAX SSIOC + +/* SSTSA bits */ +#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) + +/* SSRSA bits */ +#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x) +#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0)) + +/* SSCR3 bits */ +#define SSCR3_FRM_MST_EN BIT(0) +#define SSCR3_I2S_MODE_EN BIT(1) +#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x) +#define SSCR3_I2S_TX_SS_FIX_EN BIT(3) +#define SSCR3_I2S_RX_SS_FIX_EN BIT(4) +#define SSCR3_I2S_TX_EN BIT(9) +#define SSCR3_I2S_RX_EN BIT(10) +#define SSCR3_CLK_EDGE_SEL BIT(12) +#define SSCR3_STRETCH_TX BIT(14) +#define SSCR3_STRETCH_RX BIT(15) +#define SSCR3_MST_CLK_EN BIT(16) +#define SSCR3_SYN_FIX_EN BIT(17) + +/* SSCR4 bits */ +#define SSCR4_TOT_FRM_PRD(x) ((x) << 7) + +/* SSCR5 bits */ +#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1) +#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x) + +/* SFIFOTT bits */ +#define SFIFOTT_TX(x) ((x) - 1) +#define SFIFOTT_RX(x) (((x) - 1) << 16) + +/* SFIFOL bits */ +#define SFIFOL_TFL(x) ((x) & 0xFFFF) +#define SFIFOL_RFL(x) ((x) >> 16) + +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0) +#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8) +#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0)) +#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1) +#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) + +/* SSMIDyCS */ +#define SSMIDyCS_RXEN BIT(0) +#define SSMIDyCS_RSRE BIT(1) +#define SSMIDyCS_RFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_RFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMIDyCS_RNE BIT(26) +#define SSMIDyCS_RFS BIT(27) +#define SSMIDyCS_ROR BIT(28) +#define SSMIDyCS_PINT BIT(29) +#define SSMIDyCS_TINT BIT(30) +#define SSMIDyCS_EOC BIT(31) + +/* SSMIDyTSA */ +#define SSMIDyTSA_RTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMIDyTSA_SRTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* SSMODyCS */ +#define SSMODyCS_TXEN BIT(0) +#define SSMODyCS_TSRE BIT(1) +#define SSMODyCS_TFL DAI_INTEL_SSP_MASK(23, 16) +#define SSMIDyCS_TFL_VAL(rfl_val) (((rfl_val) >> 16) & DAI_INTEL_SSP_MASK(7, 0)) +#define SSMODyCS_TNF BIT(26) +#define SSMODyCS_TFS BIT(27) +#define SSMODyCS_TUR BIT(28) + +/* SSMODyTSA */ +#define SSMODyTSA_TTSA DAI_INTEL_SSP_MASK(63, 0) +#define SSMODyTSA_STTSA(x) DAI_INTEL_SSP_MASK(63, 0, x) + +/* For 8000 Hz rate one sample is transmitted within 125us */ +#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125 + +/* SSP flush retry counts maximum */ +#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16 + +#define SSP_CLK_MCLK_ES_REQ BIT(0) +#define SSP_CLK_MCLK_ACTIVE BIT(1) +#define SSP_CLK_BCLK_ES_REQ BIT(2) +#define SSP_CLK_BCLK_ACTIVE BIT(3) + +#define I2SLCTL_OFFSET 0x04 + +#define I2SLCTL_OFLEN BIT(4) +#define I2SLCTL_SPA(x) BIT(16 + x) +#define I2SLCTL_CPA(x) BIT(23 + x) +#define PCMS0CM_OFFSET 0x16 +#define PCMS1CM_OFFSET PCMS0CM_OFFSET + 4 * I2SIPCMC + +#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x) +#define SHIM_CLKCTL 0x78 +#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x) +#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x) + +/** \brief Offset of MCLK Divider Control Register. */ +#define MN_MDIVCTRL 0x100 + +/** \brief Offset of MCLK Divider x Ratio Register. */ +#define MN_MDIVR(x) (0x180 + (x) * 0x4) + +/** \brief Enables the output of MCLK Divider. */ +#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x) + +/** \brief Bits for setting MCLK source clock. */ +#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x) + +/** \brief Offset of BCLK x M/N Divider M Value Register. */ +#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0) + +/** \brief Offset of BCLK x M/N Divider N Value Register. */ +#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4) + +/** \brief Bits for setting M/N source clock. */ +#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x) + +/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */ +#define MN_SOURCE_CLKS_MASK 0x3 + +#endif /* __INTEL_DAI_DRIVER_SSP_REGSV1_H__ */ diff --git a/drivers/disk/flashdisk.c b/drivers/disk/flashdisk.c index 6336ad4dfd03e7..6b71ea993c21e6 100644 --- a/drivers/disk/flashdisk.c +++ b/drivers/disk/flashdisk.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016 Intel Corporation. - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,11 @@ #include LOG_MODULE_REGISTER(flashdisk, CONFIG_FLASHDISK_LOG_LEVEL); +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ + defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#define DISK_ERASE_RUNTIME_CHECK +#endif + struct flashdisk_data { struct disk_info info; struct k_mutex lock; @@ -32,11 +37,43 @@ struct flashdisk_data { off_t cached_addr; bool cache_valid; bool cache_dirty; + bool erase_required; }; #define GET_SIZE_TO_BOUNDARY(start, block_size) \ (block_size - (start & (block_size - 1))) +/* + * The default block size is used for devices not requiring erase. + * It defaults to 512 as this is most widely used sector size + * on storage devices. + */ +#define DEFAULT_BLOCK_SIZE 512 + +static inline bool flashdisk_with_erase(const struct flashdisk_data *ctx) +{ + ARG_UNUSED(ctx); +#if CONFIG_FLASH_HAS_EXPLICIT_ERASE +#if CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE + return ctx->erase_required; +#else + return true; +#endif +#endif + return false; +} + +static inline void flashdisk_probe_erase(struct flashdisk_data *ctx) +{ +#if defined(DISK_ERASE_RUNTIME_CHECK) + ctx->erase_required = + flash_params_get_erase_cap(flash_get_parameters(ctx->info.dev)) & + FLASH_ERASE_C_EXPLICIT; +#else + ARG_UNUSED(ctx); +#endif +} + static int disk_flash_access_status(struct disk_info *disk) { LOG_DBG("status : %s", disk->dev ? "okay" : "no media"); @@ -54,13 +91,20 @@ static int flashdisk_init_runtime(struct flashdisk_data *ctx, struct flash_pages_info page; off_t offset; - rc = flash_get_page_info_by_offs(ctx->info.dev, ctx->offset, &page); - if (rc < 0) { - LOG_ERR("Error %d while getting page info", rc); - return rc; + flashdisk_probe_erase(ctx); + + if (IS_ENABLED(CONFIG_FLASHDISK_VERIFY_PAGE_LAYOUT) && flashdisk_with_erase(ctx)) { + rc = flash_get_page_info_by_offs(ctx->info.dev, ctx->offset, &page); + if (rc < 0) { + LOG_ERR("Error %d while getting page info", rc); + return rc; + } + + ctx->page_size = page.size; + } else { + ctx->page_size = DEFAULT_BLOCK_SIZE; } - ctx->page_size = page.size; LOG_INF("Initialize device %s", ctx->info.name); LOG_INF("offset %lx, sector size %zu, page size %zu, volume size %zu", (long)ctx->offset, ctx->sector_size, ctx->page_size, ctx->size); @@ -71,7 +115,7 @@ static int flashdisk_init_runtime(struct flashdisk_data *ctx, return 0; } - if (IS_ENABLED(CONFIG_FLASHDISK_VERIFY_PAGE_LAYOUT)) { + if (IS_ENABLED(CONFIG_FLASHDISK_VERIFY_PAGE_LAYOUT) && flashdisk_with_erase(ctx)) { if (ctx->offset != page.start_offset) { LOG_ERR("Disk %s does not start at page boundary", ctx->info.name); @@ -213,8 +257,10 @@ static int flashdisk_cache_commit(struct flashdisk_data *ctx) return 0; } - if (flash_erase(ctx->info.dev, ctx->cached_addr, ctx->page_size) < 0) { - return -EIO; + if (flashdisk_with_erase(ctx)) { + if (flash_erase(ctx->info.dev, ctx->cached_addr, ctx->page_size) < 0) { + return -EIO; + } } /* write data to flash */ @@ -389,6 +435,7 @@ static int disk_flash_access_ioctl(struct disk_info *disk, uint8_t cmd, void *bu ctx = CONTAINER_OF(disk, struct flashdisk_data, info); switch (cmd) { + case DISK_IOCTL_CTRL_DEINIT: case DISK_IOCTL_CTRL_SYNC: k_mutex_lock(&ctx->lock, K_FOREVER); rc = flashdisk_cache_commit(ctx); @@ -405,6 +452,8 @@ static int disk_flash_access_ioctl(struct disk_info *disk, uint8_t cmd, void *bu *(uint32_t *)buff = ctx->page_size / ctx->sector_size; k_mutex_unlock(&ctx->lock); return 0; + case DISK_IOCTL_CTRL_INIT: + return disk_flash_access_init(disk); default: break; } diff --git a/drivers/disk/loopback_disk.c b/drivers/disk/loopback_disk.c index 50b7beeaabc407..c7f587b0c19557 100644 --- a/drivers/disk/loopback_disk.c +++ b/drivers/disk/loopback_disk.c @@ -22,10 +22,6 @@ static inline struct loopback_disk_access *get_ctx(struct disk_info *info) return CONTAINER_OF(info, struct loopback_disk_access, info); } -static int loopback_disk_access_init(struct disk_info *disk) -{ - return 0; -} static int loopback_disk_access_status(struct disk_info *disk) { return DISK_STATUS_OK; @@ -111,12 +107,19 @@ static int loopback_disk_access_ioctl(struct disk_info *disk, uint8_t cmd, void *(uint32_t *)buff = LOOPBACK_SECTOR_SIZE; return 0; } + case DISK_IOCTL_CTRL_DEINIT: case DISK_IOCTL_CTRL_SYNC: return fs_sync(&ctx->file); + case DISK_IOCTL_CTRL_INIT: + return 0; default: return -ENOTSUP; } } +static int loopback_disk_access_init(struct disk_info *disk) +{ + return loopback_disk_access_ioctl(disk, DISK_IOCTL_CTRL_INIT, NULL); +} static const struct disk_operations loopback_disk_operations = { .init = loopback_disk_access_init, diff --git a/drivers/disk/mmc_subsys.c b/drivers/disk/mmc_subsys.c index 455d56818d3c15..c595c0edb8a7ef 100644 --- a/drivers/disk/mmc_subsys.c +++ b/drivers/disk/mmc_subsys.c @@ -38,11 +38,6 @@ static int disk_mmc_access_init(struct disk_info *disk) struct mmc_data *data = dev->data; int ret; - if (data->status == SD_OK) { - /* Called twice, don't reinit */ - return 0; - } - ret = sd_init(cfg->host_controller, &data->card); if (ret) { data->status = SD_ERROR; @@ -87,7 +82,21 @@ static int disk_mmc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buf) const struct device *dev = disk->dev; struct mmc_data *data = dev->data; - return mmc_ioctl(&data->card, cmd, buf); + switch (cmd) { + case DISK_IOCTL_CTRL_INIT: + return disk_mmc_access_init(disk); + case DISK_IOCTL_CTRL_DEINIT: + mmc_ioctl(&data->card, DISK_IOCTL_CTRL_SYNC, NULL); + /* sd_init() will toggle power to MMC, so we can just mark + * disk as uninitialized + */ + data->status = SD_UNINIT; + return 0; + default: + return mmc_ioctl(&data->card, cmd, buf); + } + + return 0; } static const struct disk_operations mmc_disk_ops = { diff --git a/drivers/disk/nvme/nvme_disk.c b/drivers/disk/nvme/nvme_disk.c index 9b46e0270d7ac8..5d1e18f6b72644 100644 --- a/drivers/disk/nvme/nvme_disk.c +++ b/drivers/disk/nvme/nvme_disk.c @@ -11,11 +11,6 @@ LOG_MODULE_DECLARE(nvme, CONFIG_NVME_LOG_LEVEL); #include "nvme.h" -static int nvme_disk_init(struct disk_info *disk) -{ - return 0; -} - static int nvme_disk_status(struct disk_info *disk) { return 0; @@ -183,9 +178,13 @@ static int nvme_disk_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) *(uint32_t *)buff = nvme_namespace_get_sector_size(ns); break; + case DISK_IOCTL_CTRL_DEINIT: case DISK_IOCTL_CTRL_SYNC: ret = nvme_disk_flush(ns); break; + case DISK_IOCTL_CTRL_INIT: + ret = 0; + break; default: ret = -EINVAL; } @@ -194,6 +193,11 @@ static int nvme_disk_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) return ret; } +static int nvme_disk_init(struct disk_info *disk) +{ + return nvme_disk_ioctl(disk, DISK_IOCTL_CTRL_INIT, NULL); +} + static const struct disk_operations nvme_disk_ops = { .init = nvme_disk_init, .status = nvme_disk_status, diff --git a/drivers/disk/ramdisk.c b/drivers/disk/ramdisk.c index 1d1fcc46a0d2f1..d4da37ea9d9d48 100644 --- a/drivers/disk/ramdisk.c +++ b/drivers/disk/ramdisk.c @@ -41,11 +41,6 @@ static int disk_ram_access_status(struct disk_info *disk) return DISK_STATUS_OK; } -static int disk_ram_access_init(struct disk_info *disk) -{ - return 0; -} - static int disk_ram_access_read(struct disk_info *disk, uint8_t *buff, uint32_t sector, uint32_t count) { @@ -98,6 +93,9 @@ static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff case DISK_IOCTL_GET_ERASE_BLOCK_SZ: *(uint32_t *)buff = 1U; break; + case DISK_IOCTL_CTRL_INIT: + case DISK_IOCTL_CTRL_DEINIT: + break; default: return -EINVAL; } @@ -105,6 +103,11 @@ static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff return 0; } +static int disk_ram_access_init(struct disk_info *disk) +{ + return disk_ram_access_ioctl(disk, DISK_IOCTL_CTRL_INIT, NULL); +} + static int disk_ram_init(const struct device *dev) { struct disk_info *info = dev->data; diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index a9cda286e3af6d..a344bb9d19235f 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -265,10 +265,6 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) struct stm32_sdmmc_priv *priv = dev->data; int err; - if (priv->status == DISK_STATUS_OK) { - return 0; - } - if (priv->status == DISK_STATUS_NOMEDIA) { return -ENODEV; } @@ -311,14 +307,18 @@ static int stm32_sdmmc_access_init(struct disk_info *disk) return 0; } -#if !defined(CONFIG_SDMMC_STM32_EMMC) -static void stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv) +static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv) { +#if defined(CONFIG_SDMMC_STM32_EMMC) + HAL_MMC_DeInit(&priv->hsd); +#else HAL_SD_DeInit(&priv->hsd); stm32_sdmmc_clock_disable(priv); -} #endif + priv->status = DISK_STATUS_UNINIT; + return 0; +} static int stm32_sdmmc_access_status(struct disk_info *disk) { @@ -485,6 +485,10 @@ static int stm32_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd, case DISK_IOCTL_CTRL_SYNC: /* we use a blocking API, so nothing to do for sync */ break; + case DISK_IOCTL_CTRL_INIT: + return stm32_sdmmc_access_init(disk); + case DISK_IOCTL_CTRL_DEINIT: + return stm32_sdmmc_access_deinit(priv); default: return -EINVAL; } diff --git a/drivers/disk/sdmmc_subsys.c b/drivers/disk/sdmmc_subsys.c index 863755841dad3c..e2511d1b1007a3 100644 --- a/drivers/disk/sdmmc_subsys.c +++ b/drivers/disk/sdmmc_subsys.c @@ -37,11 +37,6 @@ static int disk_sdmmc_access_init(struct disk_info *disk) struct sdmmc_data *data = dev->data; int ret; - if (data->status == SD_OK) { - /* Called twice, don't reinit */ - return 0; - } - if (!sd_is_card_present(cfg->host_controller)) { return DISK_STATUS_NOMEDIA; } @@ -94,7 +89,21 @@ static int disk_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *bu const struct device *dev = disk->dev; struct sdmmc_data *data = dev->data; - return sdmmc_ioctl(&data->card, cmd, buf); + switch (cmd) { + case DISK_IOCTL_CTRL_INIT: + return disk_sdmmc_access_init(disk); + case DISK_IOCTL_CTRL_DEINIT: + sdmmc_ioctl(&data->card, DISK_IOCTL_CTRL_SYNC, NULL); + /* sd_init() will toggle power to SDMMC, so we can just mark + * disk as uninitialized + */ + data->status = SD_UNINIT; + return 0; + default: + return sdmmc_ioctl(&data->card, cmd, buf); + } + + return 0; } static const struct disk_operations sdmmc_disk_ops = { diff --git a/drivers/display/Kconfig.ili9xxx b/drivers/display/Kconfig.ili9xxx index ccd6778d04a01b..d1710d176e9182 100644 --- a/drivers/display/Kconfig.ili9xxx +++ b/drivers/display/Kconfig.ili9xxx @@ -10,6 +10,15 @@ config ILI9XXX help Hidden configuration entry for all ILI9XXX drivers. +config ILI9XXX_READ + bool "Allow display_read API with ILI9XXX" + help + Support display_read API with ILI9XXX controllers. This API is opt-in, + because it adds code overhead and is not very performant due to + the requirement to bitshift data read from the ILI9XXX. Note the + API only supports RGB565 mode. + + config ILI9340 bool "ILI9340 display driver" default y diff --git a/drivers/display/Kconfig.st7789v b/drivers/display/Kconfig.st7789v index 5a452732779af6..61d9c5497fd356 100644 --- a/drivers/display/Kconfig.st7789v +++ b/drivers/display/Kconfig.st7789v @@ -7,7 +7,7 @@ menuconfig ST7789V bool "ST7789V display driver" default y depends on DT_HAS_SITRONIX_ST7789V_ENABLED - select SPI + select MIPI_DBI help Enable driver for ST7789V display driver. diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index c3a173078fafbd..fd3cd4e7b9eb1c 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -21,6 +21,49 @@ struct ili9xxx_data { enum display_orientation orientation; }; +#ifdef CONFIG_ILI9XXX_READ + +/* We set this LUT directly when reads are enabled, + * so that we can be sure the bitshift to convert GRAM data back + * to RGB565 will result in correct data + */ +const uint8_t ili9xxx_rgb_lut[] = { + 0, 2, 4, 6, + 8, 10, 12, 14, + 16, 18, 20, 22, + 24, 26, 28, 30, + 32, 34, 36, 38, + 40, 42, 44, 46, + 48, 50, 52, 54, + 56, 58, 60, 62, + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 21, 22, 23, + 24, 25, 26, 27, + 28, 29, 30, 31, + 32, 33, 34, 35, + 36, 37, 38, 39, + 40, 41, 42, 43, + 44, 45, 46, 47, + 48, 49, 50, 51, + 52, 53, 54, 55, + 56, 57, 58, 59, + 60, 61, 62, 63, + 0, 2, 4, 6, + 8, 10, 12, 14, + 16, 18, 20, 22, + 24, 26, 28, 30, + 32, 34, 36, 38, + 40, 42, 44, 46, + 48, 50, 52, 54, + 56, 58, 60, 62 +}; + +#endif + int ili9xxx_transmit(const struct device *dev, uint8_t cmd, const void *tx_data, size_t tx_len) { @@ -142,6 +185,93 @@ static int ili9xxx_write(const struct device *dev, const uint16_t x, return 0; } +#ifdef CONFIG_ILI9XXX_READ + +static int ili9xxx_read(const struct device *dev, const uint16_t x, + const uint16_t y, + const struct display_buffer_descriptor *desc, void *buf) +{ + const struct ili9xxx_config *config = dev->config; + struct ili9xxx_data *data = dev->data; + struct display_buffer_descriptor mipi_desc; + int r; + uint32_t gram_data, nbr_of_reads; + uint16_t *read_data_start = (uint16_t *)buf; + + if (data->pixel_format != PIXEL_FORMAT_RGB_565) { + /* Only RGB565 can be supported, see note below */ + return -ENOTSUP; + } + + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); + __ASSERT((desc->pitch * data->bytes_per_pixel * desc->height) <= + desc->buf_size, + "Output buffer to small"); + + LOG_DBG("Reading %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, + x, y); + + r = ili9xxx_set_mem_area(dev, x, y, desc->width, desc->height); + if (r < 0) { + return r; + } + + /* + * ILI9XXX stores all pixel data in graphics ram (GRAM) as 18 bit + * values. When using RGB565 pixel format, pixels are converted to + * 18 bit values via a lookup table. When using RGB888 format, the + * lower 2 bits of each pixel are simply dropped. When reading pixels, + * the response format will always look like so: + * | R[5:0] | x | x | G[5:0] | x | x | B[5:0] | x | x | + * Where x represents "don't care". The internal format of the + * ILI9XXX graphics RAM results in the following restrictions: + * - RGB888 mode can't be supported. + * - we can only read one pixel at once (since we need to do + * byte manipulation on the output) + */ + + /* Setup MIPI descriptor to read 3 bytes (one pixel in GRAM) */ + mipi_desc.width = 1; + mipi_desc.height = 1; + /* Per MIPI API, pitch must always match width */ + mipi_desc.pitch = 1; + + nbr_of_reads = desc->width * desc->height; + + /* Initial read command should consist of RAMRD command, plus + * 8 dummy clock cycles + */ + uint8_t cmd[] = {ILI9XXX_RAMRD, 0xFF}; + + for (uint32_t read_cnt = 0; read_cnt < nbr_of_reads; read_cnt++) { + r = mipi_dbi_command_read(config->mipi_dev, + &config->dbi_config, + cmd, sizeof(cmd), + (uint8_t *)&gram_data, 3); + if (r < 0) { + return r; + } + + /* Bitshift the graphics RAM data to RGB565. + * For more details on the formatting of this data, + * see "Read data through 4-line SPI mode" diagram + * on page 64 of datasheet. + */ + read_data_start[read_cnt] = + ((gram_data & 0xF80000) >> 11) | /* Blue */ + ((gram_data & 0x1C00) << 3) | /* Green */ + ((gram_data & 0xE000) >> 13) | /* Green */ + (gram_data & 0xF8); /* Red */ + + /* After first read, we should use read memory continue command */ + cmd[0] = ILI9XXX_RAMRD_CONT; + } + + return 0; +} + +#endif + static int ili9xxx_display_blanking_off(const struct device *dev) { LOG_DBG("Turning display blanking off"); @@ -321,6 +451,11 @@ static int ili9xxx_init(const struct device *dev) return r; } +#ifdef CONFIG_ILI9XXX_READ + /* Set RGB LUT table to enable display read API */ + ili9xxx_transmit(dev, ILI9XXX_RGBSET, ili9xxx_rgb_lut, sizeof(ili9xxx_rgb_lut)); +#endif + k_sleep(K_MSEC(ILI9XXX_RESET_WAIT_TIME)); ili9xxx_display_blanking_on(dev); @@ -344,6 +479,9 @@ static const struct display_driver_api ili9xxx_api = { .blanking_on = ili9xxx_display_blanking_on, .blanking_off = ili9xxx_display_blanking_off, .write = ili9xxx_write, +#ifdef CONFIG_ILI9XXX_READ + .read = ili9xxx_read, +#endif .get_capabilities = ili9xxx_get_capabilities, .set_pixel_format = ili9xxx_set_pixel_format, .set_orientation = ili9xxx_set_orientation, diff --git a/drivers/display/display_ili9xxx.h b/drivers/display/display_ili9xxx.h index ddf8254224ebc9..861b26d436099d 100644 --- a/drivers/display/display_ili9xxx.h +++ b/drivers/display/display_ili9xxx.h @@ -22,8 +22,11 @@ #define ILI9XXX_CASET 0x2a #define ILI9XXX_PASET 0x2b #define ILI9XXX_RAMWR 0x2c +#define ILI9XXX_RGBSET 0x2d +#define ILI9XXX_RAMRD 0x2e #define ILI9XXX_MADCTL 0x36 #define ILI9XXX_PIXSET 0x3A +#define ILI9XXX_RAMRD_CONT 0x3e /* MADCTL register fields. */ #define ILI9XXX_MADCTL_MY BIT(7U) diff --git a/drivers/display/display_renesas_lcdc.c b/drivers/display/display_renesas_lcdc.c index 2131b9149d3ccc..a5d3d412a1aff2 100644 --- a/drivers/display/display_renesas_lcdc.c +++ b/drivers/display/display_renesas_lcdc.c @@ -606,7 +606,7 @@ static int display_smartbond_pm_action(const struct device *dev, enum pm_device_ } #endif -static struct display_driver_api display_smartbond_driver_api = { +static const struct display_driver_api display_smartbond_driver_api = { .write = display_smartbond_write, .read = display_smartbond_read, .get_framebuffer = display_smartbond_get_framebuffer, diff --git a/drivers/display/display_st7789v.c b/drivers/display/display_st7789v.c index 72ae4eb0436313..69e4e2cdb021bb 100644 --- a/drivers/display/display_st7789v.c +++ b/drivers/display/display_st7789v.c @@ -14,8 +14,7 @@ #include "display_st7789v.h" #include -#include -#include +#include #include #include #include @@ -25,9 +24,8 @@ LOG_MODULE_REGISTER(display_st7789v); struct st7789v_config { - struct spi_dt_spec bus; - struct gpio_dt_spec cmd_data_gpio; - struct gpio_dt_spec reset_gpio; + const struct device *mipi_dbi; + const struct mipi_dbi_config dbi_config; uint8_t vcom; uint8_t gctrl; bool vdv_vrh_enable; @@ -73,38 +71,9 @@ static void st7789v_transmit(const struct device *dev, uint8_t cmd, uint8_t *tx_data, size_t tx_count) { const struct st7789v_config *config = dev->config; - uint16_t data = cmd; - - struct spi_buf tx_buf = { .buf = &cmd, .len = 1 }; - struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; - - if (config->cmd_data_gpio.port != NULL) { - if (cmd != ST7789V_CMD_NONE) { - gpio_pin_set_dt(&config->cmd_data_gpio, 1); - spi_write_dt(&config->bus, &tx_bufs); - } - - if (tx_data != NULL) { - tx_buf.buf = tx_data; - tx_buf.len = tx_count; - gpio_pin_set_dt(&config->cmd_data_gpio, 0); - spi_write_dt(&config->bus, &tx_bufs); - } - } else { - tx_buf.buf = &data; - tx_buf.len = 2; - - if (cmd != ST7789V_CMD_NONE) { - spi_write_dt(&config->bus, &tx_bufs); - } - - if (tx_data != NULL) { - for (size_t index = 0; index < tx_count; ++index) { - data = 0x0100 | tx_data[index]; - spi_write_dt(&config->bus, &tx_bufs); - } - } - } + + mipi_dbi_command_write(config->mipi_dbi, &config->dbi_config, cmd, + tx_data, tx_count); } static void st7789v_exit_sleep(const struct device *dev) @@ -115,18 +84,19 @@ static void st7789v_exit_sleep(const struct device *dev) static void st7789v_reset_display(const struct device *dev) { + const struct st7789v_config *config = dev->config; + int ret; + LOG_DBG("Resetting display"); - const struct st7789v_config *config = dev->config; - if (config->reset_gpio.port != NULL) { - k_sleep(K_MSEC(1)); - gpio_pin_set_dt(&config->reset_gpio, 1); - k_sleep(K_MSEC(6)); - gpio_pin_set_dt(&config->reset_gpio, 0); - k_sleep(K_MSEC(20)); - } else { + k_sleep(K_MSEC(1)); + ret = mipi_dbi_reset(config->mipi_dbi, 6); + if (ret == -ENOTSUP) { + /* Send software reset command */ st7789v_transmit(dev, ST7789V_CMD_SW_RESET, NULL, 0); k_sleep(K_MSEC(5)); + } else { + k_sleep(K_MSEC(20)); } } @@ -166,9 +136,12 @@ static int st7789v_write(const struct device *dev, const struct display_buffer_descriptor *desc, const void *buf) { + const struct st7789v_config *config = dev->config; + struct display_buffer_descriptor mipi_desc; const uint8_t *write_data_start = (uint8_t *) buf; uint16_t nbr_of_writes; uint16_t write_h; + enum display_pixel_format pixfmt; __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); __ASSERT((desc->pitch * ST7789V_PIXEL_SIZE * desc->height) <= desc->buf_size, @@ -181,15 +154,31 @@ static int st7789v_write(const struct device *dev, if (desc->pitch > desc->width) { write_h = 1U; nbr_of_writes = desc->height; + mipi_desc.height = 1; + mipi_desc.buf_size = desc->pitch * ST7789V_PIXEL_SIZE; } else { write_h = desc->height; nbr_of_writes = 1U; + mipi_desc.height = desc->height; + mipi_desc.buf_size = desc->width * write_h * ST7789V_PIXEL_SIZE; } + if (IS_ENABLED(CONFIG_ST7789V_RGB565)) { + pixfmt = PIXEL_FORMAT_RGB_565; + } else { + pixfmt = PIXEL_FORMAT_RGB_888; + } + + mipi_desc.width = desc->width; + /* Per MIPI API, pitch must always match width */ + mipi_desc.pitch = desc->width; + + /* Send RAMWR command */ + st7789v_transmit(dev, ST7789V_CMD_RAMWR, NULL, 0); for (uint16_t write_cnt = 0U; write_cnt < nbr_of_writes; ++write_cnt) { - st7789v_transmit(dev, write_cnt == 0U ? ST7789V_CMD_RAMWR : ST7789V_CMD_NONE, - (void *) write_data_start, - desc->width * ST7789V_PIXEL_SIZE * write_h); + mipi_dbi_write_display(config->mipi_dbi, &config->dbi_config, + write_data_start, &mipi_desc, pixfmt); + write_data_start += (desc->pitch * ST7789V_PIXEL_SIZE); } @@ -326,35 +315,11 @@ static int st7789v_init(const struct device *dev) { const struct st7789v_config *config = dev->config; - if (!spi_is_ready_dt(&config->bus)) { - LOG_ERR("SPI device not ready"); + if (!device_is_ready(config->mipi_dbi)) { + LOG_ERR("MIPI DBI device not ready"); return -ENODEV; } - if (config->reset_gpio.port != NULL) { - if (!gpio_is_ready_dt(&config->reset_gpio)) { - LOG_ERR("Reset GPIO device not ready"); - return -ENODEV; - } - - if (gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE)) { - LOG_ERR("Couldn't configure reset pin"); - return -EIO; - } - } - - if (config->cmd_data_gpio.port != NULL) { - if (!gpio_is_ready_dt(&config->cmd_data_gpio)) { - LOG_ERR("CMD/DATA GPIO device not ready"); - return -ENODEV; - } - - if (gpio_pin_configure_dt(&config->cmd_data_gpio, GPIO_OUTPUT)) { - LOG_ERR("Couldn't configure CMD/DATA pin"); - return -EIO; - } - } - st7789v_reset_display(dev); st7789v_blanking_on(dev); @@ -398,14 +363,14 @@ static const struct display_driver_api st7789v_api = { }; #define ST7789V_WORD_SIZE(inst) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, cmd_data_gpios), (8), (9)) - + ((DT_INST_PROP(inst, mipi_mode) == MIPI_DBI_MODE_SPI_4WIRE) ? \ + SPI_WORD_SET(8) : SPI_WORD_SET(9)) #define ST7789V_INIT(inst) \ static const struct st7789v_config st7789v_config_ ## inst = { \ - .bus = SPI_DT_SPEC_INST_GET(inst, SPI_OP_MODE_MASTER | \ - SPI_WORD_SET(ST7789V_WORD_SIZE(inst)), 0), \ - .cmd_data_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, cmd_data_gpios, {}), \ - .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}), \ + .mipi_dbi = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .dbi_config = MIPI_DBI_CONFIG_DT_INST(inst, \ + ST7789V_WORD_SIZE(inst) | \ + SPI_OP_MODE_MASTER, 0), \ .vcom = DT_INST_PROP(inst, vcom), \ .gctrl = DT_INST_PROP(inst, gctrl), \ .vdv_vrh_enable = (DT_INST_NODE_HAS_PROP(inst, vrhs) \ diff --git a/drivers/display/display_st7789v.h b/drivers/display/display_st7789v.h index aa16e8d5633b66..191135b02fe6e2 100644 --- a/drivers/display/display_st7789v.h +++ b/drivers/display/display_st7789v.h @@ -68,6 +68,4 @@ #define ST7789V_CMD_PVGAMCTRL 0xe0 #define ST7789V_CMD_NVGAMCTRL 0xe1 -#define ST7789V_CMD_NONE 0xff - #endif diff --git a/drivers/display/display_st7796s.c b/drivers/display/display_st7796s.c index 131928b2fc7367..df4271d1b5d19b 100644 --- a/drivers/display/display_st7796s.c +++ b/drivers/display/display_st7796s.c @@ -7,8 +7,6 @@ #define DT_DRV_COMPAT sitronix_st7796s #include -#include -#include #include #include #include @@ -30,8 +28,6 @@ LOG_MODULE_REGISTER(display_st7796s, CONFIG_DISPLAY_LOG_LEVEL); struct st7796s_config { const struct device *mipi_dbi; const struct mipi_dbi_config dbi_config; - const struct gpio_dt_spec cmd_data_gpio; - const struct gpio_dt_spec reset_gpio; uint16_t width; uint16_t height; bool inverted; /* Display color inversion */ diff --git a/drivers/display/ls0xx.c b/drivers/display/ls0xx.c index 95f640ee4a137f..0616148e93267b 100644 --- a/drivers/display/ls0xx.c +++ b/drivers/display/ls0xx.c @@ -278,7 +278,7 @@ static const struct ls0xx_config ls0xx_config = { #endif }; -static struct display_driver_api ls0xx_driver_api = { +static const struct display_driver_api ls0xx_driver_api = { .blanking_on = ls0xx_blanking_on, .blanking_off = ls0xx_blanking_off, .write = ls0xx_write, diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 563c8d2071f88e..9ed263749e1604 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -455,7 +455,7 @@ static int ssd1306_init(const struct device *dev) return 0; } -static struct display_driver_api ssd1306_driver_api = { +static const struct display_driver_api ssd1306_driver_api = { .blanking_on = ssd1306_suspend, .blanking_off = ssd1306_resume, .write = ssd1306_write, diff --git a/drivers/display/ssd16xx.c b/drivers/display/ssd16xx.c index 53da2c33f40504..16ab70237338c4 100644 --- a/drivers/display/ssd16xx.c +++ b/drivers/display/ssd16xx.c @@ -66,6 +66,7 @@ struct ssd16xx_data { uint8_t scan_mode; bool blanking_on; enum ssd16xx_profile_type profile; + enum display_orientation orientation; }; struct ssd16xx_dt_array { @@ -100,7 +101,7 @@ struct ssd16xx_config { const struct ssd16xx_profile *profiles[SSD16XX_NUM_PROFILES]; - bool orientation; + uint16_t rotation; uint16_t height; uint16_t width; uint8_t tssv; @@ -380,53 +381,78 @@ static int ssd16xx_set_window(const struct device *dev, return -ENOTSUP; } - if ((y + desc->height) > panel_h) { - LOG_ERR("Buffer out of bounds (height)"); - return -EINVAL; - } + if (data->orientation == DISPLAY_ORIENTATION_NORMAL || + data->orientation == DISPLAY_ORIENTATION_ROTATED_180) { + if ((y + desc->height) > panel_h) { + LOG_ERR("Buffer out of bounds (height)"); + return -EINVAL; + } - if ((x + desc->width) > config->width) { - LOG_ERR("Buffer out of bounds (width)"); - return -EINVAL; - } + if ((x + desc->width) > config->width) { + LOG_ERR("Buffer out of bounds (width)"); + return -EINVAL; + } - if ((desc->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) { - LOG_ERR("Buffer height not multiple of %d", - EPD_PANEL_NUMOF_ROWS_PER_PAGE); - return -EINVAL; - } + if ((desc->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) { + LOG_ERR("Buffer height not multiple of %d", EPD_PANEL_NUMOF_ROWS_PER_PAGE); + return -EINVAL; + } - if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) { - LOG_ERR("Y coordinate not multiple of %d", - EPD_PANEL_NUMOF_ROWS_PER_PAGE); - return -EINVAL; + if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) { + LOG_ERR("Y coordinate not multiple of %d", EPD_PANEL_NUMOF_ROWS_PER_PAGE); + return -EINVAL; + } + } else { + if ((y + desc->height) > config->width) { + LOG_ERR("Buffer out of bounds (height)"); + return -EINVAL; + } + + if ((x + desc->width) > panel_h) { + LOG_ERR("Buffer out of bounds (width)"); + return -EINVAL; + } + + if ((desc->width % SSD16XX_PIXELS_PER_BYTE) != 0U) { + LOG_ERR("Buffer width not multiple of %d", SSD16XX_PIXELS_PER_BYTE); + return -EINVAL; + } + + if ((x % SSD16XX_PIXELS_PER_BYTE) != 0U) { + LOG_ERR("X coordinate not multiple of %d", SSD16XX_PIXELS_PER_BYTE); + return -EINVAL; + } } - switch (data->scan_mode) { - case SSD16XX_DATA_ENTRY_XIYDY: + switch (data->orientation) { + case DISPLAY_ORIENTATION_NORMAL: + x_start = (panel_h - 1 - y) / SSD16XX_PIXELS_PER_BYTE; + x_end = (panel_h - 1 - (y + desc->height - 1)) / SSD16XX_PIXELS_PER_BYTE; + y_start = x; + y_end = (x + desc->width - 1); + break; + case DISPLAY_ORIENTATION_ROTATED_90: + x_start = (panel_h - 1 - x) / SSD16XX_PIXELS_PER_BYTE; + x_end = (panel_h - 1 - (x + desc->width - 1)) / SSD16XX_PIXELS_PER_BYTE; + y_start = (config->width - 1 - y); + y_end = (config->width - 1 - (y + desc->height - 1)); + break; + case DISPLAY_ORIENTATION_ROTATED_180: x_start = y / SSD16XX_PIXELS_PER_BYTE; x_end = (y + desc->height - 1) / SSD16XX_PIXELS_PER_BYTE; y_start = (x + desc->width - 1); y_end = x; break; - - case SSD16XX_DATA_ENTRY_XDYIY: - x_start = (panel_h - 1 - y) / SSD16XX_PIXELS_PER_BYTE; - x_end = (panel_h - 1 - (y + desc->height - 1)) / - SSD16XX_PIXELS_PER_BYTE; - y_start = x; - y_end = (x + desc->width - 1); + case DISPLAY_ORIENTATION_ROTATED_270: + x_start = x / SSD16XX_PIXELS_PER_BYTE; + x_end = (x + desc->width - 1) / SSD16XX_PIXELS_PER_BYTE; + y_start = y; + y_end = (y + desc->height - 1); break; default: return -EINVAL; } - err = ssd16xx_write_cmd(dev, SSD16XX_CMD_ENTRY_MODE, - &data->scan_mode, sizeof(data->scan_mode)); - if (err < 0) { - return err; - } - err = ssd16xx_set_ram_param(dev, x_start, x_end, y_start, y_end); if (err < 0) { return err; @@ -585,6 +611,7 @@ static void ssd16xx_get_capabilities(const struct device *dev, struct display_capabilities *caps) { const struct ssd16xx_config *config = dev->config; + struct ssd16xx_data *data = dev->data; memset(caps, 0, sizeof(struct display_capabilities)); caps->x_resolution = config->width; @@ -592,9 +619,14 @@ static void ssd16xx_get_capabilities(const struct device *dev, config->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE; caps->supported_pixel_formats = PIXEL_FORMAT_MONO10; caps->current_pixel_format = PIXEL_FORMAT_MONO10; - caps->screen_info = SCREEN_INFO_MONO_VTILED | - SCREEN_INFO_MONO_MSB_FIRST | - SCREEN_INFO_EPD; + caps->screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD; + + if (data->orientation == DISPLAY_ORIENTATION_NORMAL || + data->orientation == DISPLAY_ORIENTATION_ROTATED_180) { + caps->screen_info |= SCREEN_INFO_MONO_VTILED; + } + + caps->current_orientation = data->orientation; } static int ssd16xx_set_pixel_format(const struct device *dev, @@ -608,6 +640,32 @@ static int ssd16xx_set_pixel_format(const struct device *dev, return -ENOTSUP; } +static int ssd16xx_set_orientation(const struct device *dev, + const enum display_orientation orientation) +{ + struct ssd16xx_data *data = dev->data; + int err; + + if (orientation == DISPLAY_ORIENTATION_NORMAL) { + data->scan_mode = SSD16XX_DATA_ENTRY_XDYIY; + } else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) { + data->scan_mode = SSD16XX_DATA_ENTRY_XDYDX; + } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) { + data->scan_mode = SSD16XX_DATA_ENTRY_XIYDY; + } else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) { + data->scan_mode = SSD16XX_DATA_ENTRY_XIYIX; + } + + err = ssd16xx_write_uint8(dev, SSD16XX_CMD_ENTRY_MODE, data->scan_mode); + if (err < 0) { + return err; + } + + data->orientation = orientation; + + return 0; +} + static int ssd16xx_clear_cntlr_mem(const struct device *dev, uint8_t ram_cmd) { const struct ssd16xx_config *config = dev->config; @@ -831,6 +889,11 @@ static int ssd16xx_set_profile(const struct device *dev, } } + err = ssd16xx_write_uint8(dev, SSD16XX_CMD_ENTRY_MODE, data->scan_mode); + if (err < 0) { + return err; + } + data->profile = type; return 0; @@ -840,6 +903,7 @@ static int ssd16xx_controller_init(const struct device *dev) { const struct ssd16xx_config *config = dev->config; struct ssd16xx_data *data = dev->data; + enum display_orientation orientation; int err; LOG_DBG(""); @@ -860,12 +924,6 @@ static int ssd16xx_controller_init(const struct device *dev) k_msleep(SSD16XX_RESET_DELAY); - if (config->orientation == 1) { - data->scan_mode = SSD16XX_DATA_ENTRY_XIYDY; - } else { - data->scan_mode = SSD16XX_DATA_ENTRY_XDYIY; - } - err = ssd16xx_set_profile(dev, SSD16XX_PROFILE_FULL); if (err < 0) { return err; @@ -881,6 +939,21 @@ static int ssd16xx_controller_init(const struct device *dev) return err; } + if (config->rotation == 0U) { + orientation = DISPLAY_ORIENTATION_NORMAL; + } else if (config->rotation == 90U) { + orientation = DISPLAY_ORIENTATION_ROTATED_90; + } else if (config->rotation == 180U) { + orientation = DISPLAY_ORIENTATION_ROTATED_180; + } else { + orientation = DISPLAY_ORIENTATION_ROTATED_270; + } + + err = ssd16xx_set_orientation(dev, orientation); + if (err < 0) { + return err; + } + err = ssd16xx_update_display(dev); if (err < 0) { return err; @@ -947,13 +1020,14 @@ static int ssd16xx_init(const struct device *dev) return ssd16xx_controller_init(dev); } -static struct display_driver_api ssd16xx_driver_api = { +static const struct display_driver_api ssd16xx_driver_api = { .blanking_on = ssd16xx_blanking_on, .blanking_off = ssd16xx_blanking_off, .write = ssd16xx_write, .read = ssd16xx_read, .get_capabilities = ssd16xx_get_capabilities, .set_pixel_format = ssd16xx_set_pixel_format, + .set_orientation = ssd16xx_set_orientation, }; #if DT_HAS_COMPAT_STATUS_OKAY(solomon_ssd1608) @@ -1070,7 +1144,7 @@ static struct ssd16xx_quirks quirks_solomon_ssd1681 = { .quirks = quirks_ptr, \ .height = DT_PROP(n, height), \ .width = DT_PROP(n, width), \ - .orientation = DT_PROP(n, orientation_flipped), \ + .rotation = DT_PROP(n, rotation), \ .tssv = DT_PROP_OR(n, tssv, 0), \ .softstart = SSD16XX_ASSIGN_ARRAY(n, softstart), \ .profiles = { \ diff --git a/drivers/display/uc81xx.c b/drivers/display/uc81xx.c index 56cebee552b2ff..ae0a3bf667c778 100644 --- a/drivers/display/uc81xx.c +++ b/drivers/display/uc81xx.c @@ -754,7 +754,7 @@ static const struct uc81xx_quirks uc8179_quirks = { }; #endif -static struct display_driver_api uc81xx_driver_api = { +static const struct display_driver_api uc81xx_driver_api = { .blanking_on = uc81xx_blanking_on, .blanking_off = uc81xx_blanking_off, .write = uc81xx_write, diff --git a/drivers/dma/Kconfig.intel_adsp_hda b/drivers/dma/Kconfig.intel_adsp_hda index 20ced567cb084a..3761470fc95e73 100644 --- a/drivers/dma/Kconfig.intel_adsp_hda +++ b/drivers/dma/Kconfig.intel_adsp_hda @@ -45,6 +45,7 @@ config DMA_INTEL_ADSP_HDA config DMA_INTEL_ADSP_HDA_TIMING_L1_EXIT bool "Intel ADSP HDA Host L1 Exit Interrupt" default y if SOC_INTEL_ACE15_MTPM + default y if SOC_INTEL_ACE20_LNL depends on DMA_INTEL_ADSP_HDA_HOST_IN || DMA_INTEL_ADSP_HDA_HOST_OUT help Intel ADSP HDA Host Interrupt for L1 exit. diff --git a/drivers/dma/dma_smartbond.c b/drivers/dma/dma_smartbond.c index d3ded5ebc37bbf..493ac222836de3 100644 --- a/drivers/dma/dma_smartbond.c +++ b/drivers/dma/dma_smartbond.c @@ -343,6 +343,7 @@ static bool dma_channel_update_dreq_mode(enum dma_channel_direction direction, DMA_CTRL_REG_SET_FIELD(DREQ_MODE, *dma_ctrl_reg, DREQ_MODE_SW); break; case PERIPHERAL_TO_MEMORY: + case MEMORY_TO_PERIPHERAL: case PERIPHERAL_TO_PERIPHERAL: /* DMA channels starts by peripheral DMA req */ DMA_CTRL_REG_SET_FIELD(DREQ_MODE, *dma_ctrl_reg, DREQ_MODE_HW); diff --git a/drivers/edac/edac_ibecc.c b/drivers/edac/edac_ibecc.c index 06033a2bbb407c..f8ea556f434ba0 100644 --- a/drivers/edac/edac_ibecc.c +++ b/drivers/edac/edac_ibecc.c @@ -387,7 +387,7 @@ static bool handle_nmi(void) return true; } -bool z_x86_do_kernel_nmi(const z_arch_esf_t *esf) +bool z_x86_do_kernel_nmi(const struct arch_esf *esf) { const struct device *const dev = DEVICE_DT_GET(DEVICE_NODE); struct ibecc_data *data = dev->data; diff --git a/drivers/eeprom/Kconfig b/drivers/eeprom/Kconfig index 29405f4ed65fb0..43eb02e5f283ae 100644 --- a/drivers/eeprom/Kconfig +++ b/drivers/eeprom/Kconfig @@ -64,22 +64,36 @@ config EMUL_EEPROM_AT2X [DEPRECATED] Select EEPROM_AT2X_EMUL instead. config EEPROM_AT24 - bool "Atmel AT24 (and compatible) I2C EEPROM support" + bool "I2C EEPROMs compatible with Atmel's AT24 family" default y depends on DT_HAS_ATMEL_AT24_ENABLED select I2C select EEPROM_AT2X help - Enable support for Atmel AT24 (and compatible) I2C EEPROMs. + Enable support for I2C EEPROMs compatible with Atmel's AT24 family. + + There are multiple vendors manufacturing I2C EEPROMs compatible with + the programming model of the Atmel AT24. + + Examples of compatible EEPROM families: + - Microchip AT24xxx + - ST M24xxx config EEPROM_AT25 - bool "Atmel AT25 (and compatible) SPI EEPROM support" + bool "SPI EEPROMs compatibile with Atmel's AT25 family" default y depends on DT_HAS_ATMEL_AT25_ENABLED select SPI select EEPROM_AT2X help - Enable support for Atmel AT25 (and compatible) SPI EEPROMs. + Enable support for SPI EEPROMs compatible with Atmel's AT25 family. + + There are multiple vendors manufacturing SPI EEPROMs compatible with + the programming model of the Atmel AT25. + + Examples of compatible EEPROM families: + - Microchip AT25xxx + - ST M95xxx config EEPROM_AT2X_INIT_PRIORITY int "AT2X EEPROM init priority" diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index a9cbda2abc7304..2b079da3b8bf97 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -112,6 +112,10 @@ static int entropy_stm32_suspend(void) RNG_TypeDef *rng = dev_data->rng; int res; +#if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) + /* Prevent concurrent access with PM */ + z_stm32_hsem_lock(CFG_HW_RNG_SEMID, HSEM_LOCK_WAIT_FOREVER); +#endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ LL_RNG_Disable(rng); #ifdef CONFIG_SOC_SERIES_STM32WBAX @@ -136,6 +140,10 @@ static int entropy_stm32_suspend(void) res = clock_control_off(dev_data->clock, (clock_control_subsys_t)&dev_cfg->pclken[0]); +#if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) + z_stm32_hsem_unlock(CFG_HW_RNG_SEMID); +#endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ + return res; } @@ -710,7 +718,12 @@ static int entropy_stm32_rng_pm_action(const struct device *dev, switch (action) { case PM_DEVICE_ACTION_SUSPEND: - res = entropy_stm32_suspend(); +#if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) + /* Lock to Prevent concurrent access with PM */ + z_stm32_hsem_lock(CFG_HW_RNG_SEMID, HSEM_LOCK_WAIT_FOREVER); + /* Call release_rng instead of entropy_stm32_suspend to avoid double hsem_unlock */ +#endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ + release_rng(); break; case PM_DEVICE_ACTION_RESUME: if (IS_ENABLED(CONFIG_PM_S2RAM)) { @@ -724,7 +737,15 @@ static int entropy_stm32_rng_pm_action(const struct device *dev, entropy_stm32_rng_init(dev); } else if (!entropy_stm32_rng_data.filling_pools) { /* Resume RNG only if it was suspended during filling pool */ - entropy_stm32_suspend(); +#if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) + /* Lock to Prevent concurrent access with PM */ + z_stm32_hsem_lock(CFG_HW_RNG_SEMID, HSEM_LOCK_WAIT_FOREVER); + /* + * Call release_rng instead of entropy_stm32_suspend + * to avoid double hsem_unlock + */ +#endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ + release_rng(); } #endif /* health_test_config */ } else { diff --git a/drivers/espi/CMakeLists.txt b/drivers/espi/CMakeLists.txt index 5379d00ea21065..4826880f482997 100644 --- a/drivers/espi/CMakeLists.txt +++ b/drivers/espi/CMakeLists.txt @@ -10,8 +10,8 @@ zephyr_library_sources_ifdef(CONFIG_ESPI_NPCX host_subs_npcx.c) zephyr_library_sources_ifdef(CONFIG_ESPI_TAF_NPCX espi_taf_npcx.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE espi_handlers.c) zephyr_library_sources_ifdef(CONFIG_ESPI_EMUL espi_emul.c) -zephyr_library_sources_ifdef(CONFIG_ESPI_SAF_XEC espi_saf_mchp_xec.c) +zephyr_library_sources_ifdef(CONFIG_ESPI_TAF_XEC espi_saf_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_ESPI_XEC_V2 espi_mchp_xec_v2.c) zephyr_library_sources_ifdef(CONFIG_ESPI_XEC_V2 espi_mchp_xec_host_v2.c) zephyr_library_sources_ifdef(CONFIG_ESPI_IT8XXX2 espi_it8xxx2.c) -zephyr_library_sources_ifdef(CONFIG_ESPI_SAF_XEC_V2 espi_saf_mchp_xec_v2.c) +zephyr_library_sources_ifdef(CONFIG_ESPI_TAF_XEC_V2 espi_saf_mchp_xec_v2.c) diff --git a/drivers/espi/Kconfig b/drivers/espi/Kconfig index 0a8f6173b8d737..0bfacd1581259c 100644 --- a/drivers/espi/Kconfig +++ b/drivers/espi/Kconfig @@ -22,11 +22,11 @@ module = ESPI module-str = espi source "subsys/logging/Kconfig.template.log_config" -config ESPI_SLAVE - bool "ESPI slave driver" +config ESPI_TARGET + bool "ESPI target driver" default y help - Enables eSPI driver in slave mode. + Enables eSPI driver in target mode. config ESPI_INIT_PRIORITY int "ESPI Controller driver initialization priority" @@ -50,20 +50,20 @@ config ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE bool "Automatic acknowledge for eSPI HOST warnings" default y depends on ESPI_VWIRE_CHANNEL - depends on ESPI_SLAVE + depends on ESPI_TARGET help - Enable automatic acknowledgment from eSPI slave towards eSPI host + Enable automatic acknowledgment from eSPI target towards eSPI controller whenever it receives suspend or reset warning. If this is disabled, it means the app wants to be give the opportunity to prepare for either HOST suspend or reset. config ESPI_AUTOMATIC_BOOT_DONE_ACKNOWLEDGE - bool "Automatic acknowledge slave boot status" + bool "Automatic acknowledge target boot status" default y depends on ESPI_VWIRE_CHANNEL - depends on ESPI_SLAVE + depends on ESPI_TARGET help - Enable automatic acknowledgment from slave basic configuration been + Enable automatic acknowledgment from target basic configuration been completed by sending a virtual wire message to the eSPI master. This depends on SPI boot configuration. It could be either very early in the flow after the VW channel is configured. Or it could be @@ -176,19 +176,19 @@ config ESPI_OOB_CHANNEL_RX_ASYNC Enables asynchronous handling for host-initiated OOB traffic. Otherwise OOB traffic is assumed to be always client-initiated. -config ESPI_SAF - bool "ESPI SAF driver" +config ESPI_TAF + bool "ESPI TAF driver" depends on ESPI_FLASH_CHANNEL help - Enable Slave Attached Flash eSPI driver. SAF depends upon ESPI driver + Enable Target Attached Flash eSPI driver. TAF depends upon ESPI driver and flash channel. -config ESPI_SAF_INIT_PRIORITY - int "ESPI SAF driver initialization priority" - depends on ESPI_SAF +config ESPI_TAF_INIT_PRIORITY + int "ESPI TAF driver initialization priority" + depends on ESPI_TAF default 4 help - Driver initialization priority for eSPI SAF driver. SAF driver must + Driver initialization priority for eSPI TAF driver. TAF driver must initialize after the ESPI driver. endif # ESPI diff --git a/drivers/espi/Kconfig.xec b/drivers/espi/Kconfig.xec index b1752285c59c78..cbf749467c7ca3 100644 --- a/drivers/espi/Kconfig.xec +++ b/drivers/espi/Kconfig.xec @@ -63,21 +63,21 @@ config ESPI_FLASH_BUFFER_SIZE Use maximum RAM buffer size defined by spec but allow applications to override if eSPI host doesn't support it. -config ESPI_SAF_XEC - bool "XEC Microchip ESPI SAF driver" +config ESPI_TAF_XEC + bool "XEC Microchip ESPI TAF driver" default y depends on SOC_SERIES_MEC15XX depends on DT_HAS_MICROCHIP_XEC_ESPI_SAF_ENABLED help - Enable the Microchip XEC SAF ESPI driver for MEC15xx family. + Enable the Microchip XEC TAF ESPI driver for MEC15xx family. -config ESPI_SAF_XEC_V2 - bool "XEC Microchip ESPI SAF V2 driver" +config ESPI_TAF_XEC_V2 + bool "XEC Microchip ESPI TAF V2 driver" default y depends on SOC_SERIES_MEC172X depends on DT_HAS_MICROCHIP_XEC_ESPI_SAF_V2_ENABLED help - Enable the Microchip XEC SAF ESPI driver for MEC172x series. + Enable the Microchip XEC TAF ESPI driver for MEC172x series. endif #ESPI_XEC @@ -154,19 +154,19 @@ config ESPI_PERIPHERAL_XEC_EMI2 endif #ESPI_PERIPHERAL_CHANNEL -config ESPI_SAF - bool "XEC Microchip ESPI SAF driver" +config ESPI_TAF + bool "XEC Microchip ESPI TAF driver" depends on ESPI_FLASH_CHANNEL help - Enable Slave Attached Flash eSPI driver. SAF depends upon ESPI XEC driver + Enable Target Attached Flash eSPI driver. TAF depends upon ESPI XEC driver and flash channel. -config ESPI_SAF_INIT_PRIORITY - int "ESPI SAF driver initialization priority" - depends on ESPI_SAF +config ESPI_TAF_INIT_PRIORITY + int "ESPI TAF driver initialization priority" + depends on ESPI_TAF default 4 help - Driver initialization priority for eSPI SAF driver. + Driver initialization priority for ESPI TAF driver. config ESPI_PERIPHERAL_ACPI_EC_IBF_EVT_DATA bool "Read ACPI EC Event Data in IBF ISR" diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index 05d7b60e2eafd0..3d3f2c71073143 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -69,6 +69,7 @@ struct espi_npcx_data { #define NPCX_ESPI_MAXFREQ_25 1 #define NPCX_ESPI_MAXFREQ_33 2 #define NPCX_ESPI_MAXFREQ_50 3 +#define NPCX_ESPI_MAXFREQ_66 4 /* Minimum delay before acknowledging a virtual wire */ #define NPCX_ESPI_VWIRE_ACK_DELAY 10ul /* 10 us */ @@ -309,8 +310,8 @@ static void espi_bus_cfg_update_isr(const struct device *dev) espi_vw_send_bootload_done(dev); } -#if (defined(CONFIG_ESPI_FLASH_CHANNEL) && defined(CONFIG_ESPI_SAF)) - /* If CONFIG_ESPI_SAF is set, set to auto or manual mode accroding +#if (defined(CONFIG_ESPI_FLASH_CHANNEL) && defined(CONFIG_ESPI_TAF)) + /* If CONFIG_ESPI_TAF is set, set to auto or manual mode accroding * to configuration. */ if (IS_BIT_SET(inst->ESPICFG, NPCX_ESPICFG_FLCHANMODE)) { @@ -347,7 +348,7 @@ static void espi_bus_oob_rx_isr(const struct device *dev) #endif #if defined(CONFIG_ESPI_FLASH_CHANNEL) -#if defined(CONFIG_ESPI_SAF) +#if defined(CONFIG_ESPI_TAF) static struct espi_taf_pckt taf_pckt; static uint32_t espi_taf_parse(const struct device *dev) @@ -381,7 +382,7 @@ static uint32_t espi_taf_parse(const struct device *dev) return (uint32_t)&taf_pckt; } -#endif /* CONFIG_ESPI_SAF */ +#endif /* CONFIG_ESPI_TAF */ static void espi_bus_flash_rx_isr(const struct device *dev) { @@ -403,9 +404,9 @@ static void espi_bus_flash_rx_isr(const struct device *dev) #endif k_sem_give(&data->flash_rx_lock); } else { /* Target Attached Flash Access */ -#if defined(CONFIG_ESPI_SAF) +#if defined(CONFIG_ESPI_TAF) struct espi_event evt = { - .evt_type = ESPI_BUS_SAF_NOTIFICATION, + .evt_type = ESPI_BUS_TAF_NOTIFICATION, .evt_details = ESPI_CHANNEL_FLASH, .evt_data = espi_taf_parse(dev), }; @@ -676,6 +677,11 @@ static int espi_npcx_configure(const struct device *dev, struct espi_cfg *cfg) case 50: max_freq = NPCX_ESPI_MAXFREQ_50; break; +#ifdef CONFIG_SOC_SERIES_NPCX4 + case 66: + max_freq = NPCX_ESPI_MAXFREQ_66; + break; +#endif default: return -EINVAL; } @@ -1395,7 +1401,7 @@ static int espi_npcx_init(const struct device *dev) /* Configure host sub-modules which HW blocks belong to core domain */ npcx_host_init_subs_core_domain(dev, &data->callbacks); -#if defined(CONFIG_ESPI_FLASH_CHANNEL) && defined(CONFIG_ESPI_SAF) +#if defined(CONFIG_ESPI_FLASH_CHANNEL) && defined(CONFIG_ESPI_TAF) npcx_init_taf(dev, &data->callbacks); #endif diff --git a/drivers/espi/espi_saf_mchp_xec.c b/drivers/espi/espi_saf_mchp_xec.c index 6dd39b4f1b0fee..d649deaaa14f08 100644 --- a/drivers/espi/espi_saf_mchp_xec.c +++ b/drivers/espi/espi_saf_mchp_xec.c @@ -849,7 +849,7 @@ static const struct espi_saf_xec_config espi_saf_xec_config = { DEVICE_DT_INST_DEFINE(0, &espi_saf_xec_init, NULL, &espi_saf_xec_data, &espi_saf_xec_config, POST_KERNEL, - CONFIG_ESPI_SAF_INIT_PRIORITY, &espi_saf_xec_driver_api); + CONFIG_ESPI_TAF_INIT_PRIORITY, &espi_saf_xec_driver_api); static int espi_saf_xec_init(const struct device *dev) { diff --git a/drivers/espi/espi_saf_mchp_xec_v2.c b/drivers/espi/espi_saf_mchp_xec_v2.c index aa7ea6905816de..67fb4a5162fe2b 100644 --- a/drivers/espi/espi_saf_mchp_xec_v2.c +++ b/drivers/espi/espi_saf_mchp_xec_v2.c @@ -1027,7 +1027,7 @@ static void espi_saf_done_isr(const struct device *dev) struct mchp_espi_saf * const regs = xcfg->saf_base; const struct espi_xec_irq_info *safirq = &xcfg->irq_info_list[0]; uint32_t ecp_status = regs->SAF_ECP_STATUS; - struct espi_event evt = { .evt_type = ESPI_BUS_SAF_NOTIFICATION, + struct espi_event evt = { .evt_type = ESPI_BUS_TAF_NOTIFICATION, .evt_details = BIT(0), .evt_data = ecp_status }; @@ -1142,7 +1142,7 @@ static int espi_saf_xec_init(const struct device *dev) DEVICE_DT_INST_DEFINE(0, &espi_saf_xec_init, NULL, \ &espisaf_xec_data_##n, \ &espisaf_xec_config_##n, POST_KERNEL, \ - CONFIG_ESPI_SAF_INIT_PRIORITY, \ + CONFIG_ESPI_TAF_INIT_PRIORITY, \ &espi_saf_xec_driver_api); \ \ static void espi_saf_xec_connect_irqs_##n(void) \ diff --git a/drivers/espi/espi_taf_npcx.c b/drivers/espi/espi_taf_npcx.c index c1760f7adf9874..7878df2b123af9 100644 --- a/drivers/espi/espi_taf_npcx.c +++ b/drivers/espi/espi_taf_npcx.c @@ -499,7 +499,7 @@ static void espi_taf_work(struct k_work *item) static void espi_taf_event_handler(const struct device *dev, struct espi_callback *cb, struct espi_event event) { - if ((event.evt_type != ESPI_BUS_SAF_NOTIFICATION) || + if ((event.evt_type != ESPI_BUS_TAF_NOTIFICATION) || (event.evt_details != ESPI_CHANNEL_FLASH)) { return; } @@ -510,7 +510,7 @@ static void espi_taf_event_handler(const struct device *dev, struct espi_callbac int npcx_init_taf(const struct device *dev, sys_slist_t *callbacks) { - espi_init_callback(&espi_taf_cb, espi_taf_event_handler, ESPI_BUS_SAF_NOTIFICATION); + espi_init_callback(&espi_taf_cb, espi_taf_event_handler, ESPI_BUS_TAF_NOTIFICATION); espi_add_callback(dev, &espi_taf_cb); npcx_espi_taf_data.host_dev = dev; diff --git a/drivers/ethernet/Kconfig.native_posix b/drivers/ethernet/Kconfig.native_posix index 8ab1033d477b26..d4c065fbdde458 100644 --- a/drivers/ethernet/Kconfig.native_posix +++ b/drivers/ethernet/Kconfig.native_posix @@ -15,12 +15,13 @@ if ETH_NATIVE_POSIX config ETH_NATIVE_POSIX_INTERFACE_COUNT int "Number of network interfaces created" default NET_GPTP_NUM_PORTS if NET_GPTP + default PTP_NUM_PORTS if PTP default 1 range 1 32 help By default only one network interface is created. It is possible to create multiple interfaces in certain use cases. For example if - multiple ports are defined in gPTP, then multiple network interfaces + multiple ports are defined in gPTP or PTP, then multiple network interfaces must be created here. config ETH_NATIVE_POSIX_DRV_NAME @@ -40,9 +41,9 @@ config ETH_NATIVE_POSIX_DEV_NAME config ETH_NATIVE_POSIX_PTP_CLOCK bool "PTP clock driver support" - default y if NET_GPTP + default y if NET_GPTP || PTP select PTP_CLOCK - depends on NET_GPTP + depends on NET_GPTP || PTP help Enable PTP clock support. diff --git a/drivers/ethernet/eth_dwmac_mmu.c b/drivers/ethernet/eth_dwmac_mmu.c index b78fbbc035d6bb..f7136dfba4c49d 100644 --- a/drivers/ethernet/eth_dwmac_mmu.c +++ b/drivers/ethernet/eth_dwmac_mmu.c @@ -47,12 +47,12 @@ void dwmac_platform_init(struct dwmac_priv *p) sys_cache_data_invd_range(dwmac_tx_rx_descriptors, sizeof(dwmac_tx_rx_descriptors)); - desc_phys_addr = z_mem_phys_addr(dwmac_tx_rx_descriptors); + desc_phys_addr = k_mem_phys_addr(dwmac_tx_rx_descriptors); /* remap descriptor rings uncached */ - z_phys_map(&desc_uncached_addr, desc_phys_addr, - sizeof(dwmac_tx_rx_descriptors), - K_MEM_PERM_RW | K_MEM_CACHE_NONE); + k_mem_map_phys_bare(&desc_uncached_addr, desc_phys_addr, + sizeof(dwmac_tx_rx_descriptors), + K_MEM_PERM_RW | K_MEM_CACHE_NONE); LOG_DBG("desc virt %p uncached %p phys 0x%lx", dwmac_tx_rx_descriptors, desc_uncached_addr, desc_phys_addr); diff --git a/drivers/ethernet/eth_stm32_hal.c b/drivers/ethernet/eth_stm32_hal.c index 0da1411c3112a8..e27637a5706188 100644 --- a/drivers/ethernet/eth_stm32_hal.c +++ b/drivers/ethernet/eth_stm32_hal.c @@ -352,7 +352,8 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) #endif /* CONFIG_ETH_STM32_HAL_API_V2 */ #if defined(CONFIG_PTP_CLOCK_STM32_HAL) - timestamped_frame = eth_is_ptp_pkt(net_pkt_iface(pkt), pkt); + timestamped_frame = eth_is_ptp_pkt(net_pkt_iface(pkt), pkt) || + net_pkt_is_tx_timestamping(pkt); if (timestamped_frame) { /* Enable transmit timestamp */ #if defined(CONFIG_ETH_STM32_HAL_API_V2) @@ -789,13 +790,10 @@ static struct net_pkt *eth_rx(const struct device *dev) } #if defined(CONFIG_PTP_CLOCK_STM32_HAL) - if (eth_is_ptp_pkt(get_iface(dev_data), pkt)) { - pkt->timestamp.second = timestamp.second; - pkt->timestamp.nanosecond = timestamp.nanosecond; - } else { - /* Invalid value */ - pkt->timestamp.second = UINT64_MAX; - pkt->timestamp.nanosecond = UINT32_MAX; + pkt->timestamp.second = timestamp.second; + pkt->timestamp.nanosecond = timestamp.nanosecond; + if (timestamp.second != UINT64_MAX) { + net_pkt_set_rx_timestamping(pkt, true); } #endif /* CONFIG_PTP_CLOCK_STM32_HAL */ @@ -1823,7 +1821,7 @@ static int ptp_stm32_init(const struct device *port) #if defined(CONFIG_ETH_STM32_HAL_API_V2) /* Set PTP Configuration done */ - heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED; + heth->IsPtpConfigured = ETH_STM32_PTP_CONFIGURED; #endif return 0; diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index 55ae396c90dcc5..6402a9a3069695 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -9,6 +9,15 @@ #include #include +/* Naming of the ETH PTP Config Status changes depending on the stm32 serie */ +#if defined(CONFIG_SOC_SERIES_STM32F7X) || defined(CONFIG_SOC_SERIES_STM32F4X) +#define ETH_STM32_PTP_CONFIGURED HAL_ETH_PTP_CONFIGURATED +#define ETH_STM32_PTP_NOT_CONFIGURED HAL_ETH_PTP_NOT_CONFIGURATED +#else +#define ETH_STM32_PTP_CONFIGURED HAL_ETH_PTP_CONFIGURED +#define ETH_STM32_PTP_NOT_CONFIGURED HAL_ETH_PTP_NOT_CONFIGURED +#endif /* stm32F7x or sm32F4x */ + #define ST_OUI_B0 0x00 #define ST_OUI_B1 0x80 #define ST_OUI_B2 0xE1 diff --git a/drivers/ethernet/nxp_enet/Kconfig b/drivers/ethernet/nxp_enet/Kconfig index d2eb4d071358c2..2801b3c9c864fc 100644 --- a/drivers/ethernet/nxp_enet/Kconfig +++ b/drivers/ethernet/nxp_enet/Kconfig @@ -14,7 +14,7 @@ choice NXP_ENET_DRIVER config ETH_NXP_ENET bool "NXP ENET Ethernet driver" - select NOCACHE_MEMORY if HAS_MCUX_CACHE + select NOCACHE_MEMORY if HAS_MCUX_CACHE && CPU_HAS_DCACHE select ARM_MPU if CPU_CORTEX_M7 select MDIO if DT_HAS_NXP_ENET_MDIO_ENABLED select NET_POWER_MANAGEMENT if (PM_DEVICE && SOC_FAMILY_KINETIS) @@ -38,6 +38,13 @@ endchoice if ETH_NXP_ENET +config ETH_NXP_ENET_1G + bool "1G mode for ENET1G instance" + default y + depends on DT_HAS_NXP_ENET1G_ENABLED + help + Enable the use of the ENET1G ethernet instance in 1G mode. + config ETH_NXP_ENET_USE_DTCM_FOR_DMA_BUFFER bool "Use DTCM for hardware DMA buffers" default y @@ -48,6 +55,7 @@ config ETH_NXP_ENET_USE_DTCM_FOR_DMA_BUFFER config ETH_NXP_ENET_HW_ACCELERATION bool "Hardware acceleration" default y + depends on !NET_IPV6 help Enable hardware acceleration for the following: - IPv4, UDP and TCP checksum (both Rx and Tx) diff --git a/drivers/ethernet/nxp_enet/eth_nxp_enet.c b/drivers/ethernet/nxp_enet/eth_nxp_enet.c index befa92b91aed5e..8096185e5bcbb5 100644 --- a/drivers/ethernet/nxp_enet/eth_nxp_enet.c +++ b/drivers/ethernet/nxp_enet/eth_nxp_enet.c @@ -62,19 +62,27 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define ETH_NXP_ENET_UNIQUE_ID (OCOTP->FUSEN[40].FUSE) #elif defined(CONFIG_SOC_SERIES_KINETIS_K6X) #define ETH_NXP_ENET_UNIQUE_ID (SIM->UIDH ^ SIM->UIDMH ^ SIM->UIDML ^ SIM->UIDL) +#elif defined(CONFIG_SOC_SERIES_RW6XX) +#define ETH_NXP_ENET_UNIQUE_ID (OCOTP->OTP_SHADOW[46]) #else -#define ETH_NXP_ENET_UNIQUE_ID 0xFFFFFF #error "Unsupported SOC" #endif #define RING_ID 0 +enum mac_address_source { + MAC_ADDR_SOURCE_LOCAL, + MAC_ADDR_SOURCE_RANDOM, + MAC_ADDR_SOURCE_UNIQUE, + MAC_ADDR_SOURCE_FUSED, + MAC_ADDR_SOURCE_INVALID, +}; + struct nxp_enet_mac_config { ENET_Type *base; const struct device *clock_dev; clock_control_subsys_t clock_subsys; - bool generate_mac; - bool unique_mac; + enum mac_address_source mac_addr_source; const struct pinctrl_dev_config *pincfg; enet_buffer_config_t buffer_config; uint8_t phy_mode; @@ -260,9 +268,14 @@ static void eth_nxp_enet_iface_init(struct net_if *iface) static enum ethernet_hw_caps eth_nxp_enet_get_capabilities(const struct device *dev) { +#if defined(CONFIG_ETH_NXP_ENET_1G) + const struct nxp_enet_mac_config *config = dev->config; +#else ARG_UNUSED(dev); +#endif + enum ethernet_hw_caps caps; - return ETHERNET_LINK_10BASE_T | + caps = ETHERNET_LINK_10BASE_T | ETHERNET_HW_FILTERING | #if defined(CONFIG_NET_VLAN) ETHERNET_HW_VLAN | @@ -278,6 +291,13 @@ static enum ethernet_hw_caps eth_nxp_enet_get_capabilities(const struct device * ETHERNET_HW_RX_CHKSUM_OFFLOAD | #endif ETHERNET_LINK_100BASE_T; + + if (COND_CODE_1(IS_ENABLED(CONFIG_ETH_NXP_ENET_1G), + (config->phy_mode == NXP_ENET_RGMII_MODE), (0))) { + caps |= ETHERNET_LINK_1000BASE_T; + } + + return caps; } static int eth_nxp_enet_set_config(const struct device *dev, @@ -440,22 +460,18 @@ static void eth_nxp_enet_rx_thread(struct k_work *work) ENET_EnableInterrupts(config->base, kENET_RxFrameInterrupt); } -static int nxp_enet_phy_reset_and_configure(const struct device *phy) +static int nxp_enet_phy_configure(const struct device *phy, uint8_t phy_mode) { - int ret; + enum phy_link_speed speeds = LINK_HALF_10BASE_T | LINK_FULL_10BASE_T | + LINK_HALF_100BASE_T | LINK_FULL_100BASE_T; - /* Reset the PHY */ - ret = phy_write(phy, MII_BMCR, MII_BMCR_RESET); - if (ret) { - return ret; + if (COND_CODE_1(IS_ENABLED(CONFIG_ETH_NXP_ENET_1G), + (phy_mode == NXP_ENET_RGMII_MODE), (0))) { + speeds |= (LINK_HALF_1000BASE_T | LINK_FULL_1000BASE_T); } - /* 802.3u standard says reset takes up to 0.5s */ - k_busy_wait(500000); - /* Configure the PHY */ - return phy_configure_link(phy, LINK_HALF_10BASE_T | LINK_FULL_10BASE_T | - LINK_HALF_100BASE_T | LINK_FULL_100BASE_T); + return phy_configure_link(phy, speeds); } static void nxp_enet_phy_cb(const struct device *phy, @@ -464,19 +480,44 @@ static void nxp_enet_phy_cb(const struct device *phy, { const struct device *dev = eth_dev; struct nxp_enet_mac_data *data = dev->data; + const struct nxp_enet_mac_config *config = dev->config; + enet_mii_speed_t speed; + enet_mii_duplex_t duplex; + + if (state->is_up) { +#if defined(CONFIG_ETH_NXP_ENET_1G) + if (PHY_LINK_IS_SPEED_1000M(state->speed)) { + speed = kENET_MiiSpeed1000M; + } else if (PHY_LINK_IS_SPEED_100M(state->speed)) { +#else + if (PHY_LINK_IS_SPEED_100M(state->speed)) { +#endif + speed = kENET_MiiSpeed100M; + } else { + speed = kENET_MiiSpeed10M; + } + + if (PHY_LINK_IS_FULL_DUPLEX(state->speed)) { + duplex = kENET_MiiFullDuplex; + } else { + duplex = kENET_MiiHalfDuplex; + } + + ENET_SetMII(config->base, speed, duplex); + } if (!data->iface) { return; } + LOG_INF("Link is %s", state->is_up ? "up" : "down"); + if (!state->is_up) { net_eth_carrier_off(data->iface); - nxp_enet_phy_reset_and_configure(phy); + nxp_enet_phy_configure(phy, config->phy_mode); } else { net_eth_carrier_on(data->iface); } - - LOG_INF("Link is %s", state->is_up ? "up" : "down"); } @@ -485,7 +526,7 @@ static int nxp_enet_phy_init(const struct device *dev) const struct nxp_enet_mac_config *config = dev->config; int ret = 0; - ret = nxp_enet_phy_reset_and_configure(config->phy_dev); + ret = nxp_enet_phy_configure(config->phy_dev, config->phy_mode); if (ret) { return ret; } @@ -566,11 +607,13 @@ static void eth_nxp_enet_isr(const struct device *dev) irq_unlock(irq_lock_key); } +/* Note this is not universally unique, it just is probably unique on a network */ static inline void nxp_enet_unique_mac(uint8_t *mac_addr) { uint32_t id = ETH_NXP_ENET_UNIQUE_ID; - mac_addr[0] = FREESCALE_OUI_B0; + /* Setting LAA bit because it is not guaranteed universally unique */ + mac_addr[0] = FREESCALE_OUI_B0 | 0x02; mac_addr[1] = FREESCALE_OUI_B1; mac_addr[2] = FREESCALE_OUI_B2; mac_addr[3] = FIELD_GET(0xFF0000, id); @@ -578,6 +621,34 @@ static inline void nxp_enet_unique_mac(uint8_t *mac_addr) mac_addr[5] = FIELD_GET(0x0000FF, id); } +#ifdef CONFIG_SOC_FAMILY_NXP_IMXRT +#include +#endif + +static inline void nxp_enet_fused_mac(uint8_t *mac_addr) +{ +#ifdef CONFIG_SOC_FAMILY_NXP_IMXRT + uint32_t mac_addr_fuse[2] = {0}; + + OCOTP_ReadFuseShadowRegisterExt((OCOTP_Type *)OCOTP_BASE, +#if defined(CONFIG_SOC_SERIES_IMXRT10XX) + 0x620, +#elif defined(CONFIG_SOC_SERIES_IMXRT11XX) + 0xA90, +#endif + mac_addr_fuse, 2); + + mac_addr[0] = mac_addr_fuse[0] & 0x000000FF; + mac_addr[1] = mac_addr_fuse[0] & 0x0000FF00; + mac_addr[2] = mac_addr_fuse[0] & 0x00FF0000; + mac_addr[3] = mac_addr_fuse[0] & 0xFF000000; + mac_addr[4] = mac_addr_fuse[1] & 0x00FF; + mac_addr[5] = mac_addr_fuse[1] & 0xFF00; +#else + ARG_UNUSED(mac_addr); +#endif +} + static int eth_nxp_enet_init(const struct device *dev) { struct nxp_enet_mac_data *data = dev->data; @@ -601,13 +672,21 @@ static int eth_nxp_enet_init(const struct device *dev) #endif k_work_init(&data->rx_work, eth_nxp_enet_rx_thread); - if (config->unique_mac) { - nxp_enet_unique_mac(data->mac_addr); - } - - if (config->generate_mac) { + switch (config->mac_addr_source) { + case MAC_ADDR_SOURCE_LOCAL: + break; + case MAC_ADDR_SOURCE_RANDOM: gen_random_mac(data->mac_addr, FREESCALE_OUI_B0, FREESCALE_OUI_B1, FREESCALE_OUI_B2); + break; + case MAC_ADDR_SOURCE_UNIQUE: + nxp_enet_unique_mac(data->mac_addr); + break; + case MAC_ADDR_SOURCE_FUSED: + nxp_enet_fused_mac(data->mac_addr); + break; + default: + return -ENOTSUP; } err = clock_control_get_rate(config->clock_dev, config->clock_subsys, @@ -640,6 +719,10 @@ static int eth_nxp_enet_init(const struct device *dev) enet_config.miiMode = kENET_MiiMode; } else if (config->phy_mode == NXP_ENET_RMII_MODE) { enet_config.miiMode = kENET_RmiiMode; +#if defined(CONFIG_ETH_NXP_ENET_1G) + } else if (config->phy_mode == NXP_ENET_RGMII_MODE) { + enet_config.miiMode = kENET_RgmiiMode; +#endif } else { return -EINVAL; } @@ -783,7 +866,8 @@ static const struct ethernet_api api_funcs = { #define NXP_ENET_PHY_MODE(node_id) \ DT_ENUM_HAS_VALUE(node_id, phy_connection_type, mii) ? NXP_ENET_MII_MODE : \ (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, rmii) ? NXP_ENET_RMII_MODE : \ - NXP_ENET_INVALID_MII_MODE) + (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, rgmii) ? NXP_ENET_RGMII_MODE : \ + NXP_ENET_INVALID_MII_MODE)) #ifdef CONFIG_PTP_CLOCK_NXP_ENET #define NXP_ENET_PTP_DEV(n) .ptp_clock = DEVICE_DT_GET(DT_INST_PHANDLE(n, nxp_ptp_clock)), @@ -802,12 +886,31 @@ static const struct ethernet_api api_funcs = { #define NXP_ENET_NODE_HAS_MAC_ADDR_CHECK(n) \ BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \ DT_INST_PROP(n, zephyr_random_mac_address) || \ - DT_INST_PROP(n, nxp_unique_mac), \ + DT_INST_PROP(n, nxp_unique_mac) || \ + DT_INST_PROP(n, nxp_fused_mac), \ "MAC address not specified on ENET DT node"); +#define NXP_ENET_NODE_PHY_MODE_CHECK(n) \ +BUILD_ASSERT(NXP_ENET_PHY_MODE(DT_DRV_INST(n)) != NXP_ENET_RGMII_MODE || \ + (IS_ENABLED(CONFIG_ETH_NXP_ENET_1G) && \ + DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), nxp_enet1g)), \ + "RGMII mode requires nxp,enet1g compatible on ENET DT node" \ + " and CONFIG_ETH_NXP_ENET_1G enabled"); + +#define NXP_ENET_MAC_ADDR_SOURCE(n) \ + COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), local_mac_address), \ + (MAC_ADDR_SOURCE_LOCAL), \ + (COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address), \ + (MAC_ADDR_SOURCE_RANDOM), \ + (COND_CODE_1(DT_INST_PROP(n, nxp_unique_mac), (MAC_ADDR_SOURCE_UNIQUE), \ + (COND_CODE_1(DT_INST_PROP(n, nxp_fused_mac), (MAC_ADDR_SOURCE_FUSED), \ + (MAC_ADDR_SOURCE_INVALID)))))))) + #define NXP_ENET_MAC_INIT(n) \ NXP_ENET_NODE_HAS_MAC_ADDR_CHECK(n) \ \ + NXP_ENET_NODE_PHY_MODE_CHECK(n) \ + \ PINCTRL_DT_INST_DEFINE(n); \ \ NXP_ENET_FRAMEINFO_ARRAY(n) \ @@ -862,9 +965,7 @@ static const struct ethernet_api api_funcs = { .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \ .mdio = DEVICE_DT_GET(DT_INST_PHANDLE(n, nxp_mdio)), \ NXP_ENET_PTP_DEV(n) \ - .generate_mac = DT_INST_PROP(n, \ - zephyr_random_mac_address), \ - .unique_mac = DT_INST_PROP(n, nxp_unique_mac), \ + .mac_addr_source = NXP_ENET_MAC_ADDR_SOURCE(n), \ }; \ \ static _nxp_enet_driver_buffer_section uint8_t \ @@ -889,12 +990,9 @@ static const struct ethernet_api api_funcs = { DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_MAC_INIT) -#undef DT_DRV_COMPAT -#define DT_DRV_COMPAT nxp_enet - -#define NXP_ENET_INIT(n) \ +#define NXP_ENET_INIT(n, compat) \ \ -int nxp_enet_##n##_init(void) \ +int compat##_##n##_init(void) \ { \ clock_control_on(DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ (void *)DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name)); \ @@ -905,6 +1003,14 @@ int nxp_enet_##n##_init(void) \ } \ \ /* Init the module before any of the MAC, MDIO, or PTP clock */ \ - SYS_INIT(nxp_enet_##n##_init, POST_KERNEL, 0); + SYS_INIT(compat##_##n##_init, POST_KERNEL, 0); + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_enet + +DT_INST_FOREACH_STATUS_OKAY_VARGS(NXP_ENET_INIT, DT_DRV_COMPAT) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_enet1g -DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_INIT) +DT_INST_FOREACH_STATUS_OKAY_VARGS(NXP_ENET_INIT, DT_DRV_COMPAT) diff --git a/drivers/ethernet/phy/CMakeLists.txt b/drivers/ethernet/phy/CMakeLists.txt index ff25a9a4fa39c2..65f9cd2e5938fd 100644 --- a/drivers/ethernet/phy/CMakeLists.txt +++ b/drivers/ethernet/phy/CMakeLists.txt @@ -4,3 +4,4 @@ zephyr_library_sources_ifdef(CONFIG_PHY_GENERIC_MII phy_mii.c) zephyr_library_sources_ifdef(CONFIG_PHY_ADIN2111 phy_adin2111.c) zephyr_library_sources_ifdef(CONFIG_PHY_TJA1103 phy_tja1103.c) zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_KSZ8081 phy_microchip_ksz8081.c) +zephyr_library_sources_ifdef(CONFIG_PHY_REALTEK_RTL8211F phy_realtek_rtl8211f.c) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 8ff32b8fee2a7b..9fb71571e0f022 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -41,13 +41,23 @@ config PHY_ADIN2111 Enable ADIN2111 PHY driver. config PHY_MICROCHIP_KSZ8081 - bool "Microchip KSZ8081 Phy Driver" + bool "Microchip KSZ8081 PHY Driver" default y depends on DT_HAS_MICROCHIP_KSZ8081_ENABLED depends on MDIO depends on GPIO help - Enable Microchip KSZ8081 Ethernet Phy Driver + Enable Microchip KSZ8081 Ethernet PHY Driver + +config PHY_REALTEK_RTL8211F + bool "Realtek RTL8211F PHY Driver" + default y + depends on DT_HAS_REALTEK_RTL8211F_ENABLED + depends on MDIO + depends on GPIO || (!$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),reset-gpios) && \ + !$(dt_compat_any_has_prop,$(DT_COMPAT_REALTEK_RTL8211F),int-gpios)) + help + Enable Realtek RTL8211F Ethernet PHY Driver config PHY_AUTONEG_TIMEOUT_MS int "Auto-negotiation timeout value in milliseconds" diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 5eaf269f2b7718..7ad4e0ec8e29e3 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -42,10 +42,10 @@ struct mc_ksz8081_config { uint8_t addr; const struct device *mdio_dev; enum ksz8081_interface phy_iface; -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) const struct gpio_dt_spec reset_gpio; #endif -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_interrupt_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) const struct gpio_dt_spec interrupt_gpio; #endif }; @@ -265,9 +265,9 @@ static int phy_mc_ksz8081_static_cfg(const struct device *dev) static int phy_mc_ksz8081_reset(const struct device *dev) { -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) const struct mc_ksz8081_config *config = dev->config; -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) */ +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ struct mc_ksz8081_data *data = dev->data; int ret; @@ -278,7 +278,7 @@ static int phy_mc_ksz8081_reset(const struct device *dev) return ret; } -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) if (!config->reset_gpio.port) { goto skip_reset_gpio; } @@ -296,7 +296,7 @@ static int phy_mc_ksz8081_reset(const struct device *dev) ret = gpio_pin_set_dt(&config->reset_gpio, 1); goto done; skip_reset_gpio: -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) */ +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ ret = phy_mc_ksz8081_write(dev, MII_BMCR, MII_BMCR_RESET); if (ret) { goto done; @@ -465,7 +465,7 @@ static int phy_mc_ksz8081_init(const struct device *dev) mdio_bus_enable(config->mdio_dev); -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_interrupt_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) if (!config->interrupt_gpio.port) { goto skip_int_gpio; } @@ -477,16 +477,16 @@ static int phy_mc_ksz8081_init(const struct device *dev) } skip_int_gpio: -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_interrupt_gpio) */ +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) if (config->reset_gpio.port) { ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); if (ret) { return ret; } } -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) */ +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ /* Reset PHY */ ret = phy_mc_ksz8081_reset(dev); @@ -508,16 +508,16 @@ static const struct ethphy_driver_api mc_ksz8081_phy_api = { .write = phy_mc_ksz8081_write, }; -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_reset_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) #define RESET_GPIO(n) \ - .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, mc_reset_gpio, {0}), + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), #else #define RESET_GPIO(n) #endif /* reset gpio */ -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(mc_interrupt_gpio) +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) #define INTERRUPT_GPIO(n) \ - .interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, mc_interrupt_gpio, {0}), + .interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}), #else #define INTERRUPT_GPIO(n) #endif /* interrupt gpio */ @@ -526,7 +526,7 @@ static const struct ethphy_driver_api mc_ksz8081_phy_api = { static const struct mc_ksz8081_config mc_ksz8081_##n##_config = { \ .addr = DT_INST_REG_ADDR(n), \ .mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .phy_iface = DT_INST_ENUM_IDX(n, mc_interface_type), \ + .phy_iface = DT_INST_ENUM_IDX(n, microchip_interface_type), \ RESET_GPIO(n) \ INTERRUPT_GPIO(n) \ }; \ diff --git a/drivers/ethernet/phy/phy_realtek_rtl8211f.c b/drivers/ethernet/phy/phy_realtek_rtl8211f.c new file mode 100644 index 00000000000000..b1765a500bc5ac --- /dev/null +++ b/drivers/ethernet/phy/phy_realtek_rtl8211f.c @@ -0,0 +1,634 @@ +/* + * Copyright 2023-2024 NXP + * + * Inspiration from phy_mii.c, which is: + * Copyright (c) 2021 IP-Logix Inc. + * Copyright 2022 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT realtek_rtl8211f + +#include +#include +#include +#include +#include +#include +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) || DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) +#include +#endif + +#define LOG_MODULE_NAME phy_rt_rtl8211f +#define LOG_LEVEL CONFIG_PHY_LOG_LEVEL +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#define REALTEK_OUI_MSB (0x1CU) + +#define PHY_RT_RTL8211F_PHYSR_REG (0x1A) + +#define PHY_RT_RTL8211F_PHYSR_LINKSTATUS_MASK BIT(2) +#define PHY_RT_RTL8211F_PHYSR_LINKDUPLEX_MASK BIT(3) +#define PHY_RT_RTL8211F_PHYSR_LINKSPEED_MASK (BIT(4) | BIT(5)) +#define PHY_RT_RTL8211F_PHYSR_LINKSPEED_SHIFT (4U) +#define PHY_RT_RTL8211F_PHYSR_LINKSPEED_10M (0U) +#define PHY_RT_RTL8211F_PHYSR_LINKSPEED_100M (1U) +#define PHY_RT_RTL8211F_PHYSR_LINKSPEED_1000M (2U) + +#define PHY_RT_RTL8211F_PAGSR_REG (0x1F) + +#define PHY_RT_RTL8211F_PAGE_INTR_PIN_ADDR (0xD40) +#define PHY_RT_RTL8211F_INTR_PIN_REG (0x16) +#define PHY_RT_RTL8211F_INTR_PIN_MASK BIT(5) + +#define PHY_RT_RTL8211F_PAGE_INTR_ADDR (0xA42U) +#define PHY_RT_RTL8211F_INER_REG (0x12U) +#define PHY_RT_RTL8211F_INER_LINKSTATUS_CHANGE_MASK BIT(4) +#define PHY_RT_RTL8211F_INSR_REG (0x1DU) + +#define PHY_RT_RTL8211F_RESET_HOLD_TIME_MS 10 + +struct rt_rtl8211f_config { + uint8_t addr; + const struct device *mdio_dev; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + const struct gpio_dt_spec reset_gpio; +#endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + const struct gpio_dt_spec interrupt_gpio; +#endif +}; + +struct rt_rtl8211f_data { + const struct device *dev; + struct phy_link_state state; + phy_callback_t cb; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + struct gpio_callback gpio_callback; +#endif + void *cb_data; + struct k_mutex mutex; + struct k_work_delayable phy_monitor_work; +}; + +static int phy_rt_rtl8211f_read(const struct device *dev, + uint16_t reg_addr, uint32_t *data) +{ + const struct rt_rtl8211f_config *config = dev->config; + int ret; + + /* Make sure excessive bits 16-31 are reset */ + *data = 0U; + + /* Read the PHY register */ + ret = mdio_read(config->mdio_dev, config->addr, reg_addr, (uint16_t *)data); + if (ret) { + return ret; + } + + return 0; +} + +static int phy_rt_rtl8211f_write(const struct device *dev, + uint16_t reg_addr, uint32_t data) +{ + const struct rt_rtl8211f_config *config = dev->config; + int ret; + + ret = mdio_write(config->mdio_dev, config->addr, reg_addr, (uint16_t)data); + if (ret) { + return ret; + } + + return 0; +} + +static int phy_rt_rtl8211f_reset(const struct device *dev) +{ + const struct rt_rtl8211f_config *config = dev->config; + uint32_t reg_val; + int ret; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + if (config->reset_gpio.port) { + /* Start reset */ + ret = gpio_pin_set_dt(&config->reset_gpio, 0); + if (ret) { + return ret; + } + + /* Hold reset for the minimum time specified by datasheet */ + k_busy_wait(USEC_PER_MSEC * PHY_RT_RTL8211F_RESET_HOLD_TIME_MS); + + /* Reset over */ + ret = gpio_pin_set_dt(&config->reset_gpio, 1); + if (ret) { + return ret; + } + + /* Wait another 30 ms (circuits settling time) before accessing registers */ + k_busy_wait(USEC_PER_MSEC * 30); + + goto finalize_reset; + } +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + + /* Reset PHY using register */ + ret = phy_rt_rtl8211f_write(dev, MII_BMCR, MII_BMCR_RESET); + if (ret) { + LOG_ERR("Error writing phy (%d) basic control register", config->addr); + return ret; + } + + /* Wait for the minimum reset time specified by datasheet */ + k_busy_wait(USEC_PER_MSEC * PHY_RT_RTL8211F_RESET_HOLD_TIME_MS); + + /* Wait for the reset to be cleared */ + do { + ret = phy_rt_rtl8211f_read(dev, MII_BMCR, ®_val); + if (ret) { + LOG_ERR("Error reading phy (%d) basic control register", config->addr); + return ret; + } + } while (reg_val & MII_BMCR_RESET); + + goto finalize_reset; + +finalize_reset: + /* Wait until correct data can be read from registers */ + do { + ret = phy_rt_rtl8211f_read(dev, MII_PHYID1R, ®_val); + if (ret) { + LOG_ERR("Error reading phy (%d) identifier register 1", config->addr); + return ret; + } + } while (reg_val != REALTEK_OUI_MSB); + + return 0; +} + +static int phy_rt_rtl8211f_restart_autonegotiation(const struct device *dev) +{ + const struct rt_rtl8211f_config *config = dev->config; + uint32_t bmcr = 0; + int ret; + + /* Read control register to write back with autonegotiation bit */ + ret = phy_rt_rtl8211f_read(dev, MII_BMCR, &bmcr); + if (ret) { + LOG_ERR("Error reading phy (%d) basic control register", config->addr); + return ret; + } + + /* (re)start autonegotiation */ + LOG_DBG("PHY (%d) is entering autonegotiation sequence", config->addr); + bmcr |= MII_BMCR_AUTONEG_ENABLE | MII_BMCR_AUTONEG_RESTART; + + ret = phy_rt_rtl8211f_write(dev, MII_BMCR, bmcr); + if (ret) { + LOG_ERR("Error writing phy (%d) basic control register", config->addr); + return ret; + } + + return 0; +} + +static int phy_rt_rtl8211f_get_link(const struct device *dev, + struct phy_link_state *state) +{ + const struct rt_rtl8211f_config *config = dev->config; + struct rt_rtl8211f_data *data = dev->data; + int ret; + uint32_t physr = 0; + uint32_t duplex = 0; + struct phy_link_state old_state = data->state; + struct phy_link_state new_state = {}; + + /* Lock mutex */ + ret = k_mutex_lock(&data->mutex, K_FOREVER); + if (ret) { + LOG_ERR("PHY mutex lock error"); + return ret; + } + + /* Read PHY specific status register */ + ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_PHYSR_REG, &physr); + if (ret) { + LOG_ERR("Error reading phy (%d) specific status register", config->addr); + (void)k_mutex_unlock(&data->mutex); + return ret; + } + + /* Unlock mutex */ + (void)k_mutex_unlock(&data->mutex); + + new_state.is_up = physr & PHY_RT_RTL8211F_PHYSR_LINKSTATUS_MASK; + + if (!new_state.is_up) { + goto result; + } + + duplex = (physr & PHY_RT_RTL8211F_PHYSR_LINKDUPLEX_MASK); + switch ((physr & PHY_RT_RTL8211F_PHYSR_LINKSPEED_MASK) + >> PHY_RT_RTL8211F_PHYSR_LINKSPEED_SHIFT) { + case PHY_RT_RTL8211F_PHYSR_LINKSPEED_100M: + if (duplex) { + new_state.speed = LINK_FULL_100BASE_T; + } else { + new_state.speed = LINK_HALF_100BASE_T; + } + break; + case PHY_RT_RTL8211F_PHYSR_LINKSPEED_1000M: + if (duplex) { + new_state.speed = LINK_FULL_1000BASE_T; + } else { + new_state.speed = LINK_HALF_1000BASE_T; + } + break; + case PHY_RT_RTL8211F_PHYSR_LINKSPEED_10M: + default: + if (duplex) { + new_state.speed = LINK_FULL_10BASE_T; + } else { + new_state.speed = LINK_HALF_10BASE_T; + } + break; + } +result: + if (memcmp(&old_state, &new_state, sizeof(struct phy_link_state)) != 0) { + LOG_INF("PHY %d is %s", config->addr, new_state.is_up ? "up" : "down"); + if (new_state.is_up) { + LOG_INF("PHY (%d) Link speed %s Mb, %s duplex", config->addr, + (PHY_LINK_IS_SPEED_1000M(new_state.speed) ? "1000" : + (PHY_LINK_IS_SPEED_100M(new_state.speed) ? "100" : "10")), + PHY_LINK_IS_FULL_DUPLEX(new_state.speed) ? "full" : "half"); + } + } + + memcpy(state, &new_state, sizeof(struct phy_link_state)); + + return ret; +} + +static int phy_rt_rtl8211f_cfg_link(const struct device *dev, + enum phy_link_speed speeds) +{ + const struct rt_rtl8211f_config *config = dev->config; + struct rt_rtl8211f_data *data = dev->data; + uint32_t anar; + uint32_t gbcr; + int ret; + + /* Lock mutex */ + ret = k_mutex_lock(&data->mutex, K_FOREVER); + if (ret) { + LOG_ERR("PHY mutex lock error"); + return ret; + } + + /* We are going to reconfigure the phy, don't need to monitor until done */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + if (!config->interrupt_gpio.port) { + k_work_cancel_delayable(&data->phy_monitor_work); + } +#else + k_work_cancel_delayable(&data->phy_monitor_work); +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + + /* Read ANAR register to write back */ + ret = phy_rt_rtl8211f_read(dev, MII_ANAR, &anar); + if (ret) { + LOG_ERR("Error reading phy (%d) advertising register", config->addr); + goto done; + } + + /* Read GBCR register to write back */ + ret = phy_rt_rtl8211f_read(dev, MII_1KTCR, &gbcr); + if (ret) { + LOG_ERR("Error reading phy (%d) 1000Base-T control register", config->addr); + goto done; + } + + /* Setup advertising register */ + if (speeds & LINK_FULL_100BASE_T) { + anar |= MII_ADVERTISE_100_FULL; + } else { + anar &= ~MII_ADVERTISE_100_FULL; + } + if (speeds & LINK_HALF_100BASE_T) { + anar |= MII_ADVERTISE_100_HALF; + } else { + anar &= ~MII_ADVERTISE_100_HALF; + } + if (speeds & LINK_FULL_10BASE_T) { + anar |= MII_ADVERTISE_10_FULL; + } else { + anar &= ~MII_ADVERTISE_10_FULL; + } + if (speeds & LINK_HALF_10BASE_T) { + anar |= MII_ADVERTISE_10_HALF; + } else { + anar &= ~MII_ADVERTISE_10_HALF; + } + + /* Setup 1000Base-T control register */ + if (speeds & LINK_FULL_1000BASE_T) { + gbcr |= MII_ADVERTISE_1000_FULL; + } else { + gbcr &= ~MII_ADVERTISE_1000_FULL; + } + + /* Write capabilities to advertising register */ + ret = phy_rt_rtl8211f_write(dev, MII_ANAR, anar); + if (ret) { + LOG_ERR("Error writing phy (%d) advertising register", config->addr); + goto done; + } + + /* Write capabilities to 1000Base-T control register */ + ret = phy_rt_rtl8211f_write(dev, MII_1KTCR, gbcr); + if (ret) { + LOG_ERR("Error writing phy (%d) 1000Base-T control register", config->addr); + goto done; + } + + /* (Re)start autonegotiation */ + ret = phy_rt_rtl8211f_restart_autonegotiation(dev); + if (ret) { + LOG_ERR("Error restarting autonegotiation"); + goto done; + } +done: + /* Unlock mutex */ + (void)k_mutex_unlock(&data->mutex); + + /* Start monitoring */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + if (!config->interrupt_gpio.port) { + k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); + } +#else + k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + + return ret; +} + +static int phy_rt_rtl8211f_link_cb_set(const struct device *dev, + phy_callback_t cb, void *user_data) +{ + struct rt_rtl8211f_data *data = dev->data; + + data->cb = cb; + data->cb_data = user_data; + + phy_rt_rtl8211f_get_link(dev, &data->state); + + data->cb(dev, &data->state, data->cb_data); + + return 0; +} + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) +static int phy_rt_rtl8211f_clear_interrupt(struct rt_rtl8211f_data *data) +{ + const struct device *dev = data->dev; + const struct rt_rtl8211f_config *config = dev->config; + uint32_t reg_val; + int ret; + + /* Lock mutex */ + ret = k_mutex_lock(&data->mutex, K_FOREVER); + if (ret) { + LOG_ERR("PHY mutex lock error"); + return ret; + } + + /* Read/clear PHY interrupt status register */ + ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INSR_REG, ®_val); + if (ret) { + LOG_ERR("Error reading phy (%d) interrupt status register", config->addr); + } + + /* Unlock mutex */ + (void)k_mutex_unlock(&data->mutex); + + return ret; +} + +static void phy_rt_rtl8211f_interrupt_handler(const struct device *port, + struct gpio_callback *cb, + gpio_port_pins_t pins) +{ + struct rt_rtl8211f_data *data = CONTAINER_OF(cb, struct rt_rtl8211f_data, gpio_callback); + int ret; + + ret = k_work_reschedule(&data->phy_monitor_work, K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to schedule phy_monitor_work from ISR"); + } +} +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + +static void phy_rt_rtl8211f_monitor_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct rt_rtl8211f_data *data = + CONTAINER_OF(dwork, struct rt_rtl8211f_data, phy_monitor_work); + const struct device *dev = data->dev; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + const struct rt_rtl8211f_config *config = dev->config; +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + struct phy_link_state state = {}; + int ret; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + if (config->interrupt_gpio.port) { + ret = phy_rt_rtl8211f_clear_interrupt(data); + if (ret) { + return; + } + } +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + + ret = phy_rt_rtl8211f_get_link(dev, &state); + + if (ret == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) { + memcpy(&data->state, &state, sizeof(struct phy_link_state)); + if (data->cb) { + data->cb(dev, &data->state, data->cb_data); + } + } + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + if (!config->interrupt_gpio.port) { + k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); + } +#else + k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ +} + +static int phy_rt_rtl8211f_init(const struct device *dev) +{ + const struct rt_rtl8211f_config *config = dev->config; + struct rt_rtl8211f_data *data = dev->data; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + uint32_t reg_val; +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + int ret; + + data->dev = dev; + + ret = k_mutex_init(&data->mutex); + if (ret) { + return ret; + } + + mdio_bus_enable(config->mdio_dev); + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + /* Configure reset pin */ + if (config->reset_gpio.port) { + ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); + if (ret) { + return ret; + } + } +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + + /* Reset PHY */ + ret = phy_rt_rtl8211f_reset(dev); + if (ret) { + LOG_ERR("Failed to reset phy (%d)", config->addr); + return ret; + } + + k_work_init_delayable(&data->phy_monitor_work, phy_rt_rtl8211f_monitor_work_handler); + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + if (!config->interrupt_gpio.port) { + goto skip_int_gpio; + } + + /* Set INTB/PMEB pin to interrupt mode */ + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, + PHY_RT_RTL8211F_PAGE_INTR_PIN_ADDR); + if (ret) { + LOG_ERR("Error writing phy (%d) page select register", config->addr); + return ret; + } + ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INTR_PIN_REG, ®_val); + if (!ret) { + reg_val &= ~PHY_RT_RTL8211F_INTR_PIN_MASK; + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_INTR_PIN_REG, reg_val); + if (ret) { + LOG_ERR("Error writing phy (%d) interrupt pin setting register", + config->addr); + return ret; + } + } else { + LOG_ERR("Error reading phy (%d) interrupt pin setting register", config->addr); + return ret; + } + /* Restore to default page 0 */ + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, 0); + if (ret) { + LOG_ERR("Error writing phy (%d) page select register", config->addr); + return ret; + } + + /* Clear interrupt */ + ret = phy_rt_rtl8211f_clear_interrupt(data); + if (ret) { + return ret; + } + + /* Configure interrupt pin */ + ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_INPUT); + if (ret) { + return ret; + } + + gpio_init_callback(&data->gpio_callback, phy_rt_rtl8211f_interrupt_handler, + BIT(config->interrupt_gpio.pin)); + ret = gpio_add_callback_dt(&config->interrupt_gpio, &data->gpio_callback); + if (ret) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret) { + return ret; + } + + /* Enable PHY interrupt. */ + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, + PHY_RT_RTL8211F_PAGE_INTR_ADDR); + if (ret) { + LOG_ERR("Error writing phy (%d) page select register", config->addr); + return ret; + } + ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INER_REG, ®_val); + if (ret) { + LOG_ERR("Error reading phy (%d) interrupt enable register", config->addr); + return ret; + } + reg_val |= PHY_RT_RTL8211F_INER_LINKSTATUS_CHANGE_MASK; + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_INER_REG, reg_val); + if (ret) { + LOG_ERR("Error writing phy (%d) interrupt enable register", config->addr); + return ret; + } + /* Restore to default page 0 */ + ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, 0); + if (ret) { + LOG_ERR("Error writing phy (%d) page select register", config->addr); + return ret; + } +skip_int_gpio: +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + + return 0; +} + +static const struct ethphy_driver_api rt_rtl8211f_phy_api = { + .get_link = phy_rt_rtl8211f_get_link, + .cfg_link = phy_rt_rtl8211f_cfg_link, + .link_cb_set = phy_rt_rtl8211f_link_cb_set, + .read = phy_rt_rtl8211f_read, + .write = phy_rt_rtl8211f_write, +}; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define RESET_GPIO(n) \ + .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), +#else +#define RESET_GPIO(n) +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) +#define INTERRUPT_GPIO(n) \ + .interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}), +#else +#define INTERRUPT_GPIO(n) +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */ + +#define REALTEK_RTL8211F_INIT(n) \ + static const struct rt_rtl8211f_config rt_rtl8211f_##n##_config = { \ + .addr = DT_INST_REG_ADDR(n), \ + .mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + RESET_GPIO(n) \ + INTERRUPT_GPIO(n) \ + }; \ + \ + static struct rt_rtl8211f_data rt_rtl8211f_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, &phy_rt_rtl8211f_init, NULL, \ + &rt_rtl8211f_##n##_data, &rt_rtl8211f_##n##_config, \ + POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ + &rt_rtl8211f_phy_api); + +DT_INST_FOREACH_STATUS_OKAY(REALTEK_RTL8211F_INIT) diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 54b9178c091831..744a6a5862c855 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -1,5 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_library_sources(flash_util.c) + zephyr_syscall_header_ifdef( CONFIG_FLASH_SIMULATOR ${ZEPHYR_BASE}/include/zephyr/drivers/flash/flash_simulator.h diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 441a79868786f5..4816db0b580f53 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -17,6 +17,56 @@ config FLASH_HAS_EX_OP This option is selected by drivers that support flash extended operations. +config FLASH_HAS_EXPLICIT_ERASE + bool + help + Device has does not do erase-on-write (erase-on-program, auto-erase + on write) and requires explicit erase procedure to be programmed + with random value, in place where it has already been programmed with + some other value, as program can only change bits from erased-value + to the opposite. + All pure Flash devices are evolution of EEPROM where erase has + been separated from write, EEPROM has erase-on-write, giving + it advantage of higher write speeds at a cost of larger erase block. + Note that explicit-erase capability does not warrants that + write without erase is not allowed, taking the above restrictions, + it only states that write of a random information will require + erase. + Erase is usually performed in pages, as we have chosen to name + the unit in Zephyr, that may have different naming in device + specifications, like pages, sectors or blocks, and may vary + in size, depending how they are named by vendor. + This option should be selected by drivers that serve devices with + such characteristic and is used and may be used by users to provide + paths in code that only serve such devices, and could be + optimized-out by compiler in case where there is no such device in + a system. + +config FLASH_HAS_NO_EXPLICIT_ERASE + bool + help + Device does not require explicit erase before programming + a new random value at any location that has been previously + programmed with some other value. + Note that the device may have erase-on-write (auto-erase), + as for example in EEPROM devices, but may also have no erase + at all. + A device driver may still provide erase callback, + especially if it is able to perform erase to accelerate + further writes or is able to fill the area requested for + erase, with single value, faster than consecutive writes + that would be used to emulate erase. + This option should be selected by drivers that serve + devices with such characteristic and is used and may be + used by users to provide paths in code that only serve + such devices, and could be optimized-out by compiler in + case where there is no such device in a system. + This option should be selected for any device that + can change storage bits, by write, from any value to opposite + value at any time. + When your driver sets this option you also need to set + no_explicit_erase capability in your drivers flash_parameters. + config FLASH_HAS_PAGE_LAYOUT bool help @@ -77,13 +127,30 @@ config FLASH_SHELL_BUFFER_SIZE endif # FLASH_SHELL +config FLASH_FILL_BUFFER_SIZE + int "Buffer size of flash_fill funciton" + default 32 + help + Size of a buffer used by flash_fill function to fill a device with + specific value; this buffer is allocated on stack. + The buffer is needed as most devices have write-block alignment + requirements that which imposes minimal size of data, which can + be written to a device, and alignment of write offset. + Even if device does not have such requirement, filling device by + single bytes is not efficient. + Value selected here should be multiply of the largest write-block-size + among all the memory devices used in system. + +if FLASH_HAS_PAGE_LAYOUT + config FLASH_PAGE_LAYOUT bool "API for retrieving the layout of pages" - depends on FLASH_HAS_PAGE_LAYOUT - default y + default FLASH_HAS_PAGE_LAYOUT help Enables API for retrieving the layout of flash memory pages. +endif + config FLASH_EX_OP_ENABLED bool "API for extended flash operations" depends on FLASH_HAS_EX_OP diff --git a/drivers/flash/Kconfig.ambiq b/drivers/flash/Kconfig.ambiq index 5ce028bba9664d..da0df1fcdab738 100644 --- a/drivers/flash/Kconfig.ambiq +++ b/drivers/flash/Kconfig.ambiq @@ -8,6 +8,8 @@ config FLASH_AMBIQ select AMBIQ_HAL select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_NO_EXPLICIT_ERASE if SOC_SERIES_APOLLO4X + select FLASH_HAS_EXPLICIT_ERASE if SOC_SERIES_APOLLO3X help Enables Ambiq flash driver on MRAM (e.g. Apollo4x) or flash (e.g. Apollo3x). diff --git a/drivers/flash/Kconfig.andes b/drivers/flash/Kconfig.andes index d639cf20467e61..0a1a563519533e 100644 --- a/drivers/flash/Kconfig.andes +++ b/drivers/flash/Kconfig.andes @@ -12,6 +12,7 @@ menuconfig FLASH_ANDES_QSPI select FLASH_HAS_PAGE_LAYOUT select FLASH_JESD216 select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE depends on !SPI_NOR help Enable driver for Andes QSPI diff --git a/drivers/flash/Kconfig.at45 b/drivers/flash/Kconfig.at45 index c1c892e33fd80d..bf5c0add72c7dd 100644 --- a/drivers/flash/Kconfig.at45 +++ b/drivers/flash/Kconfig.at45 @@ -7,6 +7,7 @@ menuconfig SPI_FLASH_AT45 depends on DT_HAS_ATMEL_AT45_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select SPI help This driver can handle several instances of AT45 family chips that diff --git a/drivers/flash/Kconfig.b91 b/drivers/flash/Kconfig.b91 index 46a8b10e804bf3..a3f35da8581f3b 100644 --- a/drivers/flash/Kconfig.b91 +++ b/drivers/flash/Kconfig.b91 @@ -7,5 +7,6 @@ config SOC_FLASH_TELINK_B91 depends on DT_HAS_TELINK_B91_FLASH_CONTROLLER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enables Telink B91 flash driver. diff --git a/drivers/flash/Kconfig.cadence_nand b/drivers/flash/Kconfig.cadence_nand index 52b7a1422b109a..436592aa2d8ef7 100644 --- a/drivers/flash/Kconfig.cadence_nand +++ b/drivers/flash/Kconfig.cadence_nand @@ -10,6 +10,7 @@ config FLASH_CDNS_NAND depends on DT_HAS_CDNS_NAND_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enable Cadence NAND support. diff --git a/drivers/flash/Kconfig.cadence_qspi_nor b/drivers/flash/Kconfig.cadence_qspi_nor index 0bc9a33402c653..4209b256cfdb93 100644 --- a/drivers/flash/Kconfig.cadence_qspi_nor +++ b/drivers/flash/Kconfig.cadence_qspi_nor @@ -7,6 +7,7 @@ config FLASH_CAD_QSPI_NOR depends on DT_HAS_CDNS_QSPI_NOR_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enable Cadence QSPI-NOR support. diff --git a/drivers/flash/Kconfig.cc13xx_cc26xx b/drivers/flash/Kconfig.cc13xx_cc26xx index 3abc4fc2d7d34e..e691dddb4727a6 100644 --- a/drivers/flash/Kconfig.cc13xx_cc26xx +++ b/drivers/flash/Kconfig.cc13xx_cc26xx @@ -7,6 +7,7 @@ config SOC_FLASH_CC13XX_CC26XX depends on DT_HAS_TI_CC13XX_CC26XX_FLASH_CONTROLLER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enables TI SimpleLink CC13xx/CC26xx flash controller driver. diff --git a/drivers/flash/Kconfig.esp32 b/drivers/flash/Kconfig.esp32 index 3d5790d4a2f52c..4da80bce0c0fdd 100644 --- a/drivers/flash/Kconfig.esp32 +++ b/drivers/flash/Kconfig.esp32 @@ -7,6 +7,7 @@ config SOC_FLASH_ESP32 depends on DT_HAS_ESPRESSIF_ESP32_FLASH_CONTROLLER_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE help Enable ESP32 internal flash driver. diff --git a/drivers/flash/Kconfig.gd32 b/drivers/flash/Kconfig.gd32 index c3c86bf35795ae..c4d8921a6aad03 100644 --- a/drivers/flash/Kconfig.gd32 +++ b/drivers/flash/Kconfig.gd32 @@ -7,6 +7,7 @@ config SOC_FLASH_GD32 depends on (GD32_NV_FLASH_V1 || GD32_NV_FLASH_V2 || GD32_NV_FLASH_V3) select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable the GigaDevice GD32 flash driver. diff --git a/drivers/flash/Kconfig.gecko b/drivers/flash/Kconfig.gecko index 903b08373b32e9..fc5478eae2698c 100644 --- a/drivers/flash/Kconfig.gecko +++ b/drivers/flash/Kconfig.gecko @@ -10,6 +10,7 @@ config SOC_FLASH_GECKO select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT select SOC_GECKO_MSC + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable Silicon Labs Gecko series internal flash driver. diff --git a/drivers/flash/Kconfig.ifx_cat1 b/drivers/flash/Kconfig.ifx_cat1 index f8871d4d1e30d7..4964258c4ec20d 100644 --- a/drivers/flash/Kconfig.ifx_cat1 +++ b/drivers/flash/Kconfig.ifx_cat1 @@ -12,6 +12,7 @@ config FLASH_INFINEON_CAT1 select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED select USE_INFINEON_FLASH + select FLASH_HAS_EXPLICIT_ERASE help Enable the Flash driver for Infineon CAT1 family. diff --git a/drivers/flash/Kconfig.it8xxx2 b/drivers/flash/Kconfig.it8xxx2 index 50b881335a4fed..ef0307f65a39e8 100644 --- a/drivers/flash/Kconfig.it8xxx2 +++ b/drivers/flash/Kconfig.it8xxx2 @@ -10,6 +10,7 @@ config SOC_FLASH_ITE_IT8XXX2 select SOC_IT8XXX2_USE_ILM select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select HAS_FLASH_LOAD_OFFSET help The flash driver includes support for read, write and diff --git a/drivers/flash/Kconfig.lpc b/drivers/flash/Kconfig.lpc index 379a4cdaadc70b..4d1fd1940e0f1d 100644 --- a/drivers/flash/Kconfig.lpc +++ b/drivers/flash/Kconfig.lpc @@ -8,6 +8,7 @@ config SOC_FLASH_LPC DT_HAS_NXP_IAP_FMC54_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enables the LPC IAP flash shim driver. WARNING: This driver will disable the system interrupts for diff --git a/drivers/flash/Kconfig.mcux b/drivers/flash/Kconfig.mcux index 2cf9eac494d282..7b3df8361076bc 100644 --- a/drivers/flash/Kconfig.mcux +++ b/drivers/flash/Kconfig.mcux @@ -11,6 +11,7 @@ config SOC_FLASH_MCUX DT_HAS_NXP_IAP_MSF1_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enables the MCUX flash shim driver. @@ -41,6 +42,7 @@ config FLASH_MCUX_FLEXSPI_NOR depends on DT_HAS_NXP_IMX_FLEXSPI_NOR_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select FLASH_JESD216 select MEMC select MEMC_MCUX_FLEXSPI @@ -51,6 +53,7 @@ config FLASH_MCUX_FLEXSPI_MX25UM51345G depends on DT_HAS_NXP_IMX_FLEXSPI_MX25UM51345G_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MEMC select MEMC_MCUX_FLEXSPI @@ -60,6 +63,7 @@ config FLASH_MCUX_FLEXSPI_HYPERFLASH depends on DT_HAS_NXP_IMX_FLEXSPI_HYPERFLASH_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MEMC select MEMC_MCUX_FLEXSPI diff --git a/drivers/flash/Kconfig.nios2_qspi b/drivers/flash/Kconfig.nios2_qspi index bcad6d9e50dd1e..ab834b5b956354 100644 --- a/drivers/flash/Kconfig.nios2_qspi +++ b/drivers/flash/Kconfig.nios2_qspi @@ -6,5 +6,6 @@ config SOC_FLASH_NIOS2_QSPI depends on HAS_ALTERA_HAL depends on DT_HAS_ALTR_NIOS2_QSPI_NOR_ENABLED select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enables the Nios-II QSPI flash driver. diff --git a/drivers/flash/Kconfig.nor b/drivers/flash/Kconfig.nor index 8263f7f6785da3..eed33c8e1807f9 100644 --- a/drivers/flash/Kconfig.nor +++ b/drivers/flash/Kconfig.nor @@ -1,4 +1,6 @@ # Copyright (c) 2018 Savoir-Faire Linux. +# Copyright (c) 2024 Nordic Semiconductor ASA +# # SPDX-License-Identifier: Apache-2.0 menuconfig SPI_NOR @@ -6,6 +8,7 @@ menuconfig SPI_NOR default y depends on DT_HAS_JEDEC_SPI_NOR_ENABLED select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select FLASH_HAS_PAGE_LAYOUT select FLASH_JESD216 select FLASH_HAS_EX_OP diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index 4acce55856791e..82e1e197e37534 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -7,6 +7,7 @@ menuconfig NORDIC_QSPI_NOR depends on DT_HAS_NORDIC_QSPI_NOR_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select NRFX_QSPI select FLASH_JESD216 select PINCTRL diff --git a/drivers/flash/Kconfig.npcx_fiu b/drivers/flash/Kconfig.npcx_fiu index e4ac74c9d444ea..9d464f48bb78c5 100644 --- a/drivers/flash/Kconfig.npcx_fiu +++ b/drivers/flash/Kconfig.npcx_fiu @@ -18,6 +18,7 @@ config FLASH_NPCX_FIU_NOR depends on FLASH_NPCX_FIU_QSPI select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select FLASH_JESD216 select FLASH_HAS_EX_OP help diff --git a/drivers/flash/Kconfig.nrf b/drivers/flash/Kconfig.nrf index 769ccc7a51d523..48c4e0d3fb94b5 100644 --- a/drivers/flash/Kconfig.nrf +++ b/drivers/flash/Kconfig.nrf @@ -17,6 +17,7 @@ menuconfig SOC_FLASH_NRF depends on !FLASH_NRF_FORCE_ALT select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select NRFX_NVMC select MPU_ALLOW_FLASH_WRITE if ARM_MPU help diff --git a/drivers/flash/Kconfig.nrf_mram b/drivers/flash/Kconfig.nrf_mram index 0ef65864a622f8..be41cead07f185 100644 --- a/drivers/flash/Kconfig.nrf_mram +++ b/drivers/flash/Kconfig.nrf_mram @@ -10,6 +10,7 @@ config SOC_FLASH_NRF_MRAM depends on DT_HAS_NORDIC_MRAM_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_NO_EXPLICIT_ERASE imply MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enables Nordic Semiconductor flash driver for MRAM in direct write mode. diff --git a/drivers/flash/Kconfig.nrf_rram b/drivers/flash/Kconfig.nrf_rram index a729b57bc288db..84214f809eb430 100644 --- a/drivers/flash/Kconfig.nrf_rram +++ b/drivers/flash/Kconfig.nrf_rram @@ -11,6 +11,7 @@ menuconfig SOC_FLASH_NRF_RRAM select NRFX_RRAMC select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_NO_EXPLICIT_ERASE select FLASH_NRF_FORCE_ALT select MPU_ALLOW_FLASH_WRITE if ARM_MPU help diff --git a/drivers/flash/Kconfig.numaker b/drivers/flash/Kconfig.numaker index 98d4790589d3fe..4ab0f46271dc38 100644 --- a/drivers/flash/Kconfig.numaker +++ b/drivers/flash/Kconfig.numaker @@ -8,6 +8,7 @@ config SOC_FLASH_NUMAKER default y select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select HAS_NUMAKER_FMC depends on DT_HAS_NUVOTON_NUMAKER_FMC_ENABLED help diff --git a/drivers/flash/Kconfig.numaker_rmc b/drivers/flash/Kconfig.numaker_rmc index ae149115255f73..72fd64c4d494d8 100644 --- a/drivers/flash/Kconfig.numaker_rmc +++ b/drivers/flash/Kconfig.numaker_rmc @@ -8,6 +8,7 @@ config SOC_FLASH_NUMAKER_RMC default y select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_NO_EXPLICIT_ERASE select HAS_NUMAKER_RMC depends on DT_HAS_NUVOTON_NUMAKER_RMC_ENABLED help diff --git a/drivers/flash/Kconfig.nxp_s32 b/drivers/flash/Kconfig.nxp_s32 index 08a96f1cec9bff..47db1ab654eea4 100644 --- a/drivers/flash/Kconfig.nxp_s32 +++ b/drivers/flash/Kconfig.nxp_s32 @@ -9,6 +9,7 @@ config FLASH_NXP_S32_QSPI_NOR select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED select FLASH_JESD216 + select FLASH_HAS_EXPLICIT_ERASE help Enable the Flash driver for a NOR Serial Flash Memory device connected to an NXP S32 QSPI bus. diff --git a/drivers/flash/Kconfig.rpi_pico b/drivers/flash/Kconfig.rpi_pico index 4d7fee169417f4..b41cd843c0899e 100644 --- a/drivers/flash/Kconfig.rpi_pico +++ b/drivers/flash/Kconfig.rpi_pico @@ -8,6 +8,7 @@ config FLASH_RPI_PICO depends on DT_HAS_RASPBERRYPI_PICO_FLASH_CONTROLLER_ENABLED select FLASH_HAS_DRIVER_ENABLED select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select PICOSDK_USE_FLASH help Enable Raspberry Pi Pico flash driver. diff --git a/drivers/flash/Kconfig.rv32m1 b/drivers/flash/Kconfig.rv32m1 index 0dd7f290129181..46ada40d7c3f34 100644 --- a/drivers/flash/Kconfig.rv32m1 +++ b/drivers/flash/Kconfig.rv32m1 @@ -7,6 +7,7 @@ config SOC_FLASH_RV32M1 depends on DT_HAS_OPENISA_RV32M1_FTFE_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enables the RV32M1 flash shim driver. WARNING: This driver will disable the system interrupts for diff --git a/drivers/flash/Kconfig.sam b/drivers/flash/Kconfig.sam index bb014d65279900..1e30636390d0fc 100644 --- a/drivers/flash/Kconfig.sam +++ b/drivers/flash/Kconfig.sam @@ -9,6 +9,7 @@ config SOC_FLASH_SAM depends on DT_HAS_ATMEL_SAM_FLASH_CONTROLLER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable the Atmel SAM series internal flash driver. diff --git a/drivers/flash/Kconfig.sam0 b/drivers/flash/Kconfig.sam0 index accaa30d3039dd..f285aa868f8472 100644 --- a/drivers/flash/Kconfig.sam0 +++ b/drivers/flash/Kconfig.sam0 @@ -9,6 +9,7 @@ menuconfig SOC_FLASH_SAM0 depends on DT_HAS_ATMEL_SAM0_NVMCTRL_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable the Atmel SAM0 series internal flash driver. diff --git a/drivers/flash/Kconfig.simulator b/drivers/flash/Kconfig.simulator index e32a2a72bb0dad..fd75479b316829 100644 --- a/drivers/flash/Kconfig.simulator +++ b/drivers/flash/Kconfig.simulator @@ -22,12 +22,32 @@ config FLASH_SIMULATOR_UNALIGNED_READ Disable this option only if you want to simulate a specific FLASH interface that requires aligned read access. +config FLASH_SIMULATOR_EXPLICIT_ERASE + bool "Program-erase device" + select FLASH_HAS_EXPLICIT_ERASE + default y + help + Explicit erase (non-erase-on-write) Flash, which is device that requires erase + to erase-value prior to write as it only allows to change bits from erase-value + to the opposite. + +config FLASH_SIMULATOR_RAMLIKE + bool + default y if !FLASH_SIMULATOR_EXPLICIT_ERASE + select FLASH_HAS_NO_EXPLICIT_ERASE + select FLASH_SIMULATOR_DOUBLE_WRITES + help + This is used for setting FLASH_HAS_NO_EXPLICIT_ERASE. + config FLASH_SIMULATOR_DOUBLE_WRITES bool "Allow program units to be programmed more than once" help If selected, writing to a non-erased program unit will succeed, otherwise, it will return an error. Keep in mind that write operations can only change value of a bit from erase-value to the opposite. + This option does not impact FLASH_SIMULATOR_RAMLIKE. + In case when FLASH_SIMULATOR_EXPLICIT_ERASE is selected multiple writes to the same bit + but only change from erase-value to opposite will be registered. config FLASH_SIMULATOR_SIMULATE_TIMING bool "Hardware timing simulation" diff --git a/drivers/flash/Kconfig.smartbond b/drivers/flash/Kconfig.smartbond index 3cc587ba7e1979..5d5dbd6a98e369 100644 --- a/drivers/flash/Kconfig.smartbond +++ b/drivers/flash/Kconfig.smartbond @@ -7,6 +7,7 @@ config SOC_FLASH_SMARTBOND depends on DT_HAS_RENESAS_SMARTBOND_FLASH_CONTROLLER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU help Enable flash driver for Renesas SmartBond(tm) MCU family. diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index 72481c5ae6ed9c..0c820da97c1c9d 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -6,12 +6,22 @@ # Copyright (c) 2023 Google Inc # SPDX-License-Identifier: Apache-2.0 +config STM32_MEMMAP + bool "NOR Flash in MemoryMapped for XiP" + depends on XIP && \ + (DT_HAS_ST_STM32_OSPI_NOR_ENABLED || \ + DT_HAS_ST_STM32_QSPI_NOR_ENABLED) + help + This option enables the XIP mode for the external NOR flash + mounted on STM32 boards. + config SOC_FLASH_STM32 bool "STM32 flash driver" depends on DT_HAS_ST_STM32_FLASH_CONTROLLER_ENABLED select FLASH_HAS_DRIVER_ENABLED default y select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_STM32_HAL_FLASH if BT_STM32WBA select USE_STM32_HAL_FLASH_EX if BT_STM32WBA @@ -72,11 +82,4 @@ config FLASH_STM32_BLOCK_REGISTERS registers improves system security, because flash content (or protection settings) can't be changed even when exploit was found. -config STM32_MEMMAP - bool "NOR Flash in MemoryMapped for XiP" - depends on XIP - help - This option enables the XIP mode for the external NOR flash - mounted on STM32 boards. - endif # SOC_FLASH_STM32 diff --git a/drivers/flash/Kconfig.stm32_ospi b/drivers/flash/Kconfig.stm32_ospi index 305fcfac76d13d..2cc2ffcab5c00a 100644 --- a/drivers/flash/Kconfig.stm32_ospi +++ b/drivers/flash/Kconfig.stm32_ospi @@ -17,6 +17,7 @@ config FLASH_STM32_OSPI select FLASH_HAS_DRIVER_ENABLED select FLASH_JESD216 select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || $(DT_STM32_OCTOSPI_2_HAS_DMA) select USE_STM32_HAL_DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || \ $(DT_STM32_OCTOSPI_2_HAS_DMA) diff --git a/drivers/flash/Kconfig.stm32_qspi b/drivers/flash/Kconfig.stm32_qspi index c97be5ef354b4c..4aeeaf3e2ee34d 100644 --- a/drivers/flash/Kconfig.stm32_qspi +++ b/drivers/flash/Kconfig.stm32_qspi @@ -15,6 +15,7 @@ config FLASH_STM32_QSPI select FLASH_HAS_DRIVER_ENABLED select FLASH_JESD216 select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE select DMA if $(DT_STM32_QUADSPI_HAS_DMA) select USE_STM32_HAL_DMA if $(DT_STM32_QUADSPI_HAS_DMA) help diff --git a/drivers/flash/Kconfig.stm32_xspi b/drivers/flash/Kconfig.stm32_xspi index 3bea03801f3e35..56241e2ebd3a47 100644 --- a/drivers/flash/Kconfig.stm32_xspi +++ b/drivers/flash/Kconfig.stm32_xspi @@ -3,6 +3,9 @@ # Copyright (c) 2024 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +DT_STM32_XSPI_1_HAS_DMA := $(dt_nodelabel_has_prop,xspi1,dmas) +DT_STM32_XSPI_2_HAS_DMA := $(dt_nodelabel_has_prop,xspi2,dmas) + config FLASH_STM32_XSPI bool "STM32 XSPI Flash driver" default y @@ -13,6 +16,11 @@ config FLASH_STM32_XSPI select FLASH_JESD216 select FLASH_PAGE_LAYOUT select FLASH_HAS_PAGE_LAYOUT - + select DMA if $(DT_STM32_XSPI_1_HAS_DMA) || $(DT_STM32_XSPI_2_HAS_DMA) + select USE_STM32_HAL_DMA if $(DT_STM32_XSPI_1_HAS_DMA) || \ + $(DT_STM32_XSPI_2_HAS_DMA) + select USE_STM32_HAL_DMA_EX if SOC_SERIES_STM32H5X && \ + ($(DT_STM32_XSPI_1_HAS_DMA) || \ + $(DT_STM32_XSPI_2_HAS_DMA)) help Enable XSPI-NOR support on the STM32 family of processors. diff --git a/drivers/flash/Kconfig.xmc4xxx b/drivers/flash/Kconfig.xmc4xxx index 60e5f08a759ef0..eff7b1e5679e9a 100644 --- a/drivers/flash/Kconfig.xmc4xxx +++ b/drivers/flash/Kconfig.xmc4xxx @@ -7,5 +7,6 @@ config SOC_FLASH_XMC4XXX depends on DT_HAS_INFINEON_XMC4XXX_FLASH_CONTROLLER_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE help Enables XMC4XXX flash driver. diff --git a/drivers/flash/flash_ambiq.c b/drivers/flash/flash_ambiq.c index 30ce8524045104..b496790b958682 100644 --- a/drivers/flash/flash_ambiq.c +++ b/drivers/flash/flash_ambiq.c @@ -48,6 +48,11 @@ static struct k_sem flash_ambiq_sem; static const struct flash_parameters flash_ambiq_parameters = { .write_block_size = FLASH_WRITE_BLOCK_SIZE, .erase_value = FLASH_ERASE_BYTE, +#if defined(CONFIG_SOC_SERIES_APOLLO4X) + .caps = { + .no_explicit_erase = true, + }, +#endif }; static bool flash_ambiq_valid_range(off_t offset, size_t len) diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index 6e47b10dbd383d..338c6c8402d61e 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -50,6 +50,22 @@ static inline const struct flash_parameters *z_vrfy_flash_get_parameters(const s } #include +int z_vrfy_flash_fill(const struct device *dev, uint8_t val, off_t offset, + size_t size) +{ + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); + return z_impl_flash_fill(dev, val, offset, size); +} +#include + +int z_vrfy_flash_flatten(const struct device *dev, off_t offset, size_t size) +{ + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); + return z_impl_flash_flatten(dev, offset, size); +} + +#include + #ifdef CONFIG_FLASH_PAGE_LAYOUT static inline int z_vrfy_flash_get_page_info_by_offs(const struct device *dev, off_t offs, diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 015bbbe99158eb..a0d6a19a2332a9 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -73,9 +73,11 @@ static int parse_helper(const struct shell *sh, size_t *argc, static int cmd_erase(const struct shell *sh, size_t argc, char *argv[]) { + int result = -ENOTSUP; + +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) const struct device *flash_dev; uint32_t page_addr; - int result; uint32_t size; result = parse_helper(sh, &argc, &argv, &flash_dev, &page_addr); @@ -106,6 +108,7 @@ static int cmd_erase(const struct shell *sh, size_t argc, char *argv[]) } else { shell_print(sh, "Erase success."); } +#endif return result; } diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index effd53c1f2b30d..3a7d578a250a6d 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -162,7 +162,12 @@ static const struct flash_driver_api flash_sim_api; static const struct flash_parameters flash_sim_parameters = { .write_block_size = FLASH_SIMULATOR_PROG_UNIT, - .erase_value = FLASH_SIMULATOR_ERASE_VALUE + .erase_value = FLASH_SIMULATOR_ERASE_VALUE, + .caps = { +#if !defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) + .no_explicit_erase = false, +#endif + }, }; static int flash_range_is_valid(const struct device *dev, off_t offset, @@ -226,8 +231,12 @@ static int flash_sim_write(const struct device *dev, const off_t offset, FLASH_SIM_STATS_INC(flash_sim_stats, flash_write_calls); +#if defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) /* check if any unit has been already programmed */ memset(buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(buf)); +#else + memcpy(buf, MOCK_FLASH(offset), sizeof(buf)); +#endif for (uint32_t i = 0; i < len; i += FLASH_SIMULATOR_PROG_UNIT) { if (memcmp(buf, MOCK_FLASH(offset + i), sizeof(buf))) { FLASH_SIM_STATS_INC(flash_sim_stats, double_writes); @@ -265,10 +274,14 @@ static int flash_sim_write(const struct device *dev, const off_t offset, #endif /* CONFIG_FLASH_SIMULATOR_STATS */ /* only pull bits to zero */ +#if IS_ENABLED(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) #if FLASH_SIMULATOR_ERASE_VALUE == 0xFF *(MOCK_FLASH(offset + i)) &= *((uint8_t *)data + i); #else *(MOCK_FLASH(offset + i)) |= *((uint8_t *)data + i); +#endif +#else + *(MOCK_FLASH(offset + i)) = *((uint8_t *)data + i); #endif } diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index e34c38e6eec714..c893545db226f7 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -898,6 +898,8 @@ static int stm32_ospi_mem_reset(const struct device *dev) struct flash_stm32_ospi_data *dev_data = dev->data; #if STM32_OSPI_RESET_GPIO + const struct flash_stm32_ospi_config *dev_cfg = dev->config; + /* Generate RESETn pulse for the flash memory */ gpio_pin_configure_dt(&dev_cfg->reset, GPIO_OUTPUT_ACTIVE); k_msleep(DT_INST_PROP(0, reset_gpios_duration)); diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index adec32e8e4e6fe..0ff33baf55dac0 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -35,7 +35,7 @@ #define STM32_QSPI_BASE_ADDRESS DT_INST_REG_ADDR(0) #define STM32_QSPI_RESET_GPIO DT_INST_NODE_HAS_PROP(0, reset_gpios) -#define STM32_QSPI_RESET_CMD DT_INST_NODE_HAS_PROP(0, reset_cmd) +#define STM32_QSPI_RESET_CMD DT_PROP(DT_NODELABEL(quadspi), set_cmd) #include @@ -125,6 +125,11 @@ struct flash_stm32_qspi_data { bool flag_access_32bit: 1; }; +static const QSPI_CommandTypeDef cmd_write_en = { + .Instruction = SPI_NOR_CMD_WREN, + .InstructionMode = QSPI_INSTRUCTION_1_LINE +}; + static inline void qspi_lock_thread(const struct device *dev) { struct flash_stm32_qspi_data *dev_data = dev->data; @@ -191,7 +196,7 @@ static inline int qspi_prepare_quad_program(const struct device *dev, /* * Send a command over QSPI bus. */ -static int qspi_send_cmd(const struct device *dev, QSPI_CommandTypeDef *cmd) +static int qspi_send_cmd(const struct device *dev, const QSPI_CommandTypeDef *cmd) { const struct flash_stm32_qspi_config *dev_cfg = dev->config; struct flash_stm32_qspi_data *dev_data = dev->data; @@ -203,7 +208,7 @@ static int qspi_send_cmd(const struct device *dev, QSPI_CommandTypeDef *cmd) dev_data->cmd_status = 0; - hal_ret = HAL_QSPI_Command_IT(&dev_data->hqspi, cmd); + hal_ret = HAL_QSPI_Command_IT(&dev_data->hqspi, (QSPI_CommandTypeDef *)cmd); if (hal_ret != HAL_OK) { LOG_ERR("%d: Failed to send QSPI instruction", hal_ret); return -EIO; @@ -546,11 +551,6 @@ static int flash_stm32_qspi_write(const struct device *dev, off_t addr, return 0; } - QSPI_CommandTypeDef cmd_write_en = { - .Instruction = SPI_NOR_CMD_WREN, - .InstructionMode = QSPI_INSTRUCTION_1_LINE, - }; - QSPI_CommandTypeDef cmd_pp = { .Instruction = SPI_NOR_CMD_PP, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -640,11 +640,6 @@ static int flash_stm32_qspi_erase(const struct device *dev, off_t addr, return 0; } - QSPI_CommandTypeDef cmd_write_en = { - .Instruction = SPI_NOR_CMD_WREN, - .InstructionMode = QSPI_INSTRUCTION_1_LINE, - }; - QSPI_CommandTypeDef cmd_erase = { .Instruction = 0, .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -919,10 +914,6 @@ static int qspi_program_addr_4b(const struct device *dev, bool write_enable) /* Send write enable command, if required */ if (write_enable) { - QSPI_CommandTypeDef cmd_write_en = { - .Instruction = SPI_NOR_CMD_WREN, - .InstructionMode = QSPI_INSTRUCTION_1_LINE, - }; ret = qspi_send_cmd(dev, &cmd_write_en); if (ret != 0) { return ret; @@ -1030,11 +1021,6 @@ static int qspi_write_enable(const struct device *dev) uint8_t reg; int ret; - QSPI_CommandTypeDef cmd_write_en = { - .Instruction = SPI_NOR_CMD_WREN, - .InstructionMode = QSPI_INSTRUCTION_1_LINE, - }; - ret = qspi_send_cmd(dev, &cmd_write_en); if (ret) { return ret; @@ -1392,6 +1378,19 @@ static int flash_stm32_qspi_init(const struct device *dev) dev_data->hqspi.Init.ClockPrescaler = prescaler; /* Give a bit position from 0 to 31 to the HAL init minus 1 for the DCR1 reg */ dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size) - 2; +#if DT_PROP(DT_NODELABEL(quadspi), dual_flash) && defined(QUADSPI_CR_DFM) + /* + * When the DTS has , it means Dual Flash Mode + * Even in DUAL flash config, the SDFP is read from one single quad-NOR + * else the magic nb is wrong (0x46465353) + * That means that the Dual Flash config is set after the SFDP sequence + */ + dev_data->hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + dev_data->hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_3_CYCLE; + dev_data->hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; + /* Set Dual Flash Mode only on MemoryMapped */ + dev_data->hqspi.Init.FlashID = QSPI_FLASH_ID_1; +#endif /* dual_flash */ HAL_QSPI_Init(&dev_data->hqspi); @@ -1485,6 +1484,16 @@ static int flash_stm32_qspi_init(const struct device *dev) #endif /* CONFIG_FLASH_PAGE_LAYOUT */ #ifdef CONFIG_STM32_MEMMAP +#if DT_PROP(DT_NODELABEL(quadspi), dual_flash) && defined(QUADSPI_CR_DFM) + /* + * When the DTS has dual_flash, it means Dual Flash Mode for Memory MAPPED + * Force Dual Flash mode now, after the SFDP sequence which is reading + * one quad-NOR only + */ + MODIFY_REG(dev_data->hqspi.Instance->CR, (QUADSPI_CR_DFM), QSPI_DUALFLASH_ENABLE); + LOG_DBG("Dual Flash Mode"); +#endif /* dual_flash */ + ret = stm32_qspi_set_memory_mapped(dev); if (ret != 0) { LOG_ERR("Failed to enable memory-mapped mode: %d", ret); diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index ae08e1d07cdc14..ae7cbb6862b3c9 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -44,6 +44,14 @@ LOG_MODULE_REGISTER(flash_stm32_xspi, CONFIG_FLASH_LOG_LEVEL); #define STM32_XSPI_DLYB_BYPASSED DT_PROP(STM32_XSPI_NODE, dlyb_bypass) +#define STM32_XSPI_USE_DMA DT_NODE_HAS_PROP(STM32_XSPI_NODE, dmas) + +#if STM32_XSPI_USE_DMA +#include +#include +#include +#endif /* STM32_XSPI_USE_DMA */ + #include "flash_stm32_xspi.h" static inline void xspi_lock_thread(const struct device *dev) @@ -97,7 +105,11 @@ static int xspi_read_access(const struct device *dev, XSPI_RegularCmdTypeDef *cm return -EIO; } +#if STM32_XSPI_USE_DMA + hal_ret = HAL_XSPI_Receive_DMA(&dev_data->hxspi, data); +#else hal_ret = HAL_XSPI_Receive_IT(&dev_data->hxspi, data); +#endif if (hal_ret != HAL_OK) { LOG_ERR("%d: Failed to read data", hal_ret); @@ -135,7 +147,11 @@ static int xspi_write_access(const struct device *dev, XSPI_RegularCmdTypeDef *c return -EIO; } +#if STM32_XSPI_USE_DMA + hal_ret = HAL_XSPI_Transmit_DMA(&dev_data->hxspi, (uint8_t *)data); +#else hal_ret = HAL_XSPI_Transmit_IT(&dev_data->hxspi, (uint8_t *)data); +#endif if (hal_ret != HAL_OK) { LOG_ERR("%d: Failed to write data", hal_ret); @@ -737,6 +753,8 @@ static int stm32_xspi_mem_reset(const struct device *dev) struct flash_stm32_xspi_data *dev_data = dev->data; #if STM32_XSPI_RESET_GPIO + const struct flash_stm32_xspi_config *dev_cfg = dev->config; + /* Generate RESETn pulse for the flash memory */ gpio_pin_configure_dt(&dev_cfg->reset, GPIO_OUTPUT_ACTIVE); k_msleep(DT_INST_PROP(0, reset_gpios_duration)); @@ -1218,6 +1236,24 @@ __weak HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) } #endif /* !CONFIG_SOC_SERIES_STM32H7X */ +/* This function is executed in the interrupt context */ +#if STM32_XSPI_USE_DMA +static void xspi_dma_callback(const struct device *dev, void *arg, + uint32_t channel, int status) +{ + DMA_HandleTypeDef *hdma = arg; + + ARG_UNUSED(dev); + + if (status < 0) { + LOG_ERR("DMA callback error with channel %d.", channel); + } + + HAL_DMA_IRQHandler(hdma); +} +#endif + + /* * Transfer Error callback. */ @@ -1705,6 +1741,85 @@ static int spi_nor_process_bfp(const struct device *dev, return 0; } +#if STM32_XSPI_USE_DMA +static int flash_stm32_xspi_dma_init(DMA_HandleTypeDef *hdma, struct stream *dma_stream) +{ + int ret; + /* + * DMA configuration + * Due to use of XSPI HAL API in current driver, + * both HAL and Zephyr DMA drivers should be configured. + * The required configuration for Zephyr DMA driver should only provide + * the minimum information to inform the DMA slot will be in used and + * how to route callbacks. + */ + + if (!device_is_ready(dma_stream->dev)) { + LOG_ERR("DMA %s device not ready", dma_stream->dev->name); + return -ENODEV; + } + /* Proceed to the minimum Zephyr DMA driver init of the channel */ + dma_stream->cfg.user_data = hdma; + /* HACK: This field is used to inform driver that it is overridden */ + dma_stream->cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; + /* Because of the STREAM OFFSET, the DMA channel given here is from 1 - 8 */ + ret = dma_config(dma_stream->dev, + (dma_stream->channel + STM32_DMA_STREAM_OFFSET), &dma_stream->cfg); + if (ret != 0) { + LOG_ERR("Failed to configure DMA channel %d", + dma_stream->channel + STM32_DMA_STREAM_OFFSET); + return ret; + } + + /* Proceed to the HAL DMA driver init */ + if (dma_stream->cfg.source_data_size != dma_stream->cfg.dest_data_size) { + LOG_ERR("DMA Source and destination data sizes not aligned"); + return -EINVAL; + } + + hdma->Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; /* Fixed value */ + hdma->Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; /* Fixed value */ + hdma->Init.SrcInc = (dma_stream->src_addr_increment) + ? DMA_SINC_INCREMENTED + : DMA_SINC_FIXED; + hdma->Init.DestInc = (dma_stream->dst_addr_increment) + ? DMA_DINC_INCREMENTED + : DMA_DINC_FIXED; + hdma->Init.SrcBurstLength = 4; + hdma->Init.DestBurstLength = 4; + hdma->Init.Priority = table_priority[dma_stream->cfg.channel_priority]; + hdma->Init.Direction = table_direction[dma_stream->cfg.channel_direction]; + hdma->Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_SRC_ALLOCATED_PORT1; + hdma->Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + hdma->Init.Mode = DMA_NORMAL; + hdma->Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + hdma->Init.Request = dma_stream->cfg.dma_slot; + + /* + * HAL expects a valid DMA channel (not DMAMUX). + * The channel is from 0 to 7 because of the STM32_DMA_STREAM_OFFSET + * in the dma_stm32 driver + */ + hdma->Instance = LL_DMA_GET_CHANNEL_INSTANCE(dma_stream->reg, + dma_stream->channel); + + /* Initialize DMA HAL */ + if (HAL_DMA_Init(hdma) != HAL_OK) { + LOG_ERR("XSPI DMA Init failed"); + return -EIO; + } + + if (HAL_DMA_ConfigChannelAttributes(hdma, DMA_CHANNEL_NPRIV) != HAL_OK) { + LOG_ERR("XSPI DMA Init failed"); + return -EIO; + } + + LOG_DBG("XSPI with DMA transfer"); + return 0; +} +#endif /* STM32_XSPI_USE_DMA */ + + static int flash_stm32_xspi_init(const struct device *dev) { const struct flash_stm32_xspi_config *dev_cfg = dev->config; @@ -1733,41 +1848,53 @@ static int flash_stm32_xspi_init(const struct device *dev) return -ENODEV; } + if (dev_cfg->pclk_len > 3) { + /* Max 3 domain clock are expected */ + LOG_ERR("Could not select %d XSPI domain clock", dev_cfg->pclk_len); + return -EIO; + } + /* Clock configuration */ if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &dev_cfg->pclken) != 0) { + (clock_control_subsys_t) &dev_cfg->pclken[0]) != 0) { LOG_ERR("Could not enable XSPI clock"); return -EIO; } - /* Alternate clock config for peripheral if any */ -#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_ker) - if (clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &dev_cfg->pclken_ker, - NULL) != 0) { - LOG_ERR("Could not select XSPI domain clock"); - return -EIO; - } - if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &dev_cfg->pclken_ker, - &ahb_clock_freq) < 0) { - LOG_ERR("Failed call clock_control_get_rate(pclken_ker)"); - return -EIO; - } -#else if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &dev_cfg->pclken, + (clock_control_subsys_t) &dev_cfg->pclken[0], &ahb_clock_freq) < 0) { LOG_ERR("Failed call clock_control_get_rate(pclken)"); return -EIO; } -#endif -#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_mgr) - if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &dev_cfg->pclken_mgr) != 0) { - LOG_ERR("Could not enable XSPI Manager clock"); - return -EIO; + /* Alternate clock config for peripheral if any */ + if (IS_ENABLED(STM32_XSPI_DOMAIN_CLOCK_SUPPORT) && (dev_cfg->pclk_len > 1)) { + if (clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &dev_cfg->pclken[1], + NULL) != 0) { + LOG_ERR("Could not select XSPI domain clock"); + return -EIO; + } + /* + * Get the clock rate from this one (update ahb_clock_freq) + * TODO: retrieve index in the clocks property where clocks has "xspi-ker" + * Assuming index is 1 + */ + if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &dev_cfg->pclken[1], + &ahb_clock_freq) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclken)"); + return -EIO; + } + } + /* Clock domain corresponding to the IO-Mgr (XSPIM) */ + if (IS_ENABLED(STM32_XSPI_DOMAIN_CLOCK_SUPPORT) && (dev_cfg->pclk_len > 2)) { + if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &dev_cfg->pclken[2]) != 0) { + LOG_ERR("Could not enable XSPI Manager clock"); + return -EIO; + } + /* Do NOT Get the clock rate from this one */ } -#endif for (; prescaler <= STM32_XSPI_CLOCK_PRESCALER_MAX; prescaler++) { uint32_t clk = STM32_XSPI_CLOCK_COMPUTE(ahb_clock_freq, prescaler); @@ -1845,6 +1972,28 @@ static int flash_stm32_xspi_init(const struct device *dev) #endif /* DLYB_ */ +#if STM32_XSPI_USE_DMA + /* Configure and enable the DMA channels after XSPI config */ + static DMA_HandleTypeDef hdma_tx; + static DMA_HandleTypeDef hdma_rx; + + if (flash_stm32_xspi_dma_init(&hdma_tx, &dev_data->dma_tx) != 0) { + LOG_ERR("XSPI DMA Tx init failed"); + return -EIO; + } + + /* The dma_tx handle is hold by the dma_stream.cfg.user_data */ + __HAL_LINKDMA(&dev_data->hxspi, hdmatx, hdma_tx); + + if (flash_stm32_xspi_dma_init(&hdma_rx, &dev_data->dma_rx) != 0) { + LOG_ERR("XSPI DMA Rx init failed"); + return -EIO; + } + + /* The dma_rx handle is hold by the dma_stream.cfg.user_data */ + __HAL_LINKDMA(&dev_data->hxspi, hdmarx, hdma_rx); + +#endif /* CONFIG_USE_STM32_HAL_DMA */ /* Initialize semaphores */ k_sem_init(&dev_data->sem, 1, 1); k_sem_init(&dev_data->sync, 0, 1); @@ -1990,6 +2139,39 @@ static int flash_stm32_xspi_init(const struct device *dev) return 0; } + +#if STM32_XSPI_USE_DMA +#define DMA_CHANNEL_CONFIG(node, dir) \ + DT_DMAS_CELL_BY_NAME(node, dir, channel_config) + +#define XSPI_DMA_CHANNEL_INIT(node, dir, dir_cap, src_dev, dest_dev) \ + .dev = DEVICE_DT_GET(DT_DMAS_CTLR(node)), \ + .channel = DT_DMAS_CELL_BY_NAME(node, dir, channel), \ + .reg = (DMA_TypeDef *)DT_REG_ADDR( \ + DT_PHANDLE_BY_NAME(node, dmas, dir)), \ + .cfg = { \ + .dma_slot = DT_DMAS_CELL_BY_NAME(node, dir, slot), \ + .channel_direction = STM32_DMA_CONFIG_DIRECTION( \ + DMA_CHANNEL_CONFIG(node, dir)), \ + .channel_priority = STM32_DMA_CONFIG_PRIORITY( \ + DMA_CHANNEL_CONFIG(node, dir)), \ + .dma_callback = xspi_dma_callback, \ + }, \ + .src_addr_increment = STM32_DMA_CONFIG_##src_dev##_ADDR_INC( \ + DMA_CHANNEL_CONFIG(node, dir)), \ + .dst_addr_increment = STM32_DMA_CONFIG_##dest_dev##_ADDR_INC( \ + DMA_CHANNEL_CONFIG(node, dir)), + +#define XSPI_DMA_CHANNEL(node, dir, DIR, src, dest) \ + .dma_##dir = { \ + COND_CODE_1(DT_DMAS_HAS_NAME(node, dir), \ + (XSPI_DMA_CHANNEL_INIT(node, dir, DIR, src, dest)), \ + (NULL)) \ + }, +#else +#define XSPI_DMA_CHANNEL(node, dir, DIR, src, dest) +#endif /* CONFIG_USE_STM32_HAL_DMA */ + #define XSPI_FLASH_MODULE(drv_id, flash_id) \ (DT_DRV_INST(drv_id), xspi_nor_flash_##flash_id) @@ -2006,19 +2188,13 @@ static int flash_stm32_xspi_init(const struct device *dev) static void flash_stm32_xspi_irq_config_func(const struct device *dev); +static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(STM32_XSPI_NODE); + PINCTRL_DT_DEFINE(STM32_XSPI_NODE); static const struct flash_stm32_xspi_config flash_stm32_xspi_cfg = { - .pclken = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspix, bus), - .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspix, bits)}, -#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_ker) - .pclken_ker = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_ker, bus), - .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_ker, bits)}, -#endif -#if DT_CLOCKS_HAS_NAME(STM32_XSPI_NODE, xspi_mgr) - .pclken_mgr = {.bus = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_mgr, bus), - .enr = DT_CLOCKS_CELL_BY_NAME(STM32_XSPI_NODE, xspi_mgr, bits)}, -#endif + .pclken = pclken, + .pclk_len = DT_NUM_CLOCKS(STM32_XSPI_NODE), .irq_config = flash_stm32_xspi_irq_config_func, .flash_size = DT_INST_REG_ADDR_BY_IDX(0, 1), .max_frequency = DT_INST_PROP(0, ospi_max_frequency), @@ -2057,16 +2233,18 @@ static struct flash_stm32_xspi_data flash_stm32_xspi_dev_data = { #if DT_NODE_HAS_PROP(DT_INST(0, st_stm32_ospi_nor), jedec_id) .jedec_id = DT_INST_PROP(0, jedec_id), #endif /* jedec_id */ + XSPI_DMA_CHANNEL(STM32_XSPI_NODE, tx, TX, MEMORY, PERIPHERAL) + XSPI_DMA_CHANNEL(STM32_XSPI_NODE, rx, RX, PERIPHERAL, MEMORY) }; -DEVICE_DT_INST_DEFINE(0, &flash_stm32_xspi_init, NULL, - &flash_stm32_xspi_dev_data, &flash_stm32_xspi_cfg, - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &flash_stm32_xspi_driver_api); - static void flash_stm32_xspi_irq_config_func(const struct device *dev) { IRQ_CONNECT(DT_IRQN(STM32_XSPI_NODE), DT_IRQ(STM32_XSPI_NODE, priority), flash_stm32_xspi_isr, DEVICE_DT_INST_GET(0), 0); irq_enable(DT_IRQN(STM32_XSPI_NODE)); } + +DEVICE_DT_INST_DEFINE(0, &flash_stm32_xspi_init, NULL, + &flash_stm32_xspi_dev_data, &flash_stm32_xspi_cfg, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &flash_stm32_xspi_driver_api); diff --git a/drivers/flash/flash_stm32_xspi.h b/drivers/flash/flash_stm32_xspi.h index d940cc93343b39..316efdbcd87882 100644 --- a/drivers/flash/flash_stm32_xspi.h +++ b/drivers/flash/flash_stm32_xspi.h @@ -7,6 +7,19 @@ #ifndef ZEPHYR_DRIVERS_FLASH_XSPI_STM32_H_ #define ZEPHYR_DRIVERS_FLASH_XSPI_STM32_H_ +/* Macro to check if any xspi device has a domain clock or more */ +#define STM32_XSPI_DOMAIN_CLOCK_INST_SUPPORT(inst) \ + DT_CLOCKS_HAS_IDX(DT_INST_PARENT(inst), 1) || +#define STM32_XSPI_INST_DEV_DOMAIN_CLOCK_SUPPORT \ + (DT_INST_FOREACH_STATUS_OKAY(STM32_XSPI_DOMAIN_CLOCK_INST_SUPPORT) 0) + +/* This symbol takes the value 1 if device instance has a domain clock in its dts */ +#if STM32_XSPI_INST_DEV_DOMAIN_CLOCK_SUPPORT +#define STM32_XSPI_DOMAIN_CLOCK_SUPPORT 1 +#else +#define STM32_XSPI_DOMAIN_CLOCK_SUPPORT 0 +#endif + #define STM32_XSPI_FIFO_THRESHOLD 4U /* Valid range is [0, 255] */ @@ -24,12 +37,38 @@ /* used as default value for DTS writeoc */ #define SPI_NOR_WRITEOC_NONE 0xFF +#if STM32_XSPI_USE_DMA +/* Lookup table to set dma priority from the DTS */ +static const uint32_t table_priority[] = { + DMA_LOW_PRIORITY_LOW_WEIGHT, + DMA_LOW_PRIORITY_MID_WEIGHT, + DMA_LOW_PRIORITY_HIGH_WEIGHT, + DMA_HIGH_PRIORITY, +}; + +/* Lookup table to set dma channel direction from the DTS */ +static const uint32_t table_direction[] = { + DMA_MEMORY_TO_MEMORY, + DMA_MEMORY_TO_PERIPH, + DMA_PERIPH_TO_MEMORY, +}; + +struct stream { + DMA_TypeDef *reg; + const struct device *dev; + uint32_t channel; + struct dma_config cfg; + uint8_t priority; + bool src_addr_increment; + bool dst_addr_increment; +}; +#endif /* STM32_XSPI_USE_DMA */ + typedef void (*irq_config_func_t)(const struct device *dev); struct flash_stm32_xspi_config { - const struct stm32_pclken pclken; /* clock subsystem */ - const struct stm32_pclken pclken_ker; /* clock subsystem */ - const struct stm32_pclken pclken_mgr; /* clock subsystem */ + const struct stm32_pclken *pclken; + size_t pclk_len; irq_config_func_t irq_config; size_t flash_size; uint32_t max_frequency; @@ -65,6 +104,10 @@ struct flash_stm32_xspi_data { uint8_t jedec_id[JESD216_READ_ID_LEN]; #endif /* CONFIG_FLASH_JESD216_API */ int cmd_status; +#if STM32_XSPI_USE_DMA + struct stream dma_tx; + struct stream dma_rx; +#endif /* STM32_XSPI_USE_DMA */ }; #endif /* ZEPHYR_DRIVERS_FLASH_XSPI_STM32_H_ */ diff --git a/drivers/flash/flash_util.c b/drivers/flash/flash_util.c new file mode 100644 index 00000000000000..cbaaa2049097cd --- /dev/null +++ b/drivers/flash/flash_util.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(flash, CONFIG_FLASH_LOG_LEVEL); + +int z_impl_flash_fill(const struct device *dev, uint8_t val, off_t offset, + size_t size) +{ + uint8_t filler[CONFIG_FLASH_FILL_BUFFER_SIZE]; + const struct flash_driver_api *api = + (const struct flash_driver_api *)dev->api; + const struct flash_parameters *fparams = api->get_parameters(dev); + int rc = 0; + size_t stored = 0; + + if (sizeof(filler) < fparams->write_block_size) { + LOG_ERR("Size of CONFIG_FLASH_FILL_BUFFER_SIZE"); + return -EINVAL; + } + /* The flash_write will, probably, check write alignment but this + * is too late, as we write datain chunks; data alignment may be + * broken by the size of the last chunk, that is why the check + * happens here too. + * Note that we have no way to check whether offset and size are + * are correct, as such info is only available at the level of + * a driver, so only basic check on offset. + */ + if (offset < 0) { + LOG_ERR("Negative offset not allowed\n"); + return -EINVAL; + } + if ((size | (size_t)offset) & (fparams->write_block_size - 1)) { + LOG_ERR("Incorrect size or offset alignment, expected %zx\n", + fparams->write_block_size); + return -EINVAL; + } + + memset(filler, val, sizeof(filler)); + + while (stored < size) { + size_t chunk = MIN(sizeof(filler), size); + + rc = api->write(dev, offset + stored, filler, chunk); + if (rc < 0) { + LOG_DBG("Fill to dev %p failed at offset 0x%zx\n", + dev, (size_t)offset + stored); + break; + } + stored += chunk; + } + return rc; +} + +int z_impl_flash_flatten(const struct device *dev, off_t offset, size_t size) +{ + const struct flash_driver_api *api = + (const struct flash_driver_api *)dev->api; + __maybe_unused const struct flash_parameters *params = api->get_parameters(dev); + +#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) + if ((flash_params_get_erase_cap(params) & FLASH_ERASE_C_EXPLICIT) && + api->erase != NULL) { + return api->erase(dev, offset, size); + } +#endif + +#if IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) + return flash_fill(dev, params->erase_value, offset, size); +#else + return -ENOSYS; +#endif +} diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index cc840309264e63..de9cfd423450db 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2023 Nordic Semiconductor ASA + * Copyright (c) 2017-2024 Nordic Semiconductor ASA * Copyright (c) 2016 Linaro Limited * Copyright (c) 2016 Intel Corporation * diff --git a/drivers/flash/soc_flash_nrf_mram.c b/drivers/flash/soc_flash_nrf_mram.c index 9b33ee05d6f6cf..5d8215f7af30b3 100644 --- a/drivers/flash/soc_flash_nrf_mram.c +++ b/drivers/flash/soc_flash_nrf_mram.c @@ -142,6 +142,9 @@ static const struct flash_parameters *nrf_mram_get_parameters(const struct devic static const struct flash_parameters parameters = { .write_block_size = WRITE_BLOCK_SIZE, .erase_value = ERASE_VALUE, + .caps = { + .no_explicit_erase = true, + }, }; return ¶meters; diff --git a/drivers/flash/soc_flash_nrf_rram.c b/drivers/flash/soc_flash_nrf_rram.c index 9e5e652ca5ed55..35a6c98862c699 100644 --- a/drivers/flash/soc_flash_nrf_rram.c +++ b/drivers/flash/soc_flash_nrf_rram.c @@ -309,6 +309,9 @@ static const struct flash_parameters *nrf_rram_get_parameters(const struct devic static const struct flash_parameters parameters = { .write_block_size = WRITE_LINE_SIZE, .erase_value = ERASE_VALUE, + .caps = { + .no_explicit_erase = true, + }, }; return ¶meters; diff --git a/drivers/flash/soc_flash_numaker_rmc.c b/drivers/flash/soc_flash_numaker_rmc.c index 7e7d81f348b8ce..4a6b4ff6b5f531 100644 --- a/drivers/flash/soc_flash_numaker_rmc.c +++ b/drivers/flash/soc_flash_numaker_rmc.c @@ -29,6 +29,9 @@ struct flash_numaker_data { static const struct flash_parameters flash_numaker_parameters = { .write_block_size = SOC_NV_FLASH_WRITE_BLOCK_SIZE, .erase_value = 0xff, + .caps = { + .no_explicit_erase = true, + }, }; /* Validate offset and length */ diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 1c46a9103ef572..36d7a664f70c2d 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -515,13 +515,14 @@ static int enter_dpd(const struct device *const dev) static int exit_dpd(const struct device *const dev) { int ret = 0; +#if ANY_INST_HAS_DPD const struct spi_nor_config *cfg = dev->config; if (cfg->dpd_exist) { delay_until_exit_dpd_ok(dev); -#if ANY_INST_HAS_DPD_WAKEUP_SEQUENCE if (cfg->dpd_wakeup_sequence_exist) { +#if ANY_INST_HAS_DPD_WAKEUP_SEQUENCE /* Assert CSn and wait for tCRDP. * * Unfortunately the SPI API doesn't allow us to @@ -534,6 +535,7 @@ static int exit_dpd(const struct device *const dev) /* Deassert CSn and wait for tRDP */ k_sleep(K_MSEC(cfg->t_rdp_ms)); +#endif /* ANY_INST_HAS_DPD_WAKEUP_SEQUENCE */ } else { ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_RDPD); @@ -545,8 +547,8 @@ static int exit_dpd(const struct device *const dev) } #endif /* T_EXIT_DPD */ } -#endif /* DPD_WAKEUP_SEQUENCE */ } +#endif /* ANY_INST_HAS_DPD */ return ret; } diff --git a/drivers/gnss/gnss_emul.c b/drivers/gnss/gnss_emul.c index 553736f0ba7217..37245341f036f5 100644 --- a/drivers/gnss/gnss_emul.c +++ b/drivers/gnss/gnss_emul.c @@ -336,7 +336,7 @@ static int gnss_emul_api_get_supported_systems(const struct device *dev, gnss_sy return 0; } -static struct gnss_driver_api api = { +static const struct gnss_driver_api api = { .set_fix_rate = gnss_emul_api_set_fix_rate, .get_fix_rate = gnss_emul_api_get_fix_rate, .set_navigation_mode = gnss_emul_api_set_navigation_mode, diff --git a/drivers/gnss/gnss_luatos_air530z.c b/drivers/gnss/gnss_luatos_air530z.c index a24c8245ac329f..0d26b8b71ac941 100644 --- a/drivers/gnss/gnss_luatos_air530z.c +++ b/drivers/gnss/gnss_luatos_air530z.c @@ -336,28 +336,28 @@ static int luatos_air530z_get_supported_systems(const struct device *dev, gnss_s return 0; } -static struct gnss_driver_api gnss_api = { +static const struct gnss_driver_api gnss_api = { .set_fix_rate = luatos_air530z_set_fix_rate, .set_enabled_systems = luatos_air530z_set_enabled_systems, .get_supported_systems = luatos_air530z_get_supported_systems, }; -#define LUATOS_AIR530Z(inst) \ - static struct gnss_luatos_air530z_config gnss_luatos_air530z_cfg_##inst = { \ - .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ - .on_off_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, on_off_gpios, { 0 }), \ - }; \ - \ - static struct gnss_luatos_air530z_data gnss_luatos_air530z_data_##inst = { \ - .chat_delimiter = {'\r', '\n'}, \ - .dynamic_separators_buf = {',', '*'}, \ - }; \ - \ - PM_DEVICE_DT_INST_DEFINE(inst, luatos_air530z_pm_action); \ - \ - DEVICE_DT_INST_DEFINE(inst, gnss_luatos_air530z_init, \ - PM_DEVICE_DT_INST_GET(inst), \ - &gnss_luatos_air530z_data_##inst, \ +#define LUATOS_AIR530Z(inst) \ + static const struct gnss_luatos_air530z_config gnss_luatos_air530z_cfg_##inst = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .on_off_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, on_off_gpios, { 0 }), \ + }; \ + \ + static struct gnss_luatos_air530z_data gnss_luatos_air530z_data_##inst = { \ + .chat_delimiter = {'\r', '\n'}, \ + .dynamic_separators_buf = {',', '*'}, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, luatos_air530z_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(inst, gnss_luatos_air530z_init, \ + PM_DEVICE_DT_INST_GET(inst), \ + &gnss_luatos_air530z_data_##inst, \ &gnss_luatos_air530z_cfg_##inst, \ POST_KERNEL, CONFIG_GNSS_INIT_PRIORITY, &gnss_api); diff --git a/drivers/gnss/gnss_nmea_generic.c b/drivers/gnss/gnss_nmea_generic.c index 2c92ce480ba4f3..b42d08acfad319 100644 --- a/drivers/gnss/gnss_nmea_generic.c +++ b/drivers/gnss/gnss_nmea_generic.c @@ -81,7 +81,7 @@ static int gnss_nmea_generic_resume(const struct device *dev) return ret; } -static struct gnss_driver_api gnss_api = { +static const struct gnss_driver_api gnss_api = { }; static int gnss_nmea_generic_init_nmea0183_match(const struct device *dev) @@ -183,7 +183,7 @@ MODEM_CHAT_SCRIPT_EMPTY_DEFINE(gnss_nmea_generic_init_chat_script); #endif #define GNSS_NMEA_GENERIC(inst) \ - static struct gnss_nmea_generic_config gnss_nmea_generic_cfg_##inst = { \ + static const struct gnss_nmea_generic_config gnss_nmea_generic_cfg_##inst = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .init_chat_script = &_CONCAT(DT_DRV_COMPAT, _init_chat_script), \ }; \ diff --git a/drivers/gnss/gnss_quectel_lcx6g.c b/drivers/gnss/gnss_quectel_lcx6g.c index 077dc0d7985ce3..95d611cefc51b6 100644 --- a/drivers/gnss/gnss_quectel_lcx6g.c +++ b/drivers/gnss/gnss_quectel_lcx6g.c @@ -717,7 +717,7 @@ static int quectel_lcx6g_get_supported_systems(const struct device *dev, gnss_sy return 0; } -static struct gnss_driver_api gnss_api = { +static const struct gnss_driver_api gnss_api = { .set_fix_rate = quectel_lcx6g_set_fix_rate, .get_fix_rate = quectel_lcx6g_get_fix_rate, .set_navigation_mode = quectel_lcx6g_set_navigation_mode, @@ -837,7 +837,7 @@ static int quectel_lcx6g_init(const struct device *dev) _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) #define LCX6G_DEVICE(inst) \ - static struct quectel_lcx6g_config LCX6G_INST_NAME(inst, config) = { \ + static const struct quectel_lcx6g_config LCX6G_INST_NAME(inst, config) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .pps_mode = DT_INST_STRING_UPPER_TOKEN(inst, pps_mode), \ .pps_pulse_width = DT_INST_PROP(inst, pps_pulse_width), \ diff --git a/drivers/gnss/gnss_u_blox_m10.c b/drivers/gnss/gnss_u_blox_m10.c index a5bb8d1e07defc..e5641ab634a93c 100644 --- a/drivers/gnss/gnss_u_blox_m10.c +++ b/drivers/gnss/gnss_u_blox_m10.c @@ -933,7 +933,7 @@ static int ubx_m10_get_fix_rate(const struct device *dev, uint32_t *fix_interval return ret; } -static struct gnss_driver_api gnss_api = { +static const struct gnss_driver_api gnss_api = { .set_fix_rate = ubx_m10_set_fix_rate, .get_fix_rate = ubx_m10_get_fix_rate, .set_navigation_mode = ubx_m10_set_navigation_mode, @@ -1020,7 +1020,7 @@ static int ubx_m10_init(const struct device *dev) } #define UBX_M10(inst) \ - static struct ubx_m10_config ubx_m10_cfg_##inst = { \ + static const struct ubx_m10_config ubx_m10_cfg_##inst = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .uart_baudrate = DT_PROP(DT_DRV_INST(inst), uart_baudrate), \ }; \ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b337ccba18b1eb..e6aac9e04ceb5f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -17,6 +17,7 @@ source "subsys/logging/Kconfig.template.log_config" config GPIO_SHELL bool "GPIO Shell" depends on SHELL + imply DEVICE_DT_METADATA help Enable GPIO Shell for testing. diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index dc3e5317d4d62e..1025f1eaa7ab08 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_SOC_GECKO_DEV_INIT @@ -63,9 +64,8 @@ #define GECKO_GPIO_MODEH(pin, mode) (mode << ((pin - 8) * 4)) -#define member_size(type, member) sizeof(((type *)0)->member) -#define NUMBER_OF_PORTS (member_size(GPIO_TypeDef, P) / \ - member_size(GPIO_TypeDef, P[0])) +#define NUMBER_OF_PORTS (SIZEOF_FIELD(GPIO_TypeDef, P) / \ + SIZEOF_FIELD(GPIO_TypeDef, P[0])) struct gpio_gecko_common_config { }; diff --git a/drivers/gpio/gpio_pcal64xxa.c b/drivers/gpio/gpio_pcal64xxa.c index 687cf53c1bf262..93cc4814993e58 100644 --- a/drivers/gpio/gpio_pcal64xxa.c +++ b/drivers/gpio/gpio_pcal64xxa.c @@ -204,6 +204,7 @@ static int pcal64xxa_process_input(const struct device *dev, gpio_port_value_t * if (rc != 0) { LOG_ERR("failed to read inputs from device %s", dev->name); + k_sem_give(&drv_data->lock); return rc; } diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index 7bb6b9c58cd863..1460eadafb033c 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -134,16 +134,43 @@ DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_PIN_GET) static const struct gpio_ctrl gpio_list[] = {DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_LIST)}; -static const struct gpio_ctrl *get_gpio_ctrl(char *name) +static const struct gpio_ctrl *get_gpio_ctrl_helper(const struct device *dev) { - const struct device *dev = device_get_binding(name); size_t i; + if (dev == NULL) { + return NULL; + } + for (i = 0; i < ARRAY_SIZE(gpio_list); i++) { if (gpio_list[i].dev == dev) { return &gpio_list[i]; } } + + return NULL; +} + +/* Look up a device by some human-readable string identifier. We + * always search among device names. If the feature is available, we + * search by node label as well. + */ +static const struct gpio_ctrl *get_gpio_ctrl(char *id) +{ + const struct gpio_ctrl *ctrl; + + ctrl = get_gpio_ctrl_helper(device_get_binding(id)); + if (ctrl != NULL) { + return ctrl; + } + +#ifdef CONFIG_DEVICE_DT_METADATA + ctrl = get_gpio_ctrl_helper(device_get_by_dt_nodelabel(id)); + if (ctrl != NULL) { + return ctrl; + } +#endif /* CONFIG_DEVICE_DT_METADATA */ + return NULL; } @@ -401,6 +428,35 @@ static int cmd_gpio_toggle(const struct shell *sh, size_t argc, char **argv) return 0; } +static int cmd_gpio_devices(const struct shell *sh, size_t argc, char **argv) +{ + size_t i; + + shell_fprintf(sh, SHELL_NORMAL, "%-16s Other names\n", "Device"); + + for (i = 0; i < ARRAY_SIZE(gpio_list); i++) { + const struct device *dev = gpio_list[i].dev; + + shell_fprintf(sh, SHELL_NORMAL, "%-16s", dev->name); + +#ifdef CONFIG_DEVICE_DT_METADATA + const struct device_dt_nodelabels *nl = device_get_dt_nodelabels(dev); + + if (nl->num_nodelabels > 0) { + for (size_t j = 0; j < nl->num_nodelabels; j++) { + const char *nodelabel = nl->nodelabels[j]; + + shell_fprintf(sh, SHELL_NORMAL, " %s", nodelabel); + } + } +#endif + + shell_fprintf(sh, SHELL_NORMAL, "\n"); + } + + return 0; +} + /* 500 msec = 1/2 sec */ #define SLEEP_TIME_MS 500 @@ -618,6 +674,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_gpio, SHELL_COND_CMD_ARG(CONFIG_GPIO_SHELL_TOGGLE_CMD, toggle, &sub_gpio_dev, "Toggle GPIO pin\n" "Usage: gpio toggle ", cmd_gpio_toggle, 3, 0), + SHELL_CMD(devices, NULL, + "List all GPIO devices\n" + "Usage: gpio devices", cmd_gpio_devices), SHELL_COND_CMD_ARG(CONFIG_GPIO_SHELL_BLINK_CMD, blink, &sub_gpio_dev, "Blink GPIO pin\n" "Usage: gpio blink ", cmd_gpio_blink, 3, 0), diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index d835c3454ccb8e..4c147ff486ce37 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -22,11 +22,17 @@ #include #include #include +#include +#include #include "stm32_hsem.h" #include "gpio_stm32.h" #include +#include + +LOG_MODULE_REGISTER(stm32, CONFIG_GPIO_LOG_LEVEL); + /** * @brief Common GPIO driver for STM32 MCUs. */ @@ -270,7 +276,7 @@ static void gpio_stm32_configure_raw(const struct device *dev, int pin, static int gpio_stm32_clock_request(const struct device *dev, bool on) { const struct gpio_stm32_config *cfg = dev->config; - int ret = 0; + int ret; __ASSERT_NO_MSG(dev != NULL); @@ -285,10 +291,6 @@ static int gpio_stm32_clock_request(const struct device *dev, bool on) (clock_control_subsys_t)&cfg->pclken); } - if (ret != 0) { - return ret; - } - return ret; } @@ -299,11 +301,16 @@ static inline uint32_t gpio_stm32_pin_to_exti_line(int pin) return ((pin % 4 * 4) << 16) | (pin / 4); #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) return ((pin & 0x3) << (16 + 3)) | (pin >> 2); +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti) + /* Gives the LL_SBS_EXTI_LINEn corresponding to the pin */ + return (((pin % 4 * 4) << LL_SBS_REGISTER_PINPOS_SHFT) | (pin / 4)); #else return (0xF << ((pin % 4 * 4) + 16)) | (pin / 4); #endif } + +/* Set the EXTI line corresponding to the PORT [STM32_PORTA .. ] and pin [0..15] */ static void gpio_stm32_set_exti_source(int port, int pin) { uint32_t line = gpio_stm32_pin_to_exti_line(pin); @@ -326,12 +333,15 @@ static void gpio_stm32_set_exti_source(int port, int pin) #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) LL_EXTI_SetEXTISource(port, line); +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti) + LL_SBS_SetEXTISource(port, line); #else LL_SYSCFG_SetEXTISource(port, line); #endif z_stm32_hsem_unlock(CFG_HW_EXTI_SEMID); } +/* Gives the PORT [STM32_PORTA .. ] corresponding to the EXTI line of the pin [0..15] */ static int gpio_stm32_get_exti_source(int pin) { uint32_t line = gpio_stm32_pin_to_exti_line(pin); @@ -341,6 +351,8 @@ static int gpio_stm32_get_exti_source(int pin) port = LL_GPIO_AF_GetEXTISource(line); #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) port = LL_EXTI_GetEXTISource(line); +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti) + port = LL_SBS_GetEXTISource(line); #else port = LL_SYSCFG_GetEXTISource(line); #endif @@ -369,14 +381,18 @@ static int gpio_stm32_enable_int(int port, int pin) defined(CONFIG_SOC_SERIES_STM32F4X) || \ defined(CONFIG_SOC_SERIES_STM32F7X) || \ defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32H7RSX) || \ defined(CONFIG_SOC_SERIES_STM32L1X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32G4X) const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); struct stm32_pclken pclken = { -#ifdef CONFIG_SOC_SERIES_STM32H7X +#if defined(CONFIG_SOC_SERIES_STM32H7X) .bus = STM32_CLOCK_BUS_APB4, .enr = LL_APB4_GRP1_PERIPH_SYSCFG +#elif defined(CONFIG_SOC_SERIES_STM32H7RSX) + .bus = STM32_CLOCK_BUS_APB4, + .enr = LL_APB4_GRP1_PERIPH_SBS #else .bus = STM32_CLOCK_BUS_APB2, .enr = LL_APB2_GRP1_PERIPH_SYSCFG @@ -541,6 +557,25 @@ static int gpio_stm32_config(const struct device *dev, gpio_stm32_configure_raw(dev, pin, pincfg, 0); +#ifdef CONFIG_STM32_WKUP_PINS + if (flags & STM32_GPIO_WKUP) { +#ifdef CONFIG_POWEROFF + struct gpio_dt_spec gpio_dt_cfg = { + .port = dev, + .pin = pin, + .dt_flags = (gpio_dt_flags_t)flags, + }; + + if (stm32_pwr_wkup_pin_cfg_gpio((const struct gpio_dt_spec *)&gpio_dt_cfg)) { + LOG_ERR("Could not configure GPIO %s pin %d as a wake-up source", + gpio_dt_cfg.port->name, gpio_dt_cfg.pin); + } +#else + LOG_DBG("STM32_GPIO_WKUP flag has no effect when CONFIG_POWEROFF=n"); +#endif /* CONFIG_POWEROFF */ + } +#endif /* CONFIG_STM32_WKUP_PINS */ + /* Release clock only if pin is disconnected */ if (((flags & GPIO_OUTPUT) == 0) && ((flags & GPIO_INPUT) == 0)) { err = pm_device_runtime_put(dev); @@ -760,46 +795,24 @@ static int gpio_stm32_init(const struct device *dev) DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bits),\ DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bus)) -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) -GPIO_DEVICE_INIT_STM32(a, A); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) -GPIO_DEVICE_INIT_STM32(b, B); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioc), okay) -GPIO_DEVICE_INIT_STM32(c, C); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioc), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiod), okay) -GPIO_DEVICE_INIT_STM32(d, D); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiod), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioe), okay) -GPIO_DEVICE_INIT_STM32(e, E); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioe), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiof), okay) -GPIO_DEVICE_INIT_STM32(f, F); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiof), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiog), okay) -GPIO_DEVICE_INIT_STM32(g, G); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiog), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioh), okay) -GPIO_DEVICE_INIT_STM32(h, H); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioh), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioi), okay) -GPIO_DEVICE_INIT_STM32(i, I); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioi), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioj), okay) -GPIO_DEVICE_INIT_STM32(j, J); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioj), okay) */ - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiok), okay) -GPIO_DEVICE_INIT_STM32(k, K); -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiok), okay) */ +#define GPIO_DEVICE_INIT_STM32_IF_OKAY(__suffix, __SUFFIX) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_NODELABEL(gpio##__suffix), okay), \ + (GPIO_DEVICE_INIT_STM32(__suffix, __SUFFIX)), \ + ()) + +GPIO_DEVICE_INIT_STM32_IF_OKAY(a, A); +GPIO_DEVICE_INIT_STM32_IF_OKAY(b, B); +GPIO_DEVICE_INIT_STM32_IF_OKAY(c, C); +GPIO_DEVICE_INIT_STM32_IF_OKAY(d, D); +GPIO_DEVICE_INIT_STM32_IF_OKAY(e, E); +GPIO_DEVICE_INIT_STM32_IF_OKAY(f, F); +GPIO_DEVICE_INIT_STM32_IF_OKAY(g, G); +GPIO_DEVICE_INIT_STM32_IF_OKAY(h, H); +GPIO_DEVICE_INIT_STM32_IF_OKAY(i, I); +GPIO_DEVICE_INIT_STM32_IF_OKAY(j, J); +GPIO_DEVICE_INIT_STM32_IF_OKAY(k, K); + +GPIO_DEVICE_INIT_STM32_IF_OKAY(m, M); +GPIO_DEVICE_INIT_STM32_IF_OKAY(n, N); +GPIO_DEVICE_INIT_STM32_IF_OKAY(o, O); +GPIO_DEVICE_INIT_STM32_IF_OKAY(p, P); diff --git a/drivers/gpio/gpio_stm32.h b/drivers/gpio/gpio_stm32.h index 5e9da057ea95a9..9aa83a546e9729 100644 --- a/drivers/gpio/gpio_stm32.h +++ b/drivers/gpio/gpio_stm32.h @@ -100,6 +100,20 @@ #define STM32_PERIPH_GPIOI LL_AHB4_GRP1_PERIPH_GPIOI #define STM32_PERIPH_GPIOJ LL_AHB4_GRP1_PERIPH_GPIOJ #define STM32_PERIPH_GPIOK LL_AHB4_GRP1_PERIPH_GPIOK +#elif CONFIG_SOC_SERIES_STM32H7RSX +#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB4 +#define STM32_PERIPH_GPIOA LL_AHB4_GRP1_PERIPH_GPIOA +#define STM32_PERIPH_GPIOB LL_AHB4_GRP1_PERIPH_GPIOB +#define STM32_PERIPH_GPIOC LL_AHB4_GRP1_PERIPH_GPIOC +#define STM32_PERIPH_GPIOD LL_AHB4_GRP1_PERIPH_GPIOD +#define STM32_PERIPH_GPIOE LL_AHB4_GRP1_PERIPH_GPIOE +#define STM32_PERIPH_GPIOF LL_AHB4_GRP1_PERIPH_GPIOF +#define STM32_PERIPH_GPIOG LL_AHB4_GRP1_PERIPH_GPIOG +#define STM32_PERIPH_GPIOH LL_AHB4_GRP1_PERIPH_GPIOH +#define STM32_PERIPH_GPIOM LL_AHB4_GRP1_PERIPH_GPIOM +#define STM32_PERIPH_GPION LL_AHB4_GRP1_PERIPH_GPION +#define STM32_PERIPH_GPIOO LL_AHB4_GRP1_PERIPH_GPIOO +#define STM32_PERIPH_GPIOP LL_AHB4_GRP1_PERIPH_GPIOP #elif CONFIG_SOC_SERIES_STM32G0X #define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_IOP #define STM32_PERIPH_GPIOA LL_IOP_GRP1_PERIPH_GPIOA diff --git a/drivers/hwinfo/CMakeLists.txt b/drivers/hwinfo/CMakeLists.txt index 60707d59a6199c..6730e60491f0ad 100644 --- a/drivers/hwinfo/CMakeLists.txt +++ b/drivers/hwinfo/CMakeLists.txt @@ -8,6 +8,9 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE hwinfo_handlers.c) zephyr_library_sources_ifdef(CONFIG_HWINFO hwinfo_weak_impl.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SHELL hwinfo_shell.c) +# zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_HWINFO_AMBIQ hwinfo_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_ANDES hwinfo_andes.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_CC13XX_CC26XX hwinfo_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_ESP32 hwinfo_esp32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_GECKO hwinfo_gecko.c) @@ -21,12 +24,11 @@ zephyr_library_sources_ifdef(CONFIG_HWINFO_MCUX_SYSCON hwinfo_mcux_syscon.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_NRF hwinfo_nrf.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_PSOC6 hwinfo_psoc6.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_RPI_PICO hwinfo_rpi_pico.c) -zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM_RSTC hwinfo_sam_rstc.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_RW61X hwinfo_rw61x.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM hwinfo_sam.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM0 hwinfo_sam0.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM4L hwinfo_sam4l.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM_RSTC hwinfo_sam_rstc.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SMARTBOND hwinfo_smartbond.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c) -zephyr_library_sources_ifdef(CONFIG_HWINFO_ANDES hwinfo_andes.c) -zephyr_library_sources_ifdef(CONFIG_HWINFO_RW61X hwinfo_rw61x.c) -zephyr_library_sources_ifdef(CONFIG_HWINFO_AMBIQ hwinfo_ambiq.c) +# zephyr-keep-sorted-stop diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 0d3f6b991f9869..0352215a97e962 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -180,7 +180,9 @@ config HWINFO_PSOC6 config HWINFO_GECKO bool "GECKO hwinfo" default y - depends on SOC_VENDOR_SILABS && !SOC_SERIES_EFR32MG21 && !SOC_SERIES_EFR32BG22 + depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 + depends on !SOC_SERIES_EFR32MG21 + depends on !SOC_SERIES_EFR32BG22 select SOC_GECKO_RMU help Enable Silabs GECKO hwinfo driver. diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt index 16fa2b450d1fde..aa46769ed850b1 100644 --- a/drivers/i2c/CMakeLists.txt +++ b/drivers/i2c/CMakeLists.txt @@ -79,6 +79,7 @@ zephyr_library_sources_ifdef(CONFIG_I2C_AMBIQ i2c_ambiq.c) zephyr_library_sources_ifdef(CONFIG_I2C_ENE_KB1200 i2c_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_GPIO_I2C_SWITCH gpio_i2c_switch.c) zephyr_library_sources_ifdef(CONFIG_I2C_NUMAKER i2c_numaker.c) +zephyr_library_sources_ifdef(CONFIG_I2C_MAX32 i2c_max32.c) zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V1 i2c_ll_stm32_v1.c diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index f5dacfe8ea4cad..2002813da526a0 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -128,6 +128,7 @@ source "drivers/i2c/Kconfig.ambiq" source "drivers/i2c/Kconfig.numaker" source "drivers/i2c/Kconfig.mcux" source "drivers/i2c/Kconfig.ene" +source "drivers/i2c/Kconfig.max32" config I2C_INIT_PRIORITY int "Init priority" diff --git a/drivers/i2c/Kconfig.max32 b/drivers/i2c/Kconfig.max32 new file mode 100644 index 00000000000000..b41f5ec862077c --- /dev/null +++ b/drivers/i2c/Kconfig.max32 @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig I2C_MAX32 + bool "Analog Devices MAX32 I2C driver" + default y + depends on DT_HAS_ADI_MAX32_I2C_ENABLED + help + i2c driver for max32 family. + +if I2C_MAX32 + +config I2C_MAX32_INTERRUPT + bool "Interrupt support for MAX32 I2C driver" + default y + help + Enable interrupt support for MAX32 I2C controller mode + transfers. + +endif # I2C_MAX32 diff --git a/drivers/i2c/Kconfig.stm32 b/drivers/i2c/Kconfig.stm32 index e6e98df33a083c..274cecac8cb18a 100644 --- a/drivers/i2c/Kconfig.stm32 +++ b/drivers/i2c/Kconfig.stm32 @@ -50,4 +50,10 @@ config I2C_STM32_BUS_RECOVERY help Enable STM32 driver bus recovery support via GPIO bitbanging. +config I2C_STM32_V2_TIMING + bool "compute the I2C V2 bus timing" + depends on I2C_STM32_V2 + help + Enable STM32 driver bus to calculate the Timing. + endif # I2C_STM32 diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 29f5a5ae08fe50..15eb4558d79c44 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -56,6 +56,26 @@ int i2c_stm32_get_config(const struct device *dev, uint32_t *config) *config = data->dev_config; +#if CONFIG_I2C_STM32_V2_TIMING + /* Print the timing parameter of device data */ + LOG_INF("I2C timing value, report to the DTS :"); + + /* I2C BIT RATE */ + if (data->current_timing.i2c_speed == 100000) { + LOG_INF("timings = <%d I2C_BITRATE_STANDARD 0x%X>;", + data->current_timing.periph_clock, + data->current_timing.timing_setting); + } else if (data->current_timing.i2c_speed == 400000) { + LOG_INF("timings = <%d I2C_BITRATE_FAST 0x%X>;", + data->current_timing.periph_clock, + data->current_timing.timing_setting); + } else if (data->current_timing.i2c_speed == 1000000) { + LOG_INF("timings = <%d I2C_SPEED_FAST_PLUS 0x%X>;", + data->current_timing.periph_clock, + data->current_timing.timing_setting); + } +#endif /* CONFIG_I2C_STM32_V2_TIMING */ + return 0; } diff --git a/drivers/i2c/i2c_ll_stm32.h b/drivers/i2c/i2c_ll_stm32.h index 0a9dc1be350a6a..ec6db5b32a0834 100644 --- a/drivers/i2c/i2c_ll_stm32.h +++ b/drivers/i2c/i2c_ll_stm32.h @@ -56,6 +56,10 @@ struct i2c_stm32_data { #endif struct k_sem bus_mutex; uint32_t dev_config; +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) + /* Store the current timing structure set by runtime config */ + struct i2c_config_timing current_timing; +#endif #ifdef CONFIG_I2C_STM32_V1 uint16_t slave_address; #endif diff --git a/drivers/i2c/i2c_ll_stm32_v2.c b/drivers/i2c/i2c_ll_stm32_v2.c index a685ebebeb7867..24d51eed45ea7c 100644 --- a/drivers/i2c/i2c_ll_stm32_v2.c +++ b/drivers/i2c/i2c_ll_stm32_v2.c @@ -29,6 +29,94 @@ LOG_MODULE_REGISTER(i2c_ll_stm32_v2); #define STM32_I2C_TRANSFER_TIMEOUT_MSEC 500 +#ifdef CONFIG_I2C_STM32_V2_TIMING +/* Use the algorithm to calcuate the I2C timing */ +#ifndef STM32_I2C_VALID_TIMING_NBR +#define STM32_I2C_VALID_TIMING_NBR 128U +#endif +#define STM32_I2C_SPEED_FREQ_STANDARD 0U /* 100 kHz */ +#define STM32_I2C_SPEED_FREQ_FAST 1U /* 400 kHz */ +#define STM32_I2C_SPEED_FREQ_FAST_PLUS 2U /* 1 MHz */ +#define STM32_I2C_ANALOG_FILTER_DELAY_MIN 50U /* ns */ +#define STM32_I2C_ANALOG_FILTER_DELAY_MAX 260U /* ns */ +#define STM32_I2C_USE_ANALOG_FILTER 1U +#define STM32_I2C_DIGITAL_FILTER_COEF 0U +#define STM32_I2C_PRESC_MAX 16U +#define STM32_I2C_SCLDEL_MAX 16U +#define STM32_I2C_SDADEL_MAX 16U +#define STM32_I2C_SCLH_MAX 256U +#define STM32_I2C_SCLL_MAX 256U + +/* I2C_DEVICE_Private_Types */ +struct stm32_i2c_charac_t { + uint32_t freq; /* Frequency in Hz */ + uint32_t freq_min; /* Minimum frequency in Hz */ + uint32_t freq_max; /* Maximum frequency in Hz */ + uint32_t hddat_min; /* Minimum data hold time in ns */ + uint32_t vddat_max; /* Maximum data valid time in ns */ + uint32_t sudat_min; /* Minimum data setup time in ns */ + uint32_t lscl_min; /* Minimum low period of the SCL clock in ns */ + uint32_t hscl_min; /* Minimum high period of SCL clock in ns */ + uint32_t trise; /* Rise time in ns */ + uint32_t tfall; /* Fall time in ns */ + uint32_t dnf; /* Digital noise filter coefficient */ +}; + +struct stm32_i2c_timings_t { + uint32_t presc; /* Timing prescaler */ + uint32_t tscldel; /* SCL delay */ + uint32_t tsdadel; /* SDA delay */ + uint32_t sclh; /* SCL high period */ + uint32_t scll; /* SCL low period */ +}; + +/* I2C_DEVICE Private Constants */ +static const struct stm32_i2c_charac_t stm32_i2c_charac[] = { + [STM32_I2C_SPEED_FREQ_STANDARD] = { + .freq = 100000, + .freq_min = 80000, + .freq_max = 120000, + .hddat_min = 0, + .vddat_max = 3450, + .sudat_min = 250, + .lscl_min = 4700, + .hscl_min = 4000, + .trise = 640, + .tfall = 20, + .dnf = STM32_I2C_DIGITAL_FILTER_COEF, + }, + [STM32_I2C_SPEED_FREQ_FAST] = { + .freq = 400000, + .freq_min = 320000, + .freq_max = 480000, + .hddat_min = 0, + .vddat_max = 900, + .sudat_min = 100, + .lscl_min = 1300, + .hscl_min = 600, + .trise = 250, + .tfall = 100, + .dnf = STM32_I2C_DIGITAL_FILTER_COEF, + }, + [STM32_I2C_SPEED_FREQ_FAST_PLUS] = { + .freq = 1000000, + .freq_min = 800000, + .freq_max = 1200000, + .hddat_min = 0, + .vddat_max = 450, + .sudat_min = 50, + .lscl_min = 500, + .hscl_min = 260, + .trise = 60, + .tfall = 100, + .dnf = STM32_I2C_DIGITAL_FILTER_COEF, + }, +}; + +static struct stm32_i2c_timings_t i2c_valid_timing[STM32_I2C_VALID_TIMING_NBR]; +static uint32_t i2c_valid_timing_nbr; +#endif /* CONFIG_I2C_STM32_V2_TIMING */ + static inline void msg_init(const struct device *dev, struct i2c_msg *msg, uint8_t *next_msg_flags, uint16_t slave, uint32_t transfer) @@ -725,6 +813,240 @@ static int stm32_i2c_msg_read(const struct device *dev, struct i2c_msg *msg, } #endif +#ifdef CONFIG_I2C_STM32_V2_TIMING +/* + * Macro used to fix the compliance check warning : + * "DEEP_INDENTATION: Too many leading tabs - consider code refactoring + * in the i2c_compute_scll_sclh() function below + */ +#define I2C_LOOP_SCLH(); \ + if ((tscl >= clk_min) && \ + (tscl <= clk_max) && \ + (tscl_h >= stm32_i2c_charac[i2c_speed].hscl_min) && \ + (ti2cclk < tscl_h)) { \ + \ + int32_t error = (int32_t)tscl - (int32_t)ti2cspeed; \ + \ + if (error < 0) { \ + error = -error; \ + } \ + \ + if ((uint32_t)error < prev_error) { \ + prev_error = (uint32_t)error; \ + i2c_valid_timing[count].scll = scll; \ + i2c_valid_timing[count].sclh = sclh; \ + ret = count; \ + } \ + } + +/* + * @brief Calculate SCLL and SCLH and find best configuration. + * @param clock_src_freq I2C source clock in Hz. + * @param i2c_speed I2C frequency (index). + * @retval config index (0 to I2C_VALID_TIMING_NBR], 0xFFFFFFFF for no valid config. + */ +uint32_t i2c_compute_scll_sclh(uint32_t clock_src_freq, uint32_t i2c_speed) +{ + uint32_t ret = 0xFFFFFFFFU; + uint32_t ti2cclk; + uint32_t ti2cspeed; + uint32_t prev_error; + uint32_t dnf_delay; + uint32_t clk_min, clk_max; + uint32_t scll, sclh; + uint32_t tafdel_min; + + ti2cclk = (NSEC_PER_SEC + (clock_src_freq / 2U)) / clock_src_freq; + ti2cspeed = (NSEC_PER_SEC + (stm32_i2c_charac[i2c_speed].freq / 2U)) / + stm32_i2c_charac[i2c_speed].freq; + + tafdel_min = (STM32_I2C_USE_ANALOG_FILTER == 1U) ? + STM32_I2C_ANALOG_FILTER_DELAY_MIN : + 0U; + + /* tDNF = DNF x tI2CCLK */ + dnf_delay = stm32_i2c_charac[i2c_speed].dnf * ti2cclk; + + clk_max = NSEC_PER_SEC / stm32_i2c_charac[i2c_speed].freq_min; + clk_min = NSEC_PER_SEC / stm32_i2c_charac[i2c_speed].freq_max; + + prev_error = ti2cspeed; + + for (uint32_t count = 0; count < STM32_I2C_VALID_TIMING_NBR; count++) { + /* tPRESC = (PRESC+1) x tI2CCLK*/ + uint32_t tpresc = (i2c_valid_timing[count].presc + 1U) * ti2cclk; + + for (scll = 0; scll < STM32_I2C_SCLL_MAX; scll++) { + /* tLOW(min) <= tAF(min) + tDNF + 2 x tI2CCLK + [(SCLL+1) x tPRESC ] */ + uint32_t tscl_l = tafdel_min + dnf_delay + + (2U * ti2cclk) + ((scll + 1U) * tpresc); + + /* + * The I2CCLK period tI2CCLK must respect the following conditions: + * tI2CCLK < (tLOW - tfilters) / 4 and tI2CCLK < tHIGH + */ + if ((tscl_l > stm32_i2c_charac[i2c_speed].lscl_min) && + (ti2cclk < ((tscl_l - tafdel_min - dnf_delay) / 4U))) { + for (sclh = 0; sclh < STM32_I2C_SCLH_MAX; sclh++) { + /* + * tHIGH(min) <= tAF(min) + tDNF + + * 2 x tI2CCLK + [(SCLH+1) x tPRESC] + */ + uint32_t tscl_h = tafdel_min + dnf_delay + + (2U * ti2cclk) + ((sclh + 1U) * tpresc); + + /* tSCL = tf + tLOW + tr + tHIGH */ + uint32_t tscl = tscl_l + + tscl_h + stm32_i2c_charac[i2c_speed].trise + + stm32_i2c_charac[i2c_speed].tfall; + + /* get timings with the lowest clock error */ + I2C_LOOP_SCLH(); + } + } + } + } + + return ret; +} + +/* + * Macro used to fix the compliance check warning : + * "DEEP_INDENTATION: Too many leading tabs - consider code refactoring + * in the i2c_compute_presc_scldel_sdadel() function below + */ +#define I2C_LOOP_SDADEL(); \ + \ + if ((tsdadel >= (uint32_t)tsdadel_min) && \ + (tsdadel <= (uint32_t)tsdadel_max)) { \ + if (presc != prev_presc) { \ + i2c_valid_timing[i2c_valid_timing_nbr].presc = presc; \ + i2c_valid_timing[i2c_valid_timing_nbr].tscldel = scldel; \ + i2c_valid_timing[i2c_valid_timing_nbr].tsdadel = sdadel; \ + prev_presc = presc; \ + i2c_valid_timing_nbr++; \ + \ + if (i2c_valid_timing_nbr >= STM32_I2C_VALID_TIMING_NBR) { \ + break; \ + } \ + } \ + } + +/* + * @brief Compute PRESC, SCLDEL and SDADEL. + * @param clock_src_freq I2C source clock in Hz. + * @param i2c_speed I2C frequency (index). + * @retval None. + */ +void i2c_compute_presc_scldel_sdadel(uint32_t clock_src_freq, uint32_t i2c_speed) +{ + uint32_t prev_presc = STM32_I2C_PRESC_MAX; + uint32_t ti2cclk; + int32_t tsdadel_min, tsdadel_max; + int32_t tscldel_min; + uint32_t presc, scldel, sdadel; + uint32_t tafdel_min, tafdel_max; + + ti2cclk = (NSEC_PER_SEC + (clock_src_freq / 2U)) / clock_src_freq; + + tafdel_min = (STM32_I2C_USE_ANALOG_FILTER == 1U) ? + STM32_I2C_ANALOG_FILTER_DELAY_MIN : 0U; + tafdel_max = (STM32_I2C_USE_ANALOG_FILTER == 1U) ? + STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0U; + /* + * tDNF = DNF x tI2CCLK + * tPRESC = (PRESC+1) x tI2CCLK + * SDADEL >= {tf +tHD;DAT(min) - tAF(min) - tDNF - [3 x tI2CCLK]} / {tPRESC} + * SDADEL <= {tVD;DAT(max) - tr - tAF(max) - tDNF- [4 x tI2CCLK]} / {tPRESC} + */ + tsdadel_min = (int32_t)stm32_i2c_charac[i2c_speed].tfall + + (int32_t)stm32_i2c_charac[i2c_speed].hddat_min - + (int32_t)tafdel_min - + (int32_t)(((int32_t)stm32_i2c_charac[i2c_speed].dnf + 3) * + (int32_t)ti2cclk); + + tsdadel_max = (int32_t)stm32_i2c_charac[i2c_speed].vddat_max - + (int32_t)stm32_i2c_charac[i2c_speed].trise - + (int32_t)tafdel_max - + (int32_t)(((int32_t)stm32_i2c_charac[i2c_speed].dnf + 4) * + (int32_t)ti2cclk); + + /* {[tr+ tSU;DAT(min)] / [tPRESC]} - 1 <= SCLDEL */ + tscldel_min = (int32_t)stm32_i2c_charac[i2c_speed].trise + + (int32_t)stm32_i2c_charac[i2c_speed].sudat_min; + + if (tsdadel_min <= 0) { + tsdadel_min = 0; + } + + if (tsdadel_max <= 0) { + tsdadel_max = 0; + } + + for (presc = 0; presc < STM32_I2C_PRESC_MAX; presc++) { + for (scldel = 0; scldel < STM32_I2C_SCLDEL_MAX; scldel++) { + /* TSCLDEL = (SCLDEL+1) * (PRESC+1) * TI2CCLK */ + uint32_t tscldel = (scldel + 1U) * (presc + 1U) * ti2cclk; + + if (tscldel >= (uint32_t)tscldel_min) { + for (sdadel = 0; sdadel < STM32_I2C_SDADEL_MAX; sdadel++) { + /* TSDADEL = SDADEL * (PRESC+1) * TI2CCLK */ + uint32_t tsdadel = (sdadel * (presc + 1U)) * ti2cclk; + + I2C_LOOP_SDADEL(); + } + + if (i2c_valid_timing_nbr >= STM32_I2C_VALID_TIMING_NBR) { + return; + } + } + } + } +} + +int stm32_i2c_configure_timing(const struct device *dev, uint32_t clock) +{ + const struct i2c_stm32_config *cfg = dev->config; + struct i2c_stm32_data *data = dev->data; + I2C_TypeDef *i2c = cfg->i2c; + uint32_t timing = 0U; + uint32_t idx; + uint32_t speed = 0U; + uint32_t i2c_freq = cfg->bitrate; + + /* Reset valid timing count at the beginning of each new computation */ + i2c_valid_timing_nbr = 0; + + if ((clock != 0U) && (i2c_freq != 0U)) { + for (speed = 0 ; speed <= (uint32_t)STM32_I2C_SPEED_FREQ_FAST_PLUS ; speed++) { + if ((i2c_freq >= stm32_i2c_charac[speed].freq_min) && + (i2c_freq <= stm32_i2c_charac[speed].freq_max)) { + i2c_compute_presc_scldel_sdadel(clock, speed); + idx = i2c_compute_scll_sclh(clock, speed); + if (idx < STM32_I2C_VALID_TIMING_NBR) { + timing = ((i2c_valid_timing[idx].presc & + 0x0FU) << 28) | + ((i2c_valid_timing[idx].tscldel & 0x0FU) << 20) | + ((i2c_valid_timing[idx].tsdadel & 0x0FU) << 16) | + ((i2c_valid_timing[idx].sclh & 0xFFU) << 8) | + ((i2c_valid_timing[idx].scll & 0xFFU) << 0); + } + break; + } + } + } + + /* Fill the current timing value in data structure at runtime */ + data->current_timing.periph_clock = clock; + data->current_timing.i2c_speed = i2c_freq; + data->current_timing.timing_setting = timing; + + LL_I2C_SetTiming(i2c, timing); + + return 0; +} +#else/* CONFIG_I2C_STM32_V2_TIMING */ + int stm32_i2c_configure_timing(const struct device *dev, uint32_t clock) { const struct i2c_stm32_config *cfg = dev->config; @@ -797,10 +1119,12 @@ int stm32_i2c_configure_timing(const struct device *dev, uint32_t clock) return -EINVAL; } + LOG_INF("I2C TIMING = 0x%x\n", timing); LL_I2C_SetTiming(i2c, timing); return 0; } +#endif /* CONFIG_I2C_STM32_V2_TIMING */ int stm32_i2c_transaction(const struct device *dev, struct i2c_msg msg, uint8_t *next_msg_flags, diff --git a/drivers/i2c/i2c_max32.c b/drivers/i2c/i2c_max32.c new file mode 100644 index 00000000000000..8783e6d7e4863b --- /dev/null +++ b/drivers/i2c/i2c_max32.c @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max32_i2c + +#include +#include +#include +#include +#include + +#include + +#define ADI_MAX32_I2C_INT_FL0_MASK 0x00FFFFFF +#define ADI_MAX32_I2C_INT_FL1_MASK 0x7 + +#define ADI_MAX32_I2C_STATUS_MASTER_BUSY BIT(5) + +#define I2C_RECOVER_MAX_RETRIES 3 + +/* Driver config */ +struct max32_i2c_config { + mxc_i2c_regs_t *regs; + const struct pinctrl_dev_config *pctrl; + const struct device *clock; + struct max32_perclk perclk; + uint32_t bitrate; +#if defined(CONFIG_I2C_TARGET) || defined(CONFIG_I2C_MAX32_INTERRUPT) + uint8_t irqn; + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct max32_i2c_data { + mxc_i2c_req_t req; + const struct device *dev; + struct k_sem lock; + uint8_t target_mode; + uint8_t flags; +#ifdef CONFIG_I2C_TARGET + struct i2c_target_config *target_cfg; + bool first_write; +#endif /* CONFIG_I2C_TARGET */ + uint32_t readb; + uint32_t written; +#if defined(CONFIG_I2C_MAX32_INTERRUPT) + struct k_sem xfer; + int err; +#endif +}; + +static int api_configure(const struct device *dev, uint32_t dev_cfg) +{ + int ret = 0; + const struct max32_i2c_config *const cfg = dev->config; + mxc_i2c_regs_t *i2c = cfg->regs; + + switch (I2C_SPEED_GET(dev_cfg)) { + case I2C_SPEED_STANDARD: /** I2C Standard Speed: 100 kHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_STD_MODE); + break; + + case I2C_SPEED_FAST: /** I2C Fast Speed: 400 kHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_FAST_SPEED); + break; + +#if defined(MXC_I2C_FASTPLUS_SPEED) + case I2C_SPEED_FAST_PLUS: /** I2C Fast Plus Speed: 1 MHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_FASTPLUS_SPEED); + break; +#endif + +#if defined(MXC_I2C_HIGH_SPEED) + case I2C_SPEED_HIGH: /** I2C High Speed: 3.4 MHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_HIGH_SPEED); + break; +#endif + + default: + /* Speed not supported */ + return -ENOTSUP; + } + + return ret; +} + +#ifdef CONFIG_I2C_TARGET +static int api_target_register(const struct device *dev, struct i2c_target_config *cfg) +{ + const struct max32_i2c_config *config = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = config->regs; + int ret; + + data->target_cfg = cfg; + + ret = MXC_I2C_Init(i2c, 0, cfg->address); + if (ret == E_NO_ERROR) { + data->target_mode = 1; + irq_enable(config->irqn); + MXC_I2C_SlaveTransactionAsync(i2c, NULL); + } + + return ret == E_NO_ERROR ? 0 : E_FAIL; +} + +static int api_target_unregister(const struct device *dev, struct i2c_target_config *cfg) +{ + const struct max32_i2c_config *config = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = config->regs; + + data->target_cfg = NULL; + data->target_mode = 0; + +#ifndef CONFIG_I2C_MAX32_INTERRUPT + irq_disable(config->irqn); +#endif + + return MXC_I2C_Init(i2c, 1, 0); +} + +static int i2c_max32_target_callback(const struct device *dev, mxc_i2c_regs_t *i2c, + mxc_i2c_slave_event_t event) +{ + struct max32_i2c_data *data = dev->data; + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + static uint8_t rxval, txval, rxcnt; + + switch (event) { + case MXC_I2C_EVT_MASTER_WR: + if (data->first_write && target_cb->write_requested) { + target_cb->write_requested(data->target_cfg); + data->first_write = false; + } + break; + case MXC_I2C_EVT_MASTER_RD: + break; + case MXC_I2C_EVT_RX_THRESH: + case MXC_I2C_EVT_OVERFLOW: + rxcnt = MXC_I2C_GetRXFIFOAvailable(i2c); + if (target_cb->write_received) { + while (rxcnt--) { + MXC_I2C_ReadRXFIFO(i2c, &rxval, 1); + target_cb->write_received(data->target_cfg, rxval); + } + } else { + MXC_I2C_ClearRXFIFO(i2c); + } + break; + case MXC_I2C_EVT_TX_THRESH: + case MXC_I2C_EVT_UNDERFLOW: + if (target_cb->read_requested) { + target_cb->read_requested(data->target_cfg, &txval); + MXC_I2C_WriteTXFIFO(i2c, &txval, 1); + } + if (target_cb->read_processed) { + target_cb->read_processed(data->target_cfg, &txval); + } + break; + case MXC_I2C_EVT_TRANS_COMP: + if (target_cb->stop) { + target_cb->stop(data->target_cfg); + } + data->first_write = true; + break; + } + + return 0; +} +#endif /* CONFIG_I2C_TARGET */ + +static int api_recover_bus(const struct device *dev) +{ + int ret; + const struct max32_i2c_config *const cfg = dev->config; + mxc_i2c_regs_t *i2c = cfg->regs; + + ret = MXC_I2C_Recover(i2c, I2C_RECOVER_MAX_RETRIES); + + return ret; +} + +#ifndef CONFIG_I2C_MAX32_INTERRUPT +static int i2c_max32_transfer_sync(mxc_i2c_regs_t *i2c, struct max32_i2c_data *data) +{ + uint32_t int_fl0, int_fl1; + uint32_t readb = 0; + mxc_i2c_req_t *req = &data->req; + + /* Wait for acknowledge */ + if (data->flags & (I2C_MSG_RESTART | I2C_MSG_READ)) { + do { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + } while (!(int_fl0 & ADI_MAX32_I2C_INT_FL0_ADDR_ACK) && + !(int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR)); + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + return -EIO; + } + + while (req->tx_len > data->written) { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_TX_THD) { + data->written += MXC_I2C_WriteTXFIFO(i2c, &req->tx_buf[data->written], + req->tx_len - data->written); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_TX_THD, 0); + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + return -EIO; + } + } + + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_DONE, 0); + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len); + while (req->rx_len > readb) { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + if (int_fl0 & (ADI_MAX32_I2C_INT_FL0_RX_THD | ADI_MAX32_I2C_INT_FL0_DONE)) { + readb += MXC_I2C_ReadRXFIFO(i2c, &req->rx_buf[readb], req->rx_len - readb); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_RX_THD, 0); + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + return -EIO; + } + + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + if ((int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE) && (req->rx_len > readb) && + MXC_I2C_GetRXFIFOAvailable(i2c) == 0) { + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len - readb); + Wrap_MXC_I2C_Restart(i2c); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_DONE, 0); + i2c->fifo = (req->addr << 1) | 0x1; + } + } + + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + return -EIO; + } + + if (data->flags & I2C_MSG_STOP) { + MXC_I2C_Stop(i2c); + do { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + } while (!(int_fl0 & ADI_MAX32_I2C_INT_FL0_STOP)); + } + + if (req->rx_len) { + do { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + } while (!(int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE)); + } else { + while (Wrap_MXC_I2C_GetTxFIFOLevel(i2c) > 0) { + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + } + } + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + + return 0; +} +#endif /* CONFIG_I2C_MAX32_INTERRUPT */ + +#ifdef CONFIG_I2C_MAX32_INTERRUPT +static int i2c_max32_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t target_address) +{ + int ret = 0; + const struct max32_i2c_config *const cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + mxc_i2c_req_t *req = &data->req; + uint8_t target_rw; + unsigned int i = 0; + + req->i2c = i2c; + req->addr = target_address; + + k_sem_take(&data->lock, K_FOREVER); + + MXC_I2C_ClearRXFIFO(i2c); + MXC_I2C_ClearTXFIFO(i2c); + MXC_I2C_SetRXThreshold(i2c, 1); + + /* First message should always begin with a START condition */ + msgs[0].flags |= I2C_MSG_RESTART; + + for (i = 0; i < num_msgs; i++) { + if (msgs[i].flags & I2C_MSG_READ) { + req->rx_buf = (unsigned char *)msgs[i].buf; + req->rx_len = msgs[i].len; + req->tx_buf = NULL; + req->tx_len = 0; + target_rw = (target_address << 1) | 0x1; + } else { + req->tx_buf = (unsigned char *)msgs[i].buf; + req->tx_len = msgs[i].len; + req->rx_buf = NULL; + req->rx_len = 0; + target_rw = (target_address << 1) & ~0x1; + } + + /* + * If previous message ends with a STOP condition, this message + * should begin with a START + */ + if (i > 0) { + if ((msgs[i - 1].flags & (I2C_MSG_STOP | I2C_MSG_READ))) { + msgs[i].flags |= I2C_MSG_RESTART; + } + } + + data->flags = msgs[i].flags; + data->readb = 0; + data->written = 0; + data->err = 0; + + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ERR, 0); + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len); + if ((data->flags & I2C_MSG_RESTART)) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + MXC_I2C_Start(i2c); + Wrap_MXC_I2C_WaitForRestart(i2c); + MXC_I2C_WriteTXFIFO(i2c, &target_rw, 1); + } else { + if (req->tx_len) { + data->written = MXC_I2C_WriteTXFIFO(i2c, req->tx_buf, 1); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + } else { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_RX_THD, 0); + } + } + + ret = k_sem_take(&data->xfer, K_FOREVER); + if (data->err) { + MXC_I2C_Stop(i2c); + ret = data->err; + } else { + if (data->flags & I2C_MSG_STOP) { + /* Wait for busy flag to be cleared */ + while (i2c->status & ADI_MAX32_I2C_STATUS_MASTER_BUSY) { + } + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, + ADI_MAX32_I2C_INT_FL1_MASK); + } + } + if (ret) { + break; + } + } + + k_sem_give(&data->lock); + + return ret; +} +#else +static int i2c_max32_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t target_address) +{ + int ret = 0; + const struct max32_i2c_config *const cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + mxc_i2c_req_t *req = &data->req; + uint8_t target_rw; + unsigned int i = 0; + + req->i2c = i2c; + req->addr = target_address; + + k_sem_take(&data->lock, K_FOREVER); + + MXC_I2C_ClearRXFIFO(i2c); + + /* First message should always begin with a START condition */ + msgs[0].flags |= I2C_MSG_RESTART; + + for (i = 0; i < num_msgs; i++) { + if (msgs[i].flags & I2C_MSG_READ) { + req->rx_buf = (unsigned char *)msgs[i].buf; + req->rx_len = msgs[i].len; + req->tx_buf = NULL; + req->tx_len = 0; + target_rw = (target_address << 1) | 0x1; + } else { + req->tx_buf = (unsigned char *)msgs[i].buf; + req->tx_len = msgs[i].len; + req->rx_buf = NULL; + req->rx_len = 0; + target_rw = (target_address << 1) & ~0x1; + } + + /* + * If previous message ends with a STOP condition, this message + * should begin with a START + */ + if (i > 0) { + if ((msgs[i - 1].flags & (I2C_MSG_STOP | I2C_MSG_READ))) { + msgs[i].flags |= I2C_MSG_RESTART; + } + } + + data->flags = msgs[i].flags; + data->readb = 0; + data->written = 0; + + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + + Wrap_MXC_I2C_SetIntEn(i2c, 0, 0); + if (data->flags & I2C_MSG_RESTART) { + MXC_I2C_Start(i2c); + Wrap_MXC_I2C_WaitForRestart(i2c); + MXC_I2C_WriteTXFIFO(i2c, &target_rw, 1); + } + ret = i2c_max32_transfer_sync(i2c, data); + if (ret) { + MXC_I2C_Stop(i2c); + break; + } + } + + k_sem_give(&data->lock); + + return ret; +} +#endif /* CONFIG_I2C_MAX32_INTERRUPT */ + +static int api_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t target_address) +{ + return i2c_max32_transfer(dev, msgs, num_msgs, target_address); +} + +#ifdef CONFIG_I2C_TARGET +static void i2c_max32_isr_target(const struct device *dev, mxc_i2c_regs_t *i2c) +{ + uint32_t ctrl; + uint32_t int_fl0; + uint32_t int_fl1; + uint32_t int_en0; + uint32_t int_en1; + + ctrl = i2c->ctrl; + Wrap_MXC_I2C_GetIntEn(i2c, &int_en0, &int_en1); + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + /* Error occurred, notify callback function and end transaction */ + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_TRANS_COMP); + + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + MXC_I2C_ClearTXFIFO(i2c); + MXC_I2C_ClearRXFIFO(i2c); + } + + /* Check whether data is available if we received an interrupt occurred while receiving */ + if (int_en0 & ADI_MAX32_I2C_INT_EN0_RX_THD || int_en1 & ADI_MAX32_I2C_INT_EN1_RX_OVERFLOW) { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_RX_THD) { + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_RX_THRESH); + } + + if (int_fl1 & ADI_MAX32_I2C_INT_FL1_RX_OVERFLOW) { + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_OVERFLOW); + } + } + + /* Check whether TX FIFO needs to be refilled if interrupt ocurred while transmitting */ + if (int_en0 & (ADI_MAX32_I2C_INT_EN0_TX_THD | ADI_MAX32_I2C_INT_EN0_TX_LOCK_OUT) || + int_en1 & ADI_MAX32_I2C_INT_EN1_TX_UNDERFLOW) { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_TX_THD) { + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_TX_THRESH); + } + + if (int_fl1 & ADI_MAX32_I2C_INT_EN1_TX_UNDERFLOW) { + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_UNDERFLOW); + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_TX_LOCK_OUT) { + int_en0 = ADI_MAX32_I2C_INT_EN0_ADDR_MATCH; + int_en1 = 0; + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_TRANS_COMP); + } + } + + /* Check if transaction completed or restart occurred */ + if (int_en0 & ADI_MAX32_I2C_INT_EN0_DONE) { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_STOP) { + /* Stop/NACK condition occurred, transaction complete */ + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_TRANS_COMP); + int_en0 = ADI_MAX32_I2C_INT_EN0_ADDR_MATCH; + } else if (int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE) { + /* Restart detected, re-arm address match interrupt */ + int_en0 = ADI_MAX32_I2C_INT_EN0_ADDR_MATCH; + } + int_en1 = 0; + } + + /* Check for address match interrupt */ + if (int_en0 & ADI_MAX32_I2C_INT_EN0_ADDR_MATCH) { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ADDR_MATCH) { + /* Address match occurred, prepare for transaction */ + if (i2c->ctrl & MXC_F_I2C_CTRL_READ) { + /* Read request received from the master */ + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_MASTER_RD); + int_en0 = ADI_MAX32_I2C_INT_EN0_TX_THD | + ADI_MAX32_I2C_INT_EN0_TX_LOCK_OUT | + ADI_MAX32_I2C_INT_EN0_DONE | ADI_MAX32_I2C_INT_EN0_ERR; + int_en1 = ADI_MAX32_I2C_INT_EN1_TX_UNDERFLOW; + } else { + /* Write request received from the master */ + i2c_max32_target_callback(dev, i2c, MXC_I2C_EVT_MASTER_WR); + int_en0 = ADI_MAX32_I2C_INT_EN0_RX_THD | + ADI_MAX32_I2C_INT_EN0_DONE | ADI_MAX32_I2C_INT_EN0_ERR; + int_en1 = ADI_MAX32_I2C_INT_EN1_RX_OVERFLOW; + } + } + } + Wrap_MXC_I2C_SetIntEn(i2c, int_en0, int_en1); +} +#endif /* CONFIG_I2C_TARGET */ + +#ifdef CONFIG_I2C_MAX32_INTERRUPT +static void i2c_max32_isr_controller(const struct device *dev, mxc_i2c_regs_t *i2c) +{ + struct max32_i2c_data *data = dev->data; + mxc_i2c_req_t *req = &data->req; + uint32_t written, readb; + uint32_t txfifolevel; + uint32_t int_fl0, int_fl1; + uint32_t int_en0, int_en1; + + written = data->written; + readb = data->readb; + + Wrap_MXC_I2C_GetIntEn(i2c, &int_en0, &int_en1); + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + txfifolevel = Wrap_MXC_I2C_GetTxFIFOLevel(i2c); + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + data->err = -EIO; + Wrap_MXC_I2C_SetIntEn(i2c, 0, 0); + k_sem_give(&data->xfer); + return; + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ADDR_ACK) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + if (written < req->tx_len) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + } else if (readb < req->rx_len) { + MXC_I2C_EnableInt( + i2c, ADI_MAX32_I2C_INT_EN0_RX_THD | ADI_MAX32_I2C_INT_EN0_DONE, 0); + } + } + + if (req->tx_len && + (int_fl0 & (ADI_MAX32_I2C_INT_FL0_TX_THD | ADI_MAX32_I2C_INT_FL0_DONE))) { + if (written < req->tx_len) { + written += MXC_I2C_WriteTXFIFO(i2c, &req->tx_buf[written], + req->tx_len - written); + } else { + if (!(int_en0 & ADI_MAX32_I2C_INT_EN0_DONE)) { + /* We are done, stop sending more data */ + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + if (data->flags & I2C_MSG_STOP) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + /* Done flag is not set if stop/restart is not set */ + Wrap_MXC_I2C_Stop(i2c); + } else { + k_sem_give(&data->xfer); + } + } + + if ((int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE)) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + k_sem_give(&data->xfer); + } + } + } else if ((int_fl0 & (ADI_MAX32_I2C_INT_FL0_RX_THD | ADI_MAX32_I2C_INT_FL0_DONE))) { + readb += MXC_I2C_ReadRXFIFO(i2c, &req->rx_buf[readb], req->rx_len - readb); + if (readb == req->rx_len) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_RX_THD, 0); + if (data->flags & I2C_MSG_STOP) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + Wrap_MXC_I2C_Stop(i2c); + k_sem_give(&data->xfer); + } else { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + k_sem_give(&data->xfer); + } + } + } else if ((int_en0 & ADI_MAX32_I2C_INT_EN0_DONE) && + (int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE)) { + MXC_I2C_DisableInt( + i2c, (ADI_MAX32_I2C_INT_EN0_RX_THD | ADI_MAX32_I2C_INT_EN0_DONE), + 0); + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len - readb); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + i2c->fifo = (req->addr << 1) | 0x1; + Wrap_MXC_I2C_Restart(i2c); + } + } + + data->written = written; + data->readb = readb; +} +#endif /* CONFIG_I2C_MAX32_INTERRUPT */ + +#if defined(CONFIG_I2C_TARGET) || defined(CONFIG_I2C_MAX32_INTERRUPT) +static void i2c_max32_isr(const struct device *dev) +{ + const struct max32_i2c_config *cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + +#ifdef CONFIG_I2C_MAX32_INTERRUPT + if (data->target_mode == 0) { + i2c_max32_isr_controller(dev, i2c); + return; + } +#endif /* CONFIG_I2C_MAX32_INTERRUPT */ + +#ifdef CONFIG_I2C_TARGET + if (data->target_mode == 1) { + i2c_max32_isr_target(dev, i2c); + } +#endif +} +#endif /* CONFIG_I2C_TARGET || CONFIG_I2C_MAX32_INTERRUPT */ + +static const struct i2c_driver_api api = { + .configure = api_configure, + .transfer = api_transfer, +#ifdef CONFIG_I2C_TARGET + .target_register = api_target_register, + .target_unregister = api_target_unregister, +#endif + .recover_bus = api_recover_bus, +}; + +static int i2c_max32_init(const struct device *dev) +{ + const struct max32_i2c_config *const cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + int ret = 0; + + if (!device_is_ready(cfg->clock)) { + return -ENODEV; + } + + MXC_I2C_Shutdown(i2c); /* Clear everything out */ + + ret = clock_control_on(cfg->clock, (clock_control_subsys_t)&cfg->perclk); + if (ret) { + return ret; + } + + ret = pinctrl_apply_state(cfg->pctrl, PINCTRL_STATE_DEFAULT); + if (ret) { + return ret; + } + + ret = MXC_I2C_Init(i2c, 1, 0); /* Configure as master */ + if (ret) { + return ret; + } + + MXC_I2C_SetFrequency(i2c, cfg->bitrate); + + k_sem_init(&data->lock, 1, 1); + +#if defined(CONFIG_I2C_TARGET) || defined(CONFIG_I2C_MAX32_INTERRUPT) + cfg->irq_config_func(dev); +#endif + +#ifdef CONFIG_I2C_MAX32_INTERRUPT + irq_enable(cfg->irqn); + + k_sem_init(&data->xfer, 0, 1); +#endif + +#if defined(CONFIG_I2C_TARGET) + data->first_write = true; + data->target_mode = 0; +#endif + data->dev = dev; + + return ret; +} + +#if defined(CONFIG_I2C_TARGET) || defined(CONFIG_I2C_MAX32_INTERRUPT) +#define I2C_MAX32_CONFIG_IRQ_FUNC(n) \ + .irq_config_func = i2c_max32_irq_config_func_##n, .irqn = DT_INST_IRQN(n), + +#define I2C_MAX32_IRQ_CONFIG_FUNC(n) \ + static void i2c_max32_irq_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_max32_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + } +#else +#define I2C_MAX32_CONFIG_IRQ_FUNC(n) +#define I2C_MAX32_IRQ_CONFIG_FUNC(n) +#endif + +#define DEFINE_I2C_MAX32(_num) \ + PINCTRL_DT_INST_DEFINE(_num); \ + I2C_MAX32_IRQ_CONFIG_FUNC(_num) \ + static const struct max32_i2c_config max32_i2c_dev_cfg_##_num = { \ + .regs = (mxc_i2c_regs_t *)DT_INST_REG_ADDR(_num), \ + .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(_num), \ + .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(_num)), \ + .perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \ + .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \ + .bitrate = DT_INST_PROP(_num, clock_frequency), \ + I2C_MAX32_CONFIG_IRQ_FUNC(_num)}; \ + static struct max32_i2c_data max32_i2c_data_##_num; \ + I2C_DEVICE_DT_INST_DEFINE(_num, i2c_max32_init, NULL, &max32_i2c_data_##_num, \ + &max32_i2c_dev_cfg_##_num, PRE_KERNEL_2, \ + CONFIG_I2C_INIT_PRIORITY, &api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_I2C_MAX32) diff --git a/drivers/i2c/i2c_rtio.c b/drivers/i2c/i2c_rtio.c index 7fd90c3b89da1c..d921f5604efe44 100644 --- a/drivers/i2c/i2c_rtio.c +++ b/drivers/i2c/i2c_rtio.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL @@ -55,14 +55,12 @@ struct rtio_sqe *i2c_rtio_copy(struct rtio *r, struct rtio_iodev *iodev, const s void i2c_rtio_init(struct i2c_rtio *ctx, const struct device *dev) { k_sem_init(&ctx->lock, 1, 1); - rtio_mpsc_init(&ctx->io_q); + mpsc_init(&ctx->io_q); ctx->txn_curr = NULL; ctx->txn_head = NULL; ctx->dt_spec.bus = dev; ctx->iodev.data = &ctx->dt_spec; ctx->iodev.api = &i2c_iodev_api; - /* TODO drop the builtin submission queue? */ - rtio_mpsc_init(&ctx->iodev.iodev_sq); } /** @@ -82,7 +80,7 @@ static bool i2c_rtio_next(struct i2c_rtio *ctx, bool completion) return false; } - struct rtio_mpsc_node *next = rtio_mpsc_pop(&ctx->io_q); + struct mpsc_node *next = mpsc_pop(&ctx->io_q); /* Nothing left to do */ if (next == NULL) { @@ -119,7 +117,7 @@ bool i2c_rtio_complete(struct i2c_rtio *ctx, int status) } bool i2c_rtio_submit(struct i2c_rtio *ctx, struct rtio_iodev_sqe *iodev_sqe) { - rtio_mpsc_push(&ctx->io_q, &iodev_sqe->q); + mpsc_push(&ctx->io_q, &iodev_sqe->q); return i2c_rtio_next(ctx, false); } diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index a8d64416bc8365..13f4132a01dfd7 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -126,7 +126,11 @@ static void nrf5_get_eui64(uint8_t *mac) mac[index++] = (IEEE802154_NRF5_VENDOR_OUI >> 8) & 0xff; mac[index++] = IEEE802154_NRF5_VENDOR_OUI & 0xff; -#if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && defined(NRF_FICR_S) +#if defined(NRF54H_SERIES) + /* Can't access SICR with device id on a radio core. Use BLE.ADDR. */ + deviceid[0] = NRF_FICR->BLE.ADDR[0]; + deviceid[1] = NRF_FICR->BLE.ADDR[1]; +#elif defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && defined(NRF_FICR_S) soc_secure_read_deviceid(deviceid); #else deviceid[0] = nrf_ficr_deviceid_get(NRF_FICR, 0); diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index bab58e5c6d3025..a996cb93ead3ba 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_PAT912X input_pat912x.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PAW32XX input_paw32xx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PINNACLE input_pinnacle.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PMW3610 input_pmw3610.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_SBUS input_sbus.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XEC_KBD input_xec_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XPT2046 input_xpt2046.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e810b5b0914c40..34363e3eca94c3 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -26,6 +26,7 @@ source "drivers/input/Kconfig.pat912x" source "drivers/input/Kconfig.paw32xx" source "drivers/input/Kconfig.pinnacle" source "drivers/input/Kconfig.pmw3610" +source "drivers/input/Kconfig.sbus" source "drivers/input/Kconfig.sdl" source "drivers/input/Kconfig.stmpe811" source "drivers/input/Kconfig.xec" diff --git a/drivers/input/Kconfig.sbus b/drivers/input/Kconfig.sbus new file mode 100644 index 00000000000000..a3d1532161ed7c --- /dev/null +++ b/drivers/input/Kconfig.sbus @@ -0,0 +1,54 @@ +# Copyright (c) 2024 NXP Semiconductors +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_SBUS + bool "SBUS driver" + default y + depends on DT_HAS_FUTABA_SBUS_ENABLED + depends on UART_INTERRUPT_DRIVEN + select UART_USE_RUNTIME_CONFIGURE + help + Enable driver for SBUS Remote controller. + +if INPUT_SBUS + +config INPUT_SBUS_THREAD_STACK_SIZE + int "Stack size for the sbus thread" + default 1024 + help + Size of the stack used for the sbus thread. + +config INPUT_SBUS_THREAD_PRIORITY + int "Priority for the sbus thread" + default 0 + help + Priority level of the sbus thread. + +config INPUT_SBUS_REPORT_FILTER + int "Minimal change in signal to report" + default 1 + help + SBUS tends to be a bit noisy you can increase the threshold to + to lower the amounts of input events. Set to 0 for no filtering + +config INPUT_SBUS_SEND_SYNC + bool "Send Sync to input subsys on each SBUS frame" + default y + help + Sends sync message to input subsys with sync bit. + +config INPUT_SBUS_CHANNEL_VALUE_ONE + int "Threshold value > for INPUT_EV_KEY value 1" + default 1800 + help + SBUS sends analogue values for digital switches. This config value + sets the threshold to interperted the analogue value as an logic 1 + +config INPUT_SBUS_CHANNEL_VALUE_ZERO + int "Threshold value < for INPUT_EV_KEY value 0" + default 1200 + help + SBUS sends analogue values for digital switches. This config value + sets the threshold to interperted the analogue value as an logic 0 + +endif # INPUT_SBUS diff --git a/drivers/input/input_sbus.c b/drivers/input/input_sbus.c new file mode 100644 index 00000000000000..ef88f5fc677f01 --- /dev/null +++ b/drivers/input/input_sbus.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2024 CogniPilot Foundation + * Copyright (c) 2024 NXP Semiconductors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT futaba_sbus + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(futaba_sbus, CONFIG_INPUT_LOG_LEVEL); + +/* Driver config */ +struct sbus_input_channel { + uint32_t sbus_channel; + uint32_t type; + uint32_t zephyr_code; +}; + +const struct uart_config uart_cfg_sbus = { + .baudrate = 100000, + .parity = UART_CFG_PARITY_EVEN, + .stop_bits = UART_CFG_STOP_BITS_2, + .data_bits = UART_CFG_DATA_BITS_8, + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE +}; + +struct input_sbus_config { + uint8_t num_channels; + const struct sbus_input_channel *channel_info; + const struct device *uart_dev; + uart_irq_callback_user_data_t cb; +}; + +#define SBUS_FRAME_LEN 25 +#define SBUS_HEADER 0x0F +#define SBUS_FOOTER 0x00 + +#define SBUS_SERVO_LEN 22 +#define SBUS_SERVO_CH_MASK 0x7FF + +#define SBUS_BYTE24_IDX 23 +#define SBUS_BYTE24_CH17 0x01 +#define SBUS_BYTE24_CH18 0x02 +#define SBUS_BYTE24_FRAME_LOST 0x04 +#define SBUS_BYTE24_FAILSAFE 0x08 + +#define SBUS_TRANSMISSION_TIME_MS 4 /* Max transmission of a single SBUS frame */ +#define SBUS_INTERFRAME_SPACING_MS 20 /* Max spacing between SBUS frames */ +#define SBUS_CHANNEL_COUNT 16 + +#define REPORT_FILTER CONFIG_INPUT_SBUS_REPORT_FILTER +#define CHANNEL_VALUE_ZERO CONFIG_INPUT_SBUS_CHANNEL_VALUE_ZERO +#define CHANNEL_VALUE_ONE CONFIG_INPUT_SBUS_CHANNEL_VALUE_ONE + +struct input_sbus_data { + struct k_thread thread; + struct k_sem report_lock; + + uint16_t xfer_bytes; + uint8_t rd_data[SBUS_FRAME_LEN]; + uint8_t sbus_frame[SBUS_FRAME_LEN]; + bool partial_sync; + bool in_sync; + uint32_t last_rx_time; + + uint16_t last_reported_value[SBUS_CHANNEL_COUNT]; + int8_t channel_mapping[SBUS_CHANNEL_COUNT]; + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_INPUT_SBUS_THREAD_STACK_SIZE); +}; + +static void input_sbus_report(const struct device *dev, unsigned int sbus_channel, + unsigned int value) +{ + const struct input_sbus_config *const config = dev->config; + struct input_sbus_data *const data = dev->data; + + int channel = data->channel_mapping[sbus_channel]; + + /* Not Mapped */ + if (channel == -1) { + return; + } + + if (value >= (data->last_reported_value[channel] + REPORT_FILTER) || + value <= (data->last_reported_value[channel] - REPORT_FILTER)) { + switch (config->channel_info[channel].type) { + case INPUT_EV_ABS: + case INPUT_EV_MSC: + input_report(dev, config->channel_info[channel].type, + config->channel_info[channel].zephyr_code, value, false, + K_FOREVER); + break; + + default: + if (value > CHANNEL_VALUE_ONE) { + input_report_key(dev, config->channel_info[channel].zephyr_code, 1, + false, K_FOREVER); + } else if (value < CHANNEL_VALUE_ZERO) { + input_report_key(dev, config->channel_info[channel].zephyr_code, 0, + false, K_FOREVER); + } + } + data->last_reported_value[channel] = value; + } +} + +static void input_sbus_input_report_thread(const struct device *dev, void *dummy2, void *dummy3) +{ + struct input_sbus_data *const data = dev->data; + + ARG_UNUSED(dummy2); + ARG_UNUSED(dummy3); + + uint8_t i, channel; + uint8_t *sbus_channel_data = &data->sbus_frame[1]; /* Omit header */ + uint16_t value; + int bits_read; + unsigned int key; + int ret; + bool connected_reported = false; + + while (true) { + if (!data->in_sync) { + k_sem_take(&data->report_lock, K_FOREVER); + if (data->in_sync) { + LOG_DBG("SBUS receiver connected"); + } else { + continue; + } + } else { + ret = k_sem_take(&data->report_lock, K_MSEC(SBUS_INTERFRAME_SPACING_MS)); + if (ret == -EBUSY) { + continue; + } else if (ret < 0 || !data->in_sync) { + /* We've lost sync with the UART receiver */ + key = irq_lock(); + + data->partial_sync = false; + data->in_sync = false; + data->xfer_bytes = 0; + irq_unlock(key); + + connected_reported = false; + LOG_DBG("SBUS receiver connection lost"); + + /* Report connection lost */ + continue; + } + } + + if (connected_reported && + data->sbus_frame[SBUS_BYTE24_IDX] & SBUS_BYTE24_FRAME_LOST) { + LOG_DBG("SBUS controller connection lost"); + connected_reported = false; + } else if (!connected_reported && + !(data->sbus_frame[SBUS_BYTE24_IDX] & SBUS_BYTE24_FRAME_LOST)) { + LOG_DBG("SBUS controller connected"); + connected_reported = true; + } + + /* Parse the data */ + channel = 0; + value = 0; + bits_read = 0; + + for (i = 0; i < SBUS_SERVO_LEN; i++) { + /* Read the next byte */ + unsigned char byte = sbus_channel_data[i]; + + /* Extract bits and construct the 11-bit value */ + value |= byte << bits_read; + bits_read += 8; + + /* Check if we've read enough bits to form a full 11-bit value */ + while (bits_read >= 11) { + input_sbus_report(dev, channel, value & SBUS_SERVO_CH_MASK); + + /* Shift right to prepare for the next 11 bits */ + value >>= 11; + bits_read -= 11; + channel++; + } + } + +#ifdef CONFIG_INPUT_SBUS_SEND_SYNC + input_report(dev, 0, 0, 0, true, K_FOREVER); +#endif + } +} + +static void sbus_resync(const struct device *uart_dev, struct input_sbus_data *const data) +{ + uint8_t *rd_data = data->rd_data; + + if (data->partial_sync) { + data->xfer_bytes += uart_fifo_read(uart_dev, &rd_data[data->xfer_bytes], + SBUS_FRAME_LEN - data->xfer_bytes); + if (data->xfer_bytes == SBUS_FRAME_LEN) { + /* Transfer took longer then 4ms probably faulty */ + if (k_uptime_get_32() - data->last_rx_time > SBUS_TRANSMISSION_TIME_MS) { + data->xfer_bytes = 0; + data->partial_sync = false; + } else if (rd_data[0] == SBUS_HEADER && + rd_data[SBUS_FRAME_LEN - 1] == SBUS_FOOTER) { + data->in_sync = true; + } else { + /* Dummy read to clear fifo */ + uart_fifo_read(uart_dev, &rd_data[0], 1); + data->xfer_bytes = 0; + data->partial_sync = false; + } + } + } else { + if (uart_fifo_read(uart_dev, &rd_data[0], 1) == 1) { + if (rd_data[0] == SBUS_HEADER) { + data->partial_sync = true; + data->xfer_bytes = 1; + data->last_rx_time = k_uptime_get_32(); + } + } + } +} + +static void sbus_uart_isr(const struct device *uart_dev, void *user_data) +{ + const struct device *dev = user_data; + struct input_sbus_data *const data = dev->data; + uint8_t *rd_data = data->rd_data; + + if (uart_dev == NULL) { + LOG_DBG("UART device is NULL"); + return; + } + + if (!uart_irq_update(uart_dev)) { + LOG_DBG("Unable to start processing interrupts"); + return; + } + + while (uart_irq_rx_ready(uart_dev) && data->xfer_bytes <= SBUS_FRAME_LEN) { + if (data->in_sync) { + if (data->xfer_bytes == 0) { + data->last_rx_time = k_uptime_get_32(); + } + data->xfer_bytes += uart_fifo_read(uart_dev, &rd_data[data->xfer_bytes], + SBUS_FRAME_LEN - data->xfer_bytes); + } else { + sbus_resync(uart_dev, data); + } + } + + if (data->in_sync && (k_uptime_get_32() - data->last_rx_time > + SBUS_INTERFRAME_SPACING_MS)) { + data->partial_sync = false; + data->in_sync = false; + data->xfer_bytes = 0; + k_sem_give(&data->report_lock); + } else if (data->in_sync && data->xfer_bytes == SBUS_FRAME_LEN) { + data->xfer_bytes = 0; + + if (rd_data[0] == SBUS_HEADER && rd_data[SBUS_FRAME_LEN - 1] == SBUS_FOOTER) { + memcpy(data->sbus_frame, rd_data, SBUS_FRAME_LEN); + k_sem_give(&data->report_lock); + } else { + data->partial_sync = false; + data->in_sync = false; + } + } +} + +/* + * @brief Initialize sbus driver + */ +static int input_sbus_init(const struct device *dev) +{ + const struct input_sbus_config *const config = dev->config; + struct input_sbus_data *const data = dev->data; + int i, ret; + + uart_irq_rx_disable(config->uart_dev); + uart_irq_tx_disable(config->uart_dev); + + LOG_DBG("Initializing SBUS driver"); + + for (i = 0; i < SBUS_CHANNEL_COUNT; i++) { + data->last_reported_value[i] = 0; + data->channel_mapping[i] = -1; + } + + data->xfer_bytes = 0; + data->in_sync = false; + data->partial_sync = false; + data->last_rx_time = 0; + + for (i = 0; i < config->num_channels; i++) { + data->channel_mapping[config->channel_info[i].sbus_channel - 1] = i; + } + + ret = uart_configure(config->uart_dev, &uart_cfg_sbus); + if (ret < 0) { + LOG_ERR("Unable to configure UART port: %d", ret); + return ret; + } + + ret = uart_irq_callback_user_data_set(config->uart_dev, config->cb, (void *)dev); + if (ret < 0) { + if (ret == -ENOTSUP) { + LOG_ERR("Interrupt-driven UART API support not enabled"); + } else if (ret == -ENOSYS) { + LOG_ERR("UART device does not support interrupt-driven API"); + } else { + LOG_ERR("Error setting UART callback: %d", ret); + } + return ret; + } + + uart_irq_rx_enable(config->uart_dev); + + k_sem_init(&data->report_lock, 0, 1); + + k_thread_create(&data->thread, data->thread_stack, + K_KERNEL_STACK_SIZEOF(data->thread_stack), + (k_thread_entry_t)input_sbus_input_report_thread, (void *)dev, NULL, NULL, + CONFIG_INPUT_SBUS_THREAD_PRIORITY, 0, K_NO_WAIT); + + k_thread_name_set(&data->thread, dev->name); + + return ret; +} + +#define INPUT_CHANNEL_CHECK(input_channel_id) \ + BUILD_ASSERT(IN_RANGE(DT_PROP(input_channel_id, channel), 1, 16), \ + "invalid channel number"); \ + BUILD_ASSERT(DT_PROP(input_channel_id, type) == INPUT_EV_ABS || \ + DT_PROP(input_channel_id, type) == INPUT_EV_KEY || \ + DT_PROP(input_channel_id, type) == INPUT_EV_MSC, \ + "invalid channel type"); + +#define SBUS_INPUT_CHANNEL_INITIALIZER(input_channel_id) \ + { \ + .sbus_channel = DT_PROP(input_channel_id, channel), \ + .type = DT_PROP(input_channel_id, type), \ + .zephyr_code = DT_PROP(input_channel_id, zephyr_code), \ + }, + +#define INPUT_SBUS_INIT(n) \ + \ + static const struct sbus_input_channel input_##id[] = { \ + DT_INST_FOREACH_CHILD(n, SBUS_INPUT_CHANNEL_INITIALIZER) \ + }; \ + DT_INST_FOREACH_CHILD(n, INPUT_CHANNEL_CHECK) \ + \ + static struct input_sbus_data sbus_data_##n; \ + \ + static const struct input_sbus_config sbus_cfg_##n = { \ + .channel_info = input_##id, \ + .uart_dev = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .num_channels = ARRAY_SIZE(input_##id), \ + .cb = sbus_uart_isr, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, input_sbus_init, NULL, &sbus_data_##n, &sbus_cfg_##n, \ + POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(INPUT_SBUS_INIT) diff --git a/drivers/led/CMakeLists.txt b/drivers/led/CMakeLists.txt index c3d90d0ba06ff4..09ea5e202fdf53 100644 --- a/drivers/led/CMakeLists.txt +++ b/drivers/led/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_NCP5623 ncp5623.c) zephyr_library_sources_ifdef(CONFIG_PCA9633 pca9633.c) zephyr_library_sources_ifdef(CONFIG_TLC59108 tlc59108.c) zephyr_library_sources_ifdef(CONFIG_IS31FL3733 is31fl3733.c) +zephyr_library_sources_ifdef(CONFIG_IS31FL3194 is31fl3194.c) zephyr_library_sources_ifdef(CONFIG_LED_SHELL led_shell.c) diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 7808a1013ae9cf..26bf49cd5e2aef 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -40,5 +40,6 @@ source "drivers/led/Kconfig.pwm" source "drivers/led/Kconfig.tlc59108" source "drivers/led/Kconfig.xec" source "drivers/led/Kconfig.is31fl3733" +source "drivers/led/Kconfig.is31fl3194" endif # LED diff --git a/drivers/led/Kconfig.is31fl3194 b/drivers/led/Kconfig.is31fl3194 new file mode 100644 index 00000000000000..42166805a1d16f --- /dev/null +++ b/drivers/led/Kconfig.is31fl3194 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config IS31FL3194 + bool "IS31FL3194 LED driver" + default y + depends on DT_HAS_ISSI_IS31FL3194_ENABLED + select I2C + help + Enable LED driver for Lumissil Microsystems (a division of ISSI) + IS31FL3194. This chip supports one RGB LED or 3 independent LEDs. diff --git a/drivers/led/is31fl3194.c b/drivers/led/is31fl3194.c new file mode 100644 index 00000000000000..5b0c34ebf571c0 --- /dev/null +++ b/drivers/led/is31fl3194.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2024 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT issi_is31fl3194 + +/** + * @file + * @brief IS31FL3194 LED driver + * + * The IS31FL3194 is a 3-channel LED driver that communicates over I2C. + */ + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(is31fl3194, CONFIG_LED_LOG_LEVEL); + +#define IS31FL3194_PROD_ID_REG 0x00 +#define IS31FL3194_CONF_REG 0x01 +#define IS31FL3194_CURRENT_REG 0x03 +#define IS31FL3194_OUT1_REG 0x10 +#define IS31FL3194_OUT2_REG 0x21 +#define IS31FL3194_OUT3_REG 0x32 +#define IS31FL3194_UPDATE_REG 0x40 + +#define IS31FL3194_PROD_ID_VAL 0xce +#define IS31FL3194_CONF_ENABLE 0x01 +#define IS31FL3194_UPDATE_VAL 0xc5 + +#define IS31FL3194_CHANNEL_COUNT 3 + +static const uint8_t led_channels[] = { + IS31FL3194_OUT1_REG, + IS31FL3194_OUT2_REG, + IS31FL3194_OUT3_REG +}; + +struct is31fl3194_config { + struct i2c_dt_spec bus; + uint8_t num_leds; + const struct led_info *led_infos; + const uint8_t *current_limits; +}; + +static const struct led_info *is31fl3194_led_to_info(const struct is31fl3194_config *config, + uint32_t led) +{ + if (led < config->num_leds) { + return &config->led_infos[led]; + } + + return NULL; +} + +static int is31fl3194_get_info(const struct device *dev, + uint32_t led, + const struct led_info **info_out) +{ + const struct is31fl3194_config *config = dev->config; + const struct led_info *info = is31fl3194_led_to_info(config, led); + + if (info == NULL) { + return -EINVAL; + } + + *info_out = info; + return 0; +} + +static int is31fl3194_set_color(const struct device *dev, uint32_t led, uint8_t num_colors, + const uint8_t *color) +{ + const struct is31fl3194_config *config = dev->config; + const struct led_info *info = is31fl3194_led_to_info(config, led); + int ret; + + if (info == NULL) { + return -ENODEV; + } + + if (info->num_colors != 3) { + return -ENOTSUP; + } + + if (num_colors != 3) { + return -EINVAL; + } + + for (int i = 0; i < 3; i++) { + uint8_t value; + + switch (info->color_mapping[i]) { + case LED_COLOR_ID_RED: + value = color[0]; + break; + case LED_COLOR_ID_GREEN: + value = color[1]; + break; + case LED_COLOR_ID_BLUE: + value = color[2]; + break; + default: + /* unreachable: mapping already tested in is31fl3194_check_config */ + continue; + } + + ret = i2c_reg_write_byte_dt(&config->bus, led_channels[i], value); + if (ret != 0) { + break; + } + } + + if (ret == 0) { + ret = i2c_reg_write_byte_dt(&config->bus, + IS31FL3194_UPDATE_REG, + IS31FL3194_UPDATE_VAL); + } + + if (ret != 0) { + LOG_ERR("%s: LED write failed: %d", dev->name, ret); + } + + return ret; +} + +static int is31fl3194_set_brightness(const struct device *dev, uint32_t led, uint8_t value) +{ + const struct is31fl3194_config *config = dev->config; + const struct led_info *info = is31fl3194_led_to_info(config, led); + int ret = 0; + + if (info == NULL) { + return -ENODEV; + } + + if (info->num_colors != 1) { + return -ENOTSUP; + } + + if (value > 100) { + return -EINVAL; + } + + /* Rescale 0..100 to 0..255 */ + value = value * 255 / 100; + + ret = i2c_reg_write_byte_dt(&config->bus, led_channels[led], value); + if (ret == 0) { + ret = i2c_reg_write_byte_dt(&config->bus, + IS31FL3194_UPDATE_REG, + IS31FL3194_UPDATE_VAL); + } + + if (ret != 0) { + LOG_ERR("%s: LED write failed", dev->name); + } + + return ret; +} + +static inline int is31fl3194_led_on(const struct device *dev, uint32_t led) +{ + return is31fl3194_set_brightness(dev, led, 100); +} + +static inline int is31fl3194_led_off(const struct device *dev, uint32_t led) +{ + return is31fl3194_set_brightness(dev, led, 0); +} + +/* + * Counts red, green, blue channels; returns true if color_id is valid + * and no more than one channel maps to the same color + */ +static bool is31fl3194_count_colors(const struct device *dev, + uint8_t color_id, uint8_t *rgb_counts) +{ + bool ret = false; + + switch (color_id) { + case LED_COLOR_ID_RED: + ret = (++rgb_counts[0] == 1); + break; + case LED_COLOR_ID_GREEN: + ret = (++rgb_counts[1] == 1); + break; + case LED_COLOR_ID_BLUE: + ret = (++rgb_counts[2] == 1); + break; + } + + if (!ret) { + LOG_ERR("%s: invalid color %d (duplicate or not RGB)", + dev->name, color_id); + } + + return ret; +} + +static int is31fl3194_check_config(const struct device *dev) +{ + const struct is31fl3194_config *config = dev->config; + const struct led_info *info; + uint8_t rgb_counts[3] = { 0 }; + uint8_t i; + + switch (config->num_leds) { + case 1: + /* check that it is a three-channel LED */ + info = &config->led_infos[0]; + + if (info->num_colors != 3) { + LOG_ERR("%s: invalid number of colors %d " + "(must be 3 for RGB LED)", + dev->name, info->num_colors); + return -EINVAL; + } + + for (i = 0; i < 3; i++) { + if (!is31fl3194_count_colors(dev, info->color_mapping[i], rgb_counts)) { + return -EINVAL; + } + + } + break; + case 3: + /* check that each LED is single-color */ + for (i = 0; i < 3; i++) { + info = &config->led_infos[i]; + + if (info->num_colors != 1) { + LOG_ERR("%s: invalid number of colors %d " + "(must be 1 when defining multiple LEDs)", + dev->name, info->num_colors); + return -EINVAL; + } + + if (!is31fl3194_count_colors(dev, info->color_mapping[0], rgb_counts)) { + return -EINVAL; + } + } + break; + default: + LOG_ERR("%s: invalid number of LEDs %d (must be 1 or 3)", + dev->name, config->num_leds); + return -EINVAL; + } + + return 0; +} + +static int is31fl3194_init(const struct device *dev) +{ + const struct is31fl3194_config *config = dev->config; + const struct led_info *info = NULL; + int i, ret; + uint8_t prod_id, band; + uint8_t current_reg = 0; + + ret = is31fl3194_check_config(dev); + if (ret != 0) { + return ret; + } + + if (!i2c_is_ready_dt(&config->bus)) { + LOG_ERR("%s: I2C device not ready", dev->name); + return -ENODEV; + } + + ret = i2c_reg_read_byte_dt(&config->bus, IS31FL3194_PROD_ID_REG, &prod_id); + if (ret != 0) { + LOG_ERR("%s: failed to read product ID", dev->name); + return ret; + } + + if (prod_id != IS31FL3194_PROD_ID_VAL) { + LOG_ERR("%s: invalid product ID 0x%02x (expected 0x%02x)", dev->name, prod_id, + IS31FL3194_PROD_ID_VAL); + return -ENODEV; + } + + /* calc current limit register value */ + info = &config->led_infos[0]; + if (info->num_colors == IS31FL3194_CHANNEL_COUNT) { + /* one RGB LED: set all channels to the same current limit */ + band = (config->current_limits[0] / 10) - 1; + for (i = 0; i < IS31FL3194_CHANNEL_COUNT; i++) { + current_reg |= band << (2 * i); + } + } else { + /* single-channel LEDs: independent limits */ + for (i = 0; i < config->num_leds; i++) { + band = (config->current_limits[i] / 10) - 1; + current_reg |= band << (2 * i); + } + } + + ret = i2c_reg_write_byte_dt(&config->bus, IS31FL3194_CURRENT_REG, current_reg); + if (ret != 0) { + LOG_ERR("%s: failed to set current limit", dev->name); + return ret; + } + + /* enable device */ + return i2c_reg_write_byte_dt(&config->bus, IS31FL3194_CONF_REG, IS31FL3194_CONF_ENABLE); +} + +static const struct led_driver_api is31fl3194_led_api = { + .set_brightness = is31fl3194_set_brightness, + .on = is31fl3194_led_on, + .off = is31fl3194_led_off, + .get_info = is31fl3194_get_info, + .set_color = is31fl3194_set_color, +}; + +#define COLOR_MAPPING(led_node_id) \ + static const uint8_t color_mapping_##led_node_id[] = \ + DT_PROP(led_node_id, color_mapping); + +#define LED_INFO(led_node_id) \ + { \ + .label = DT_PROP(led_node_id, label), \ + .num_colors = DT_PROP_LEN(led_node_id, color_mapping), \ + .color_mapping = color_mapping_##led_node_id, \ + }, + +#define LED_CURRENT(led_node_id) \ + DT_PROP(led_node_id, current_limit), + +#define IS31FL3194_DEFINE(id) \ + \ + DT_INST_FOREACH_CHILD(id, COLOR_MAPPING) \ + \ + static const struct led_info is31fl3194_leds_##id[] = \ + { DT_INST_FOREACH_CHILD(id, LED_INFO) }; \ + static const uint8_t is31fl3194_currents_##id[] = \ + { DT_INST_FOREACH_CHILD(id, LED_CURRENT) }; \ + BUILD_ASSERT(ARRAY_SIZE(is31fl3194_leds_##id) > 0, \ + "No LEDs defined for " #id); \ + \ + static const struct is31fl3194_config is31fl3194_config_##id = { \ + .bus = I2C_DT_SPEC_INST_GET(id), \ + .num_leds = ARRAY_SIZE(is31fl3194_leds_##id), \ + .led_infos = is31fl3194_leds_##id, \ + .current_limits = is31fl3194_currents_##id, \ + }; \ + DEVICE_DT_INST_DEFINE(id, &is31fl3194_init, NULL, NULL, \ + &is31fl3194_config_##id, POST_KERNEL, \ + CONFIG_LED_INIT_PRIORITY, &is31fl3194_led_api); + +DT_INST_FOREACH_STATUS_OKAY(IS31FL3194_DEFINE) diff --git a/drivers/led/led_shell.c b/drivers/led/led_shell.c index 3e26c915c3cbb5..b138403e499e0c 100644 --- a/drivers/led/led_shell.c +++ b/drivers/led/led_shell.c @@ -6,6 +6,7 @@ #include #include +#include #include #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL @@ -84,6 +85,28 @@ static int cmd_on(const struct shell *sh, size_t argc, char **argv) return err; } +static const char *led_color_to_str(uint8_t color) +{ + switch (color) { + case LED_COLOR_ID_WHITE: + return "white"; + case LED_COLOR_ID_RED: + return "red"; + case LED_COLOR_ID_GREEN: + return "green"; + case LED_COLOR_ID_BLUE: + return "blue"; + case LED_COLOR_ID_VIOLET: + return "violet"; + case LED_COLOR_ID_YELLOW: + return "yellow"; + case LED_COLOR_ID_IR: + return "IR"; + default: + return "unknown"; + } +} + static int cmd_get_info(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; @@ -109,11 +132,11 @@ static int cmd_get_info(const struct shell *sh, size_t argc, char **argv) shell_print(sh, "Index : %d", info->index); shell_print(sh, "Num colors : %d", info->num_colors); if (info->color_mapping) { - shell_fprintf(sh, SHELL_NORMAL, "Colors : %d", - info->color_mapping[0]); + shell_fprintf(sh, SHELL_NORMAL, "Colors : %s", + led_color_to_str(info->color_mapping[0])); for (i = 1; i < info->num_colors; i++) { - shell_fprintf(sh, SHELL_NORMAL, ":%d", - info->color_mapping[i]); + shell_fprintf(sh, SHELL_NORMAL, ":%s", + led_color_to_str(info->color_mapping[i])); } shell_fprintf(sh, SHELL_NORMAL, "\n"); } diff --git a/drivers/mm/mm_drv_intel_adsp.h b/drivers/mm/mm_drv_intel_adsp.h index 8de9ccc42cab62..861621a510f44d 100644 --- a/drivers/mm/mm_drv_intel_adsp.h +++ b/drivers/mm/mm_drv_intel_adsp.h @@ -30,10 +30,7 @@ #include "mm_drv_common.h" -DEVICE_MMIO_TOPLEVEL_STATIC(tlb_regs, DT_DRV_INST(0)); - -#define TLB_BASE \ - ((mm_reg_t)DEVICE_MMIO_TOPLEVEL_GET(tlb_regs)) +#define TLB_BASE (mm_reg_t)DT_REG_ADDR(DT_NODELABEL(tlb)) /* * Number of significant bits in the page index (defines the size of diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index b78a247ae0122c..5b0bc5e576be05 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -26,6 +26,7 @@ #include #include #include +#include #define SRAM_BANK_PAGE_NUM (SRAM_BANK_SIZE / CONFIG_MM_DRV_PAGE_SIZE) @@ -268,6 +269,9 @@ int sys_mm_drv_map_page(void *virt, uintptr_t phys, uint32_t flags) tlb_entries[entry_idx] = entry; +#ifdef CONFIG_MMU + arch_mem_map(virt, va, CONFIG_MM_DRV_PAGE_SIZE, flags); +#endif /* * Invalid the cache of the newly mapped virtual page to * avoid stale data. @@ -329,7 +333,7 @@ int sys_mm_drv_map_array(void *virt, uintptr_t *phys, return sys_mm_drv_simple_map_array(va, phys, cnt, flags); } -int sys_mm_drv_unmap_page(void *virt) +static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) { k_spinlock_key_t key; uint32_t entry_idx, bank_idx; @@ -358,8 +362,14 @@ int sys_mm_drv_unmap_page(void *virt) /* * Flush the cache to make sure the backing physical page * has the latest data. + * No flush when called from sys_mm_drv_mm_init(). */ - sys_cache_data_flush_range(virt, CONFIG_MM_DRV_PAGE_SIZE); + if (flush_data) { + sys_cache_data_flush_range(virt, CONFIG_MM_DRV_PAGE_SIZE); +#ifdef CONFIG_MMU + arch_mem_unmap(virt, CONFIG_MM_DRV_PAGE_SIZE); +#endif + } entry_idx = get_tlb_entry_idx(va); pa = tlb_entry_to_pa(tlb_entries[entry_idx]); @@ -391,6 +401,11 @@ int sys_mm_drv_unmap_page(void *virt) return ret; } +int sys_mm_drv_unmap_page(void *virt) +{ + return sys_mm_drv_unmap_page_wflush(virt, true); +} + int sys_mm_drv_unmap_region(void *virt, size_t size) { void *va = (__sparse_force void *)sys_cache_cached_ptr_get(virt); @@ -441,6 +456,42 @@ int sys_mm_drv_update_page_flags(void *virt, uint32_t flags) return ret; } +#ifdef CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM +static int sys_mm_drv_unmap_region_initial(void *virt_in, size_t size) +{ + void *virt = (__sparse_force void *)sys_cache_cached_ptr_get(virt_in); + + k_spinlock_key_t key; + int ret = 0; + size_t offset; + + CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) || + !sys_mm_drv_is_size_aligned(size)) { + ret = -EINVAL; + goto out; + } + + key = k_spin_lock(&sys_mm_drv_common_lock); + + for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { + uint8_t *va = (uint8_t *)virt + offset; + + int ret2 = sys_mm_drv_unmap_page_wflush(va, false); + + if (ret2 != 0) { + __ASSERT(false, "cannot unmap %p\n", va); + + ret = ret2; + } + } + + k_spin_unlock(&sys_mm_drv_common_lock, key); + +out: + return ret; +} +#endif + int sys_mm_drv_page_phys_get(void *virt, uintptr_t *phys) { uint16_t *tlb_entries = UINT_TO_POINTER(TLB_BASE); @@ -721,8 +772,9 @@ static int sys_mm_drv_mm_init(const struct device *dev) size_t unused_size = CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE - UNUSED_L2_START_ALIGNED; - ret = sys_mm_drv_unmap_region(UINT_TO_POINTER(UNUSED_L2_START_ALIGNED), - unused_size); + ret = sys_mm_drv_unmap_region_initial(UINT_TO_POINTER(UNUSED_L2_START_ALIGNED), + unused_size); + /* Need to reset max pages statistics after unmap */ for (int i = 0; i < L2_SRAM_BANK_NUM; i++) { diff --git a/drivers/modem/CMakeLists.txt b/drivers/modem/CMakeLists.txt index 665dd961acd1f8..62b84bd792946c 100644 --- a/drivers/modem/CMakeLists.txt +++ b/drivers/modem/CMakeLists.txt @@ -36,3 +36,4 @@ if (CONFIG_MODEM_SIM7080) endif() zephyr_library_sources_ifdef(CONFIG_MODEM_CELLULAR modem_cellular.c) +zephyr_library_sources_ifdef(CONFIG_MODEM_AT_SHELL modem_at_shell.c) diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig index dbc78f067d79e3..7219312e18f736 100644 --- a/drivers/modem/Kconfig +++ b/drivers/modem/Kconfig @@ -155,7 +155,7 @@ config MODEM_SOCKET modem_socket_init(). Note that the modem socket uses runtime allocated file descriptors reserved from the fdtable, for which the max count is set using the - Kconfig option POSIX_MAX_FDS. Make sure to update this value as both + Kconfig option ZVFS_OPEN_MAX. Make sure to update this value as both the modem sockets and the POSIX_API, if used, share them. config MODEM_SOCKET_PACKET_COUNT @@ -190,6 +190,7 @@ source "drivers/modem/Kconfig.ublox-sara-r4" source "drivers/modem/Kconfig.quectel-bg9x" source "drivers/modem/Kconfig.wncm14a2a" source "drivers/modem/Kconfig.cellular" +source "drivers/modem/Kconfig.at_shell" source "drivers/modem/Kconfig.hl7800" source "drivers/modem/Kconfig.simcom-sim7080" diff --git a/drivers/modem/Kconfig.at_shell b/drivers/modem/Kconfig.at_shell new file mode 100644 index 00000000000000..b2f6f42e393623 --- /dev/null +++ b/drivers/modem/Kconfig.at_shell @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MODEM_AT_SHELL + bool "AT command shell based on modem modules" + select MODEM_MODULES + select MODEM_CHAT + select MODEM_PIPE + select MODEM_PIPELINK + depends on !MODEM_SHELL + depends on !SHELL_WILDCARD + depends on $(dt_alias_enabled,modem) + +if MODEM_AT_SHELL + +config MODEM_AT_SHELL_USER_PIPE + int "User pipe number to use" + default 0 + +config MODEM_AT_SHELL_RESPONSE_TIMEOUT_S + int "Timeout waiting for response to AT command in seconds" + default 5 + +config MODEM_AT_SHELL_COMMAND_MAX_SIZE + int "Maximum size of AT command" + default 32 + +config MODEM_AT_SHELL_RESPONSE_MAX_SIZE + int "Maximum size of AT response" + default 64 + +config MODEM_AT_SHELL_CHAT_RECEIVE_BUF_SIZE + int "Size of modem chat receive buffer in bytes" + default 128 + +endif # MODEM_AT_SHELL diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index f778069b19ea11..224ffdfdb97a86 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -8,6 +8,7 @@ config MODEM_CELLULAR select MODEM_CMUX select MODEM_CHAT select MODEM_PIPE + select MODEM_PIPELINK select MODEM_BACKEND_UART select RING_BUFFER select NET_L2_PPP_OPTION_MRU @@ -50,4 +51,8 @@ config MODEM_CELLULAR_CHAT_BUFFER_SIZES int "The size of the buffers used for the chat scripts in bytes." default 128 +config MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES + int "The size of the buffers used for each user pipe in bytes." + default 128 + endif diff --git a/drivers/modem/modem_at_shell.c b/drivers/modem/modem_at_shell.c new file mode 100644 index 00000000000000..5d2820d7483edf --- /dev/null +++ b/drivers/modem/modem_at_shell.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2024 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(modem_at_shell, CONFIG_MODEM_LOG_LEVEL); + +#define AT_SHELL_MODEM_NODE DT_ALIAS(modem) +#define AT_SHELL_PIPELINK_NAME _CONCAT(user_pipe_, CONFIG_MODEM_AT_SHELL_USER_PIPE) + +#define AT_SHELL_STATE_ATTACHED_BIT 0 +#define AT_SHELL_STATE_SCRIPT_RUNNING_BIT 1 + +MODEM_PIPELINK_DT_DECLARE(AT_SHELL_MODEM_NODE, AT_SHELL_PIPELINK_NAME); + +static struct modem_pipelink *at_shell_pipelink = + MODEM_PIPELINK_DT_GET(AT_SHELL_MODEM_NODE, AT_SHELL_PIPELINK_NAME); + +static struct modem_chat at_shell_chat; +static uint8_t at_shell_chat_receive_buf[CONFIG_MODEM_AT_SHELL_CHAT_RECEIVE_BUF_SIZE]; +static uint8_t *at_shell_chat_argv_buf[2]; +static uint8_t at_shell_request_buf[CONFIG_MODEM_AT_SHELL_COMMAND_MAX_SIZE]; +static struct modem_chat_script_chat at_shell_script_chat[1]; +static struct modem_chat_match at_shell_script_chat_matches[2]; +static uint8_t at_shell_match_buf[CONFIG_MODEM_AT_SHELL_RESPONSE_MAX_SIZE]; +static const struct shell *at_shell_active_shell; +static struct k_work at_shell_open_pipe_work; +static struct k_work at_shell_attach_chat_work; +static struct k_work at_shell_release_chat_work; +static atomic_t at_shell_state; + +static void at_shell_print_any_match(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + if (at_shell_active_shell == NULL) { + return; + } + + if (argc != 2) { + return; + } + + shell_print(at_shell_active_shell, "%s", argv[1]); +} + +static void at_shell_print_match(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + if (at_shell_active_shell == NULL) { + return; + } + + if (argc != 1) { + return; + } + + shell_print(at_shell_active_shell, "%s", argv[0]); +} + +MODEM_CHAT_MATCHES_DEFINE( + at_shell_abort_matches, + MODEM_CHAT_MATCH("ERROR", "", at_shell_print_match), +); + +static void at_shell_script_callback(struct modem_chat *chat, + enum modem_chat_script_result result, + void *user_data) +{ + atomic_clear_bit(&at_shell_state, AT_SHELL_STATE_SCRIPT_RUNNING_BIT); +} + +MODEM_CHAT_SCRIPT_DEFINE( + at_shell_script, + at_shell_script_chat, + at_shell_abort_matches, + at_shell_script_callback, + CONFIG_MODEM_AT_SHELL_RESPONSE_TIMEOUT_S +); + +static void at_shell_pipe_callback(struct modem_pipe *pipe, + enum modem_pipe_event event, + void *user_data) +{ + ARG_UNUSED(user_data); + + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + LOG_INF("pipe opened"); + k_work_submit(&at_shell_attach_chat_work); + break; + + default: + break; + } +} + +void at_shell_pipelink_callback(struct modem_pipelink *link, + enum modem_pipelink_event event, + void *user_data) +{ + ARG_UNUSED(user_data); + + switch (event) { + case MODEM_PIPELINK_EVENT_CONNECTED: + LOG_INF("pipe connected"); + k_work_submit(&at_shell_open_pipe_work); + break; + + case MODEM_PIPELINK_EVENT_DISCONNECTED: + LOG_INF("pipe disconnected"); + k_work_submit(&at_shell_release_chat_work); + break; + + default: + break; + } +} + +static void at_shell_open_pipe_handler(struct k_work *work) +{ + ARG_UNUSED(work); + + LOG_INF("opening pipe"); + + modem_pipe_attach(modem_pipelink_get_pipe(at_shell_pipelink), + at_shell_pipe_callback, + NULL); + + modem_pipe_open_async(modem_pipelink_get_pipe(at_shell_pipelink)); +} + +static void at_shell_attach_chat_handler(struct k_work *work) +{ + ARG_UNUSED(work); + + modem_chat_attach(&at_shell_chat, modem_pipelink_get_pipe(at_shell_pipelink)); + atomic_set_bit(&at_shell_state, AT_SHELL_STATE_ATTACHED_BIT); + LOG_INF("chat attached"); +} + +static void at_shell_release_chat_handler(struct k_work *work) +{ + ARG_UNUSED(work); + + modem_chat_release(&at_shell_chat); + atomic_clear_bit(&at_shell_state, AT_SHELL_STATE_ATTACHED_BIT); + LOG_INF("chat released"); +} + +static void at_shell_init_work(void) +{ + k_work_init(&at_shell_open_pipe_work, at_shell_open_pipe_handler); + k_work_init(&at_shell_attach_chat_work, at_shell_attach_chat_handler); + k_work_init(&at_shell_release_chat_work, at_shell_release_chat_handler); +} + +static void at_shell_init_chat(void) +{ + const struct modem_chat_config at_shell_chat_config = { + .receive_buf = at_shell_chat_receive_buf, + .receive_buf_size = sizeof(at_shell_chat_receive_buf), + .delimiter = "\r", + .delimiter_size = sizeof("\r") - 1, + .filter = "\n", + .filter_size = sizeof("\n") - 1, + .argv = at_shell_chat_argv_buf, + .argv_size = ARRAY_SIZE(at_shell_chat_argv_buf), + }; + + modem_chat_init(&at_shell_chat, &at_shell_chat_config); +} + +static void at_shell_init_script_chat(void) +{ + /* Match anything except the expected response without progressing script */ + modem_chat_match_init(&at_shell_script_chat_matches[0]); + modem_chat_match_set_match(&at_shell_script_chat_matches[0], ""); + modem_chat_match_set_separators(&at_shell_script_chat_matches[0], ""); + modem_chat_match_set_callback(&at_shell_script_chat_matches[0], at_shell_print_any_match); + modem_chat_match_set_partial(&at_shell_script_chat_matches[0], true); + modem_chat_match_enable_wildcards(&at_shell_script_chat_matches[0], false); + + /* Match the expected response and terminate script */ + modem_chat_match_init(&at_shell_script_chat_matches[1]); + modem_chat_match_set_match(&at_shell_script_chat_matches[1], ""); + modem_chat_match_set_separators(&at_shell_script_chat_matches[1], ""); + modem_chat_match_set_callback(&at_shell_script_chat_matches[1], at_shell_print_match); + modem_chat_match_set_partial(&at_shell_script_chat_matches[1], false); + modem_chat_match_enable_wildcards(&at_shell_script_chat_matches[1], false); + + modem_chat_script_chat_init(at_shell_script_chat); + modem_chat_script_chat_set_response_matches(at_shell_script_chat, + at_shell_script_chat_matches, + ARRAY_SIZE(at_shell_script_chat_matches)); + modem_chat_script_chat_set_timeout(at_shell_script_chat, + CONFIG_MODEM_AT_SHELL_RESPONSE_TIMEOUT_S); +} + +static void at_shell_init_pipelink(void) +{ + modem_pipelink_attach(at_shell_pipelink, at_shell_pipelink_callback, NULL); +} + +static int at_shell_init(void) +{ + at_shell_init_work(); + at_shell_init_chat(); + at_shell_init_script_chat(); + at_shell_init_pipelink(); + return 0; +} + +SYS_INIT(at_shell_init, POST_KERNEL, 99); + +static int at_shell_cmd_handler(const struct shell *sh, size_t argc, char **argv) +{ + int ret; + + if (argc < 2) { + return -EINVAL; + } + + if (!atomic_test_bit(&at_shell_state, AT_SHELL_STATE_ATTACHED_BIT)) { + shell_error(sh, "modem is not ready"); + return -EPERM; + } + + if (atomic_test_and_set_bit(&at_shell_state, AT_SHELL_STATE_SCRIPT_RUNNING_BIT)) { + shell_error(sh, "script is already running"); + return -EBUSY; + } + + strncpy(at_shell_request_buf, argv[1], sizeof(at_shell_request_buf) - 1); + ret = modem_chat_script_chat_set_request(at_shell_script_chat, at_shell_request_buf); + if (ret < 0) { + return -EINVAL; + } + + if (argc == 3) { + strncpy(at_shell_match_buf, argv[2], sizeof(at_shell_match_buf) - 1); + } else { + strncpy(at_shell_match_buf, "OK", sizeof(at_shell_match_buf) - 1); + } + + ret = modem_chat_match_set_match(&at_shell_script_chat_matches[1], at_shell_match_buf); + if (ret < 0) { + return -EINVAL; + } + + at_shell_active_shell = sh; + + ret = modem_chat_run_script_async(&at_shell_chat, &at_shell_script); + if (ret < 0) { + shell_error(sh, "failed to start script"); + atomic_clear_bit(&at_shell_state, AT_SHELL_STATE_SCRIPT_RUNNING_BIT); + } + + return ret; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(modem_sub_cmds, + SHELL_CMD_ARG(at, NULL, "at ", at_shell_cmd_handler, 1, 2), + SHELL_SUBCMD_SET_END +); + +SHELL_CMD_REGISTER(modem, &modem_sub_cmds, "Modem commands", NULL); diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 8bb96424102e07..a3622adf2f4996 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,8 @@ LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL); #define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (65) #define MODEM_CELLULAR_DATA_FW_VERSION_LEN (65) +#define MODEM_CELLULAR_RESERVED_DLCIS (2) + /* Magic constants */ #define CSQ_RSSI_UNKNOWN (99) #define CESQ_RSRP_UNKNOWN (255) @@ -86,6 +89,7 @@ struct modem_cellular_data { struct modem_cmux cmux; uint8_t cmux_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE]; uint8_t cmux_transmit_buf[2 * CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE]; + struct modem_cmux_dlci dlci1; struct modem_cmux_dlci dlci2; struct modem_pipe *dlci1_pipe; @@ -132,6 +136,15 @@ struct modem_cellular_data { struct k_mutex event_rb_lock; }; +struct modem_cellular_user_pipe { + struct modem_cmux_dlci dlci; + uint8_t dlci_address; + uint8_t *dlci_receive_buf; + uint16_t dlci_receive_buf_size; + struct modem_pipe *pipe; + struct modem_pipelink *pipelink; +}; + struct modem_cellular_config { const struct device *uart; struct gpio_dt_spec power_gpio; @@ -144,6 +157,8 @@ struct modem_cellular_config { const struct modem_chat_script *init_chat_script; const struct modem_chat_script *dial_chat_script; const struct modem_chat_script *periodic_chat_script; + struct modem_cellular_user_pipe *user_pipes; + uint8_t user_pipes_size; }; static const char *modem_cellular_state_str(enum modem_cellular_state state) @@ -219,6 +234,34 @@ static bool modem_cellular_gpio_is_enabled(const struct gpio_dt_spec *gpio) return gpio->port != NULL; } +static void modem_cellular_notify_user_pipes_connected(struct modem_cellular_data *data) +{ + const struct modem_cellular_config *config = + (const struct modem_cellular_config *)data->dev->config; + struct modem_cellular_user_pipe *user_pipe; + struct modem_pipelink *pipelink; + + for (uint8_t i = 0; i < config->user_pipes_size; i++) { + user_pipe = &config->user_pipes[i]; + pipelink = user_pipe->pipelink; + modem_pipelink_notify_connected(pipelink); + } +} + +static void modem_cellular_notify_user_pipes_disconnected(struct modem_cellular_data *data) +{ + const struct modem_cellular_config *config = + (const struct modem_cellular_config *)data->dev->config; + struct modem_cellular_user_pipe *user_pipe; + struct modem_pipelink *pipelink; + + for (uint8_t i = 0; i < config->user_pipes_size; i++) { + user_pipe = &config->user_pipes[i]; + pipelink = user_pipe->pipelink; + modem_pipelink_notify_disconnected(pipelink); + } +} + static void modem_cellular_enter_state(struct modem_cellular_data *data, enum modem_cellular_state state); @@ -530,6 +573,7 @@ static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data) gpio_pin_set_dt(&config->reset_gpio, 1); } + modem_cellular_notify_user_pipes_disconnected(data); modem_chat_release(&data->chat); modem_ppp_release(data->ppp); modem_cmux_release(&data->cmux); @@ -766,6 +810,7 @@ static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data break; case MODEM_CELLULAR_EVENT_CMUX_CONNECTED: + modem_cellular_notify_user_pipes_connected(data); modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI1); break; @@ -994,6 +1039,7 @@ static void modem_cellular_init_power_off_event_handler(struct modem_cellular_da static int modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data *data) { + modem_cellular_notify_user_pipes_disconnected(data); modem_chat_release(&data->chat); modem_ppp_release(data->ppp); return 0; @@ -1560,6 +1606,20 @@ static int modem_cellular_init(const struct device *dev) &dlci2_config); } + for (uint8_t i = 0; i < config->user_pipes_size; i++) { + struct modem_cellular_user_pipe *user_pipe = &config->user_pipes[i]; + const struct modem_cmux_dlci_config user_dlci_config = { + .dlci_address = user_pipe->dlci_address, + .receive_buf = user_pipe->dlci_receive_buf, + .receive_buf_size = user_pipe->dlci_receive_buf_size, + }; + + user_pipe->pipe = modem_cmux_dlci_init(&data->cmux, &user_pipe->dlci, + &user_dlci_config); + + modem_pipelink_init(user_pipe->pipelink, user_pipe->pipe); + } + { const struct modem_chat_config chat_config = { .user_data = data, @@ -2027,7 +2087,27 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, #endif #define MODEM_CELLULAR_INST_NAME(name, inst) \ - _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) + _CONCAT_4(name, _, DT_DRV_COMPAT, inst) + +#define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size) \ + MODEM_PIPELINK_DT_INST_DEFINE(inst, name); \ + static uint8_t MODEM_CELLULAR_INST_NAME(name, inst)[size] \ + +#define MODEM_CELLULAR_INIT_USER_PIPE(_inst, _name, _dlci_address) \ + { \ + .dlci_address = _dlci_address, \ + .dlci_receive_buf = MODEM_CELLULAR_INST_NAME(_name, _inst), \ + .dlci_receive_buf_size = sizeof(MODEM_CELLULAR_INST_NAME(_name, _inst)), \ + .pipelink = MODEM_PIPELINK_DT_INST_GET(_inst, _name), \ + } + +#define MODEM_CELLULAR_DEFINE_USER_PIPES(inst, ...) \ + static struct modem_cellular_user_pipe MODEM_CELLULAR_INST_NAME(user_pipes, inst)[] = { \ + __VA_ARGS__ \ + } + +#define MODEM_CELLULAR_GET_USER_PIPES(inst) \ + MODEM_CELLULAR_INST_NAME(user_pipes, inst) #define MODEM_CELLULAR_DEVICE_QUECTEL_BG95(inst) \ MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ @@ -2038,6 +2118,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2049,6 +2154,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &quectel_bg95_init_chat_script, \ .dial_chat_script = &quectel_bg95_dial_chat_script, \ .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2067,6 +2174,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2078,6 +2210,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &quectel_eg25_g_init_chat_script, \ .dial_chat_script = &quectel_eg25_g_dial_chat_script, \ .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2096,6 +2230,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2107,6 +2266,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &simcom_sim7080_init_chat_script, \ .dial_chat_script = &simcom_sim7080_dial_chat_script, \ .periodic_chat_script = &simcom_sim7080_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2125,6 +2286,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2136,6 +2322,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &u_blox_sara_r4_init_chat_script, \ .dial_chat_script = &u_blox_sara_r4_dial_chat_script, \ .periodic_chat_script = &u_blox_sara_r4_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2154,6 +2342,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2166,6 +2379,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &u_blox_sara_r5_init_chat_script, \ .dial_chat_script = &u_blox_sara_r5_dial_chat_script, \ .periodic_chat_script = &u_blox_sara_r5_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2184,6 +2399,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2195,6 +2435,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &swir_hl7800_init_chat_script, \ .dial_chat_script = &swir_hl7800_dial_chat_script, \ .periodic_chat_script = &swir_hl7800_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2213,6 +2455,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2224,6 +2491,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &telit_me910g1_init_chat_script, \ .dial_chat_script = &telit_me910g1_dial_chat_script, \ .periodic_chat_script = &telit_me910g1_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2241,6 +2510,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2252,6 +2546,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &nordic_nrf91_slm_init_chat_script, \ .dial_chat_script = &nordic_nrf91_slm_dial_chat_script, \ .periodic_chat_script = &nordic_nrf91_slm_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ @@ -2270,6 +2566,31 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + gnss_pipe, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_0, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \ + inst, \ + user_pipe_1, \ + CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \ + ); \ + \ + MODEM_CELLULAR_DEFINE_USER_PIPES( \ + inst, \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \ + MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 5), \ + ); \ + \ static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \ .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ @@ -2282,6 +2603,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .init_chat_script = &sqn_gm02s_init_chat_script, \ .dial_chat_script = &sqn_gm02s_dial_chat_script, \ .periodic_chat_script = &sqn_gm02s_periodic_chat_script, \ + .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \ + .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \ }; \ \ PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \ diff --git a/drivers/net/nsos.h b/drivers/net/nsos.h index 911e49dff2c3e5..f1e2f12eb553f9 100644 --- a/drivers/net/nsos.h +++ b/drivers/net/nsos.h @@ -140,6 +140,8 @@ int nsos_adapt_fcntl_setfl(int fd, int flags); int nsos_adapt_fionread(int fd, int *avail); +int nsos_adapt_dup(int oldfd); + int nsos_adapt_getaddrinfo(const char *node, const char *service, const struct nsos_mid_addrinfo *hints, struct nsos_mid_addrinfo **res, diff --git a/drivers/net/nsos_adapt.c b/drivers/net/nsos_adapt.c index af9acd1e40e7ee..91be0b4cf5b482 100644 --- a/drivers/net/nsos_adapt.c +++ b/drivers/net/nsos_adapt.c @@ -692,6 +692,22 @@ int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname, return 0; } + case NSOS_MID_SO_SNDTIMEO: { + const struct nsos_mid_timeval *nsos_mid_tv = nsos_mid_optval; + struct timeval tv = { + .tv_sec = nsos_mid_tv->tv_sec, + .tv_usec = nsos_mid_tv->tv_usec, + }; + int ret; + + ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, + &tv, sizeof(tv)); + if (ret < 0) { + return -errno_to_nsos_mid(errno); + } + + return 0; + } case NSOS_MID_SO_RCVBUF: return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF, nsos_mid_optval, nsos_mid_optlen); @@ -1001,6 +1017,18 @@ int nsos_adapt_fionread(int fd, int *avail) return 0; } +int nsos_adapt_dup(int oldfd) +{ + int ret; + + ret = dup(oldfd); + if (ret < 0) { + return -errno_to_nsos_mid(errno); + } + + return ret; +} + static void nsos_adapt_init(void) { nsos_epoll_fd = epoll_create(1); diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c index 1c7df2af830d9d..1e6c03abca8c9b 100644 --- a/drivers/net/nsos_sockets.c +++ b/drivers/net/nsos_sockets.c @@ -13,6 +13,9 @@ #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L +#include +LOG_MODULE_REGISTER(nsos_sockets); + #include #include #include @@ -37,17 +40,25 @@ BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE > 0); #define NSOS_IRQ_FLAGS (0) #define NSOS_IRQ_PRIORITY (2) +struct nsos_socket; + +struct nsos_socket_poll { + struct nsos_mid_pollfd mid; + struct k_poll_signal signal; + + sys_dnode_t node; +}; + struct nsos_socket { int fd; - struct nsos_mid_pollfd pollfd; - struct k_poll_signal poll; k_timeout_t recv_timeout; + k_timeout_t send_timeout; - sys_dnode_t node; + struct nsos_socket_poll poll; }; -static sys_dlist_t nsos_sockets = SYS_DLIST_STATIC_INIT(&nsos_sockets); +static sys_dlist_t nsos_polls = SYS_DLIST_STATIC_INIT(&nsos_polls); static int socket_family_to_nsos_mid(int family, int *family_mid) { @@ -183,10 +194,11 @@ static int nsos_socket_create(int family, int type, int proto) sock->fd = fd; sock->recv_timeout = K_FOREVER; + sock->send_timeout = K_FOREVER; - sock->pollfd.fd = nsos_adapt_socket(family_mid, type_mid, proto_mid); - if (sock->pollfd.fd < 0) { - errno = errno_from_nsos_mid(-sock->pollfd.fd); + sock->poll.mid.fd = nsos_adapt_socket(family_mid, type_mid, proto_mid); + if (sock->poll.mid.fd < 0) { + errno = errno_from_nsos_mid(-sock->poll.mid.fd); goto free_sock; } @@ -213,7 +225,7 @@ static ssize_t nsos_read(void *obj, void *buf, size_t sz) struct nsos_socket *sock = obj; int ret; - ret = nsi_host_read(sock->pollfd.fd, buf, sz); + ret = nsi_host_read(sock->poll.mid.fd, buf, sz); if (ret < 0) { errno = nsos_adapt_get_zephyr_errno(); } @@ -226,7 +238,7 @@ static ssize_t nsos_write(void *obj, const void *buf, size_t sz) struct nsos_socket *sock = obj; int ret; - ret = nsi_host_write(sock->pollfd.fd, buf, sz); + ret = nsi_host_write(sock->poll.mid.fd, buf, sz); if (ret < 0) { errno = nsos_adapt_get_zephyr_errno(); } @@ -239,7 +251,7 @@ static int nsos_close(void *obj) struct nsos_socket *sock = obj; int ret; - ret = nsi_host_close(sock->pollfd.fd); + ret = nsi_host_close(sock->poll.mid.fd); if (ret < 0) { errno = nsos_adapt_get_zephyr_errno(); } @@ -247,33 +259,34 @@ static int nsos_close(void *obj) return ret; } -static void pollcb(struct nsos_mid_pollfd *pollfd) +static void pollcb(struct nsos_mid_pollfd *mid) { - struct nsos_socket *sock = CONTAINER_OF(pollfd, struct nsos_socket, pollfd); + struct nsos_socket_poll *poll = CONTAINER_OF(mid, struct nsos_socket_poll, mid); - k_poll_signal_raise(&sock->poll, sock->pollfd.revents); + k_poll_signal_raise(&poll->signal, poll->mid.revents); } static int nsos_poll_prepare(struct nsos_socket *sock, struct zsock_pollfd *pfd, - struct k_poll_event **pev, struct k_poll_event *pev_end) + struct k_poll_event **pev, struct k_poll_event *pev_end, + struct nsos_socket_poll *poll) { unsigned int signaled; int flags; - sock->pollfd.events = pfd->events; - sock->pollfd.revents = 0; - sock->pollfd.cb = pollcb; + poll->mid.events = pfd->events; + poll->mid.revents = 0; + poll->mid.cb = pollcb; if (*pev == pev_end) { return -ENOMEM; } - k_poll_signal_init(&sock->poll); - k_poll_event_init(*pev, K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &sock->poll); + k_poll_signal_init(&poll->signal); + k_poll_event_init(*pev, K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &poll->signal); - sys_dlist_append(&nsos_sockets, &sock->node); + sys_dlist_append(&nsos_polls, &poll->node); - nsos_adapt_poll_add(&sock->pollfd); + nsos_adapt_poll_add(&poll->mid); /* Let other sockets use another k_poll_event */ (*pev)++; @@ -281,7 +294,7 @@ static int nsos_poll_prepare(struct nsos_socket *sock, struct zsock_pollfd *pfd, signaled = 0; flags = 0; - k_poll_signal_check(&sock->poll, &signaled, &flags); + k_poll_signal_check(&poll->signal, &signaled, &flags); if (!signaled) { return 0; } @@ -291,7 +304,7 @@ static int nsos_poll_prepare(struct nsos_socket *sock, struct zsock_pollfd *pfd, } static int nsos_poll_update(struct nsos_socket *sock, struct zsock_pollfd *pfd, - struct k_poll_event **pev) + struct k_poll_event **pev, struct nsos_socket_poll *poll) { unsigned int signaled; int flags; @@ -301,15 +314,15 @@ static int nsos_poll_update(struct nsos_socket *sock, struct zsock_pollfd *pfd, signaled = 0; flags = 0; - if (!sys_dnode_is_linked(&sock->node)) { - nsos_adapt_poll_update(&sock->pollfd); + if (!sys_dnode_is_linked(&poll->node)) { + nsos_adapt_poll_update(&poll->mid); return 0; } - nsos_adapt_poll_remove(&sock->pollfd); - sys_dlist_remove(&sock->node); + nsos_adapt_poll_remove(&poll->mid); + sys_dlist_remove(&poll->node); - k_poll_signal_check(&sock->poll, &signaled, &flags); + k_poll_signal_check(&poll->signal, &signaled, &flags); if (!signaled) { return 0; } @@ -333,7 +346,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args) pev = va_arg(args, struct k_poll_event **); pev_end = va_arg(args, struct k_poll_event *); - return nsos_poll_prepare(obj, pfd, pev, pev_end); + return nsos_poll_prepare(obj, pfd, pev, pev_end, &sock->poll); } case ZFD_IOCTL_POLL_UPDATE: { @@ -343,7 +356,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args) pfd = va_arg(args, struct zsock_pollfd *); pev = va_arg(args, struct k_poll_event **); - return nsos_poll_update(obj, pfd, pev); + return nsos_poll_update(obj, pfd, pev, &sock->poll); } case ZFD_IOCTL_POLL_OFFLOAD: @@ -352,7 +365,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args) case F_GETFL: { int flags; - flags = nsos_adapt_fcntl_getfl(sock->pollfd.fd); + flags = nsos_adapt_fcntl_getfl(sock->poll.mid.fd); return fl_from_nsos_mid(flags); } @@ -366,7 +379,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args) return -errno_from_nsos_mid(-ret); } - ret = nsos_adapt_fcntl_setfl(sock->pollfd.fd, flags); + ret = nsos_adapt_fcntl_setfl(sock->poll.mid.fd, flags); return -errno_from_nsos_mid(-ret); } @@ -375,7 +388,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args) int *avail = va_arg(args, int *); int ret; - ret = nsos_adapt_fionread(sock->pollfd.fd, avail); + ret = nsos_adapt_fionread(sock->poll.mid.fd, avail); return -errno_from_nsos_mid(-ret); } @@ -481,31 +494,77 @@ static int sockaddr_from_nsos_mid(struct sockaddr *addr, socklen_t *addrlen, return -NSOS_MID_EINVAL; } -static int nsos_bind(void *obj, const struct sockaddr *addr, socklen_t addrlen) +static int nsos_wait_for_poll(struct nsos_socket *sock, int events, + k_timeout_t timeout) { - struct nsos_socket *sock = obj; - struct nsos_mid_sockaddr_storage addr_storage_mid; - struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid; - size_t addrlen_mid; + struct zsock_pollfd pfd = { + .fd = sock->fd, + .events = events, + }; + struct k_poll_event poll_events[1]; + struct k_poll_event *pev = poll_events; + struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); + struct nsos_socket_poll socket_poll = {}; int ret; - ret = sockaddr_to_nsos_mid(addr, addrlen, &addr_mid, &addrlen_mid); + ret = nsos_adapt_dup(sock->poll.mid.fd); if (ret < 0) { goto return_ret; } - ret = nsos_adapt_bind(sock->pollfd.fd, addr_mid, addrlen_mid); + socket_poll.mid.fd = ret; + + ret = nsos_poll_prepare(sock, &pfd, &pev, pev_end, &socket_poll); + if (ret == -EALREADY) { + ret = 0; + goto poll_update; + } else if (ret < 0) { + goto close_dup; + } + + ret = k_poll(poll_events, ARRAY_SIZE(poll_events), timeout); + if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { + goto poll_update; + } + + ret = 0; + +poll_update: + pev = poll_events; + nsos_poll_update(sock, &pfd, &pev, &socket_poll); + +close_dup: + nsi_host_close(socket_poll.mid.fd); return_ret: if (ret < 0) { - errno = errno_from_nsos_mid(-ret); - return -1; + return -errno_to_nsos_mid(-ret); } - return ret; + return 0; } -static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrlen) +static int nsos_poll_if_blocking(struct nsos_socket *sock, int events, + k_timeout_t timeout, int flags) +{ + int sock_flags; + bool non_blocking; + + if (flags & ZSOCK_MSG_DONTWAIT) { + non_blocking = true; + } else { + sock_flags = nsos_adapt_fcntl_getfl(sock->poll.mid.fd); + non_blocking = sock_flags & NSOS_MID_O_NONBLOCK; + } + + if (!non_blocking) { + return nsos_wait_for_poll(sock, events, timeout); + } + + return 0; +} + +static int nsos_bind(void *obj, const struct sockaddr *addr, socklen_t addrlen) { struct nsos_socket *sock = obj; struct nsos_mid_sockaddr_storage addr_storage_mid; @@ -518,7 +577,7 @@ static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrle goto return_ret; } - ret = nsos_adapt_connect(sock->pollfd.fd, addr_mid, addrlen_mid); + ret = nsos_adapt_bind(sock->poll.mid.fd, addr_mid, addrlen_mid); return_ret: if (ret < 0) { @@ -529,68 +588,87 @@ static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrle return ret; } -static int nsos_listen(void *obj, int backlog) +static int nsos_connect_blocking(struct nsos_socket *sock, + struct nsos_mid_sockaddr *addr_mid, + size_t addrlen_mid, + int fcntl_flags) { - struct nsos_socket *sock = obj; + int clear_nonblock_ret; int ret; - ret = nsos_adapt_listen(sock->pollfd.fd, backlog); + ret = nsos_adapt_fcntl_setfl(sock->poll.mid.fd, fcntl_flags | NSOS_MID_O_NONBLOCK); if (ret < 0) { - errno = errno_from_nsos_mid(-ret); - return -1; + return ret; + } + + ret = nsos_adapt_connect(sock->poll.mid.fd, addr_mid, addrlen_mid); + if (ret == -NSOS_MID_EINPROGRESS) { + int so_err; + size_t so_err_len = sizeof(so_err); + + ret = nsos_wait_for_poll(sock, ZSOCK_POLLOUT, sock->send_timeout); + if (ret < 0) { + goto clear_nonblock; + } + + ret = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, + NSOS_MID_SO_ERROR, &so_err, &so_err_len); + if (ret < 0) { + goto clear_nonblock; + } + + ret = so_err; + } + +clear_nonblock: + clear_nonblock_ret = nsos_adapt_fcntl_setfl(sock->poll.mid.fd, fcntl_flags); + if (clear_nonblock_ret < 0) { + LOG_ERR("Failed to clear O_NONBLOCK: %d", clear_nonblock_ret); } return ret; } -static int nsos_wait_for_pollin(struct nsos_socket *sock) +static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrlen) { - struct zsock_pollfd pfd = { - .fd = sock->fd, - .events = ZSOCK_POLLIN, - }; - struct k_poll_event poll_events[1]; - struct k_poll_event *pev = poll_events; - struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); + struct nsos_socket *sock = obj; + struct nsos_mid_sockaddr_storage addr_storage_mid; + struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid; + size_t addrlen_mid; + int flags; int ret; - ret = nsos_poll_prepare(sock, &pfd, &pev, pev_end); - if (ret == -EALREADY) { - return 0; - } else if (ret < 0) { - return ret; + ret = sockaddr_to_nsos_mid(addr, addrlen, &addr_mid, &addrlen_mid); + if (ret < 0) { + goto return_ret; } - ret = k_poll(poll_events, ARRAY_SIZE(poll_events), sock->recv_timeout); - if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { - return ret; + flags = nsos_adapt_fcntl_getfl(sock->poll.mid.fd); + + if (flags & NSOS_MID_O_NONBLOCK) { + ret = nsos_adapt_connect(sock->poll.mid.fd, addr_mid, addrlen_mid); + } else { + ret = nsos_connect_blocking(sock, addr_mid, addrlen_mid, flags); } - pev = poll_events; - nsos_poll_update(sock, &pfd, &pev); +return_ret: + if (ret < 0) { + errno = errno_from_nsos_mid(-ret); + return -1; + } - return 0; + return ret; } -static int nsos_accept_with_poll(struct nsos_socket *sock, - struct nsos_mid_sockaddr *addr_mid, - size_t *addrlen_mid) +static int nsos_listen(void *obj, int backlog) { - int ret = 0; - int flags; - - flags = nsos_adapt_fcntl_getfl(sock->pollfd.fd); - - if (!(flags & NSOS_MID_O_NONBLOCK)) { - ret = nsos_wait_for_pollin(sock); - if (ret < 0) { - return ret; - } - } + struct nsos_socket *sock = obj; + int ret; - ret = nsos_adapt_accept(sock->pollfd.fd, addr_mid, addrlen_mid); + ret = nsos_adapt_listen(sock->poll.mid.fd, backlog); if (ret < 0) { - return -errno_from_nsos_mid(-ret); + errno = errno_from_nsos_mid(-ret); + return -1; } return ret; @@ -607,34 +685,38 @@ static int nsos_accept(void *obj, struct sockaddr *addr, socklen_t *addrlen) struct nsos_socket *conn_sock; int ret; - ret = nsos_accept_with_poll(accept_sock, addr_mid, &addrlen_mid); + ret = nsos_poll_if_blocking(accept_sock, ZSOCK_POLLIN, + accept_sock->recv_timeout, 0); if (ret < 0) { - errno = errno_from_nsos_mid(-ret); - return -1; + goto return_ret; + } + + ret = nsos_adapt_accept(accept_sock->poll.mid.fd, addr_mid, &addrlen_mid); + if (ret < 0) { + goto return_ret; } adapt_fd = ret; ret = sockaddr_from_nsos_mid(addr, addrlen, addr_mid, addrlen_mid); if (ret < 0) { - errno = errno_from_nsos_mid(-ret); goto close_adapt_fd; } zephyr_fd = z_reserve_fd(); if (zephyr_fd < 0) { - errno = -zephyr_fd; + ret = -errno_to_nsos_mid(-zephyr_fd); goto close_adapt_fd; } conn_sock = k_malloc(sizeof(*conn_sock)); if (!conn_sock) { - errno = ENOMEM; + ret = -NSOS_MID_ENOMEM; goto free_zephyr_fd; } conn_sock->fd = zephyr_fd; - conn_sock->pollfd.fd = adapt_fd; + conn_sock->poll.mid.fd = adapt_fd; z_finalize_fd(zephyr_fd, conn_sock, &nsos_socket_fd_op_vtable.fd_vtable); @@ -646,6 +728,8 @@ static int nsos_accept(void *obj, struct sockaddr *addr, socklen_t *addrlen) close_adapt_fd: nsi_host_close(adapt_fd); +return_ret: + errno = errno_from_nsos_mid(-ret); return -1; } @@ -671,7 +755,12 @@ static ssize_t nsos_sendto(void *obj, const void *buf, size_t len, int flags, goto return_ret; } - ret = nsos_adapt_sendto(sock->pollfd.fd, buf, len, flags_mid, + ret = nsos_poll_if_blocking(sock, ZSOCK_POLLOUT, sock->send_timeout, flags); + if (ret < 0) { + goto return_ret; + } + + ret = nsos_adapt_sendto(sock->poll.mid.fd, buf, len, flags_mid, addr_mid, addrlen_mid); return_ret: @@ -725,8 +814,14 @@ static ssize_t nsos_sendmsg(void *obj, const struct msghdr *msg, int flags) msg_mid.msg_controllen = 0; msg_mid.msg_flags = 0; - ret = nsos_adapt_sendmsg(sock->pollfd.fd, &msg_mid, flags_mid); + ret = nsos_poll_if_blocking(sock, ZSOCK_POLLOUT, sock->send_timeout, flags); + if (ret < 0) { + goto free_msg_iov; + } + + ret = nsos_adapt_sendmsg(sock->poll.mid.fd, &msg_mid, flags_mid); +free_msg_iov: k_free(msg_iov); return_ret: @@ -738,36 +833,6 @@ static ssize_t nsos_sendmsg(void *obj, const struct msghdr *msg, int flags) return ret; } -static int nsos_recvfrom_with_poll(struct nsos_socket *sock, void *buf, size_t len, int flags, - struct nsos_mid_sockaddr *addr_mid, size_t *addrlen_mid) -{ - int ret = 0; - int sock_flags; - bool non_blocking; - - if (flags & ZSOCK_MSG_DONTWAIT) { - non_blocking = true; - } else { - sock_flags = nsos_adapt_fcntl_getfl(sock->pollfd.fd); - non_blocking = sock_flags & NSOS_MID_O_NONBLOCK; - } - - if (!non_blocking) { - ret = nsos_wait_for_pollin(sock); - if (ret < 0) { - return ret; - } - } - - ret = nsos_adapt_recvfrom(sock->pollfd.fd, buf, len, flags, - addr_mid, addrlen_mid); - if (ret < 0) { - return -errno_from_nsos_mid(-ret); - } - - return ret; -} - static ssize_t nsos_recvfrom(void *obj, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen) { @@ -785,8 +850,13 @@ static ssize_t nsos_recvfrom(void *obj, void *buf, size_t len, int flags, flags_mid = ret; - ret = nsos_recvfrom_with_poll(sock, buf, len, flags_mid, - addr_mid, &addrlen_mid); + ret = nsos_poll_if_blocking(sock, ZSOCK_POLLIN, sock->recv_timeout, flags); + if (ret < 0) { + goto return_ret; + } + + ret = nsos_adapt_recvfrom(sock->poll.mid.fd, buf, len, flags_mid, + addr_mid, &addrlen_mid); if (ret < 0) { goto return_ret; } @@ -891,7 +961,7 @@ static int nsos_getsockopt_int(struct nsos_socket *sock, int nsos_mid_level, int return -1; } - err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_KEEPALIVE, optval, &nsos_mid_optlen); if (err) { errno = errno_from_nsos_mid(-err); @@ -920,7 +990,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, return -1; } - err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_ERROR, &nsos_mid_err, NULL); if (err) { errno = errno_from_nsos_mid(-err); @@ -940,7 +1010,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, return -1; } - err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_TYPE, &nsos_mid_type, NULL); if (err) { errno = errno_from_nsos_mid(-err); @@ -964,7 +1034,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, return -1; } - err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_PROTOCOL, &nsos_mid_proto, NULL); if (err) { errno = errno_from_nsos_mid(-err); @@ -988,7 +1058,7 @@ static int nsos_getsockopt(void *obj, int level, int optname, return -1; } - err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_getsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_DOMAIN, &nsos_mid_family, NULL); if (err) { errno = errno_from_nsos_mid(-err); @@ -1068,7 +1138,7 @@ static int nsos_setsockopt_int(struct nsos_socket *sock, int nsos_mid_level, int return -1; } - err = nsos_adapt_setsockopt(sock->pollfd.fd, nsos_mid_level, nsos_mid_optname, + err = nsos_adapt_setsockopt(sock->poll.mid.fd, nsos_mid_level, nsos_mid_optname, optval, optlen); if (err) { errno = errno_from_nsos_mid(-err); @@ -1097,7 +1167,7 @@ static int nsos_setsockopt(void *obj, int level, int optname, nsos_mid_priority = *(uint8_t *)optval; - err = nsos_adapt_setsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_setsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_PRIORITY, &nsos_mid_priority, sizeof(nsos_mid_priority)); if (err) { @@ -1120,7 +1190,7 @@ static int nsos_setsockopt(void *obj, int level, int optname, nsos_mid_tv.tv_sec = tv->tv_sec; nsos_mid_tv.tv_usec = tv->tv_usec; - err = nsos_adapt_setsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET, + err = nsos_adapt_setsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_RCVTIMEO, &nsos_mid_tv, sizeof(nsos_mid_tv)); if (err) { @@ -1136,6 +1206,35 @@ static int nsos_setsockopt(void *obj, int level, int optname, return 0; } + case SO_SNDTIMEO: { + const struct zsock_timeval *tv = optval; + struct nsos_mid_timeval nsos_mid_tv; + int err; + + if (optlen != sizeof(struct zsock_timeval)) { + errno = EINVAL; + return -1; + } + + nsos_mid_tv.tv_sec = tv->tv_sec; + nsos_mid_tv.tv_usec = tv->tv_usec; + + err = nsos_adapt_setsockopt(sock->poll.mid.fd, NSOS_MID_SOL_SOCKET, + NSOS_MID_SO_SNDTIMEO, &nsos_mid_tv, + sizeof(nsos_mid_tv)); + if (err) { + errno = errno_from_nsos_mid(-err); + return -1; + } + + if (tv->tv_sec == 0 && tv->tv_usec == 0) { + sock->send_timeout = K_FOREVER; + } else { + sock->send_timeout = K_USEC(tv->tv_sec * 1000000LL + tv->tv_usec); + } + + return 0; + } case SO_RCVBUF: return nsos_setsockopt_int(sock, NSOS_MID_SOL_SOCKET, NSOS_MID_SO_RCVBUF, @@ -1372,11 +1471,11 @@ static const struct socket_dns_offload nsos_dns_ops = { static void nsos_isr(const void *obj) { - struct nsos_socket *sock; + struct nsos_socket_poll *poll; - SYS_DLIST_FOR_EACH_CONTAINER(&nsos_sockets, sock, node) { - if (sock->pollfd.revents) { - sock->pollfd.cb(&sock->pollfd); + SYS_DLIST_FOR_EACH_CONTAINER(&nsos_polls, poll, node) { + if (poll->mid.revents) { + poll->mid.cb(&poll->mid); } } } diff --git a/drivers/pcie/host/msi.c b/drivers/pcie/host/msi.c index f78f5b171a61a6..7718175159aac6 100644 --- a/drivers/pcie/host/msi.c +++ b/drivers/pcie/host/msi.c @@ -96,9 +96,9 @@ static bool map_msix_table_entries(pcie_bdf_t bdf, return false; } - z_phys_map((uint8_t **)&mapped_table, - bar.phys_addr + table_offset, - n_vector * PCIE_MSIR_TABLE_ENTRY_SIZE, K_MEM_PERM_RW); + k_mem_map_phys_bare((uint8_t **)&mapped_table, + bar.phys_addr + table_offset, + n_vector * PCIE_MSIR_TABLE_ENTRY_SIZE, K_MEM_PERM_RW); for (i = 0; i < n_vector; i++) { vectors[i].msix_vector = (struct msix_vector *) diff --git a/drivers/pinctrl/pinctrl_esp32.c b/drivers/pinctrl/pinctrl_esp32.c index ee3811604511e9..71049f5b1cb5da 100644 --- a/drivers/pinctrl/pinctrl_esp32.c +++ b/drivers/pinctrl/pinctrl_esp32.c @@ -242,12 +242,12 @@ static int esp32_pin_configure(const uint32_t pin_mux, const uint32_t pin_cfg) if (ESP32_PORT_IDX(pin_num) == 0) { gpio_dev_t *const gpio_dev = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0)); - gpio_dev->out_w1ts = pin_num; + gpio_dev->out_w1ts = BIT(pin_num); #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) } else { gpio_dev_t *const gpio_dev = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio1)); - gpio_dev->out1_w1ts.data = pin_num; + gpio_dev->out1_w1ts.data = BIT(pin_num - 32); #endif } } @@ -256,12 +256,12 @@ static int esp32_pin_configure(const uint32_t pin_mux, const uint32_t pin_cfg) if (ESP32_PORT_IDX(pin_num) == 0) { gpio_dev_t *const gpio_dev = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0)); - gpio_dev->out_w1tc = pin_num; + gpio_dev->out_w1tc = BIT(pin_num); #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) } else { gpio_dev_t *const gpio_dev = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio1)); - gpio_dev->out1_w1tc.data = pin_num; + gpio_dev->out1_w1tc.data = BIT(pin_num - 32); #endif } } diff --git a/drivers/pinctrl/pinctrl_ifx_cat1.c b/drivers/pinctrl/pinctrl_ifx_cat1.c index dbeaab855f3007..d1806346a8fa24 100644 --- a/drivers/pinctrl/pinctrl_ifx_cat1.c +++ b/drivers/pinctrl/pinctrl_ifx_cat1.c @@ -10,7 +10,6 @@ */ #include -#include #include #define GPIO_PORT_OR_NULL(node_id) \ diff --git a/drivers/pinctrl/pinctrl_ite_it8xxx2.c b/drivers/pinctrl/pinctrl_ite_it8xxx2.c index 33ed9130b62e2e..f7d71adc43e5f5 100644 --- a/drivers/pinctrl/pinctrl_ite_it8xxx2.c +++ b/drivers/pinctrl/pinctrl_ite_it8xxx2.c @@ -20,6 +20,8 @@ LOG_MODULE_REGISTER(pinctrl_ite_it8xxx2, LOG_LEVEL_ERR); struct pinctrl_it8xxx2_gpio { /* gpio port control register (byte mapping to pin) */ uint8_t *reg_gpcr; + /* port driving select control */ + uint8_t *reg_pdsc; /* function 3 general control register */ uintptr_t func3_gcr[GPIO_GROUP_MEMBERS]; /* function 3 enable mask */ @@ -74,6 +76,7 @@ static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins) uint8_t pin = pins->pin; volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin; volatile uint8_t *reg_volt_sel = (uint8_t *)(gpio->volt_sel[pin]); + volatile uint8_t *reg_pdsc = (uint8_t *)gpio->reg_pdsc; /* Setting pull-up or pull-down. */ switch (IT8XXX2_DT_PINCFG_PUPDR(pincfg)) { @@ -125,6 +128,18 @@ static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins) GPCR_PORT_PIN_MODE_PULLDOWN); } + /* Driving current selection. */ + if (reg_pdsc != NULL && + IT8XXX2_DT_PINCFG_DRIVE_CURRENT(pincfg) != IT8XXX2_DRIVE_DEFAULT) { + if (IT8XXX2_DT_PINCFG_DRIVE_CURRENT(pincfg) & IT8XXX2_PDSCX_MASK) { + /* Driving current selects low. */ + *reg_pdsc |= BIT(pin); + } else { + /* Driving current selects high. */ + *reg_pdsc &= ~BIT(pin); + } + } + return 0; } @@ -366,6 +381,7 @@ static int pinctrl_it8xxx2_init(const struct device *dev) COND_CODE_1(DT_INST_PROP(inst, gpio_group), \ (.gpio = { \ .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .reg_pdsc = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1), \ .func3_gcr = DT_INST_PROP(inst, func3_gcr), \ .func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \ .func3_ext = DT_INST_PROP_OR(inst, func3_ext, {0}), \ diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index 4c2acee81b58a8..17193c160cad1b 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -162,7 +162,10 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, dir = NRF_GPIO_PIN_DIR_OUTPUT; input = NRF_GPIO_PIN_INPUT_DISCONNECT; #if NRF_GPIO_HAS_CLOCKPIN && defined(NRF_SPIM_CLOCKPIN_MOSI_NEEDED) - clockpin = true; + /* CLOCKPIN setting must not be applied to SPIM12x instances. */ + if (!NRF_SPIM_IS_320MHZ_SPIM((void *)reg)) { + clockpin = true; + } #endif break; case NRF_FUN_SPIM_MISO: diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index b6a1b550e8bfb4..9dc3e26f37cca7 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -58,6 +58,11 @@ static const struct device *const gpio_ports[] = { DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpioi)), DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpioj)), DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpiok)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpiol)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpiom)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpion)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpioo)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpiop)), }; /** Number of GPIO ports. */ diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 2ac86d3e38ebc8..3a6eef01236213 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_MCPWM_ESP32 pwm_mc_esp32.c) zephyr_library_sources_ifdef(CONFIG_PWM_SAM pwm_sam.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX pwm_mcux.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_SCTIMER pwm_mcux_sctimer.c) +zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_QTMR pwm_mcux_qtmr.c) zephyr_library_sources_ifdef(CONFIG_PWM_XEC pwm_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_PWM_LITEX pwm_litex.c) zephyr_library_sources_ifdef(CONFIG_PWM_RV32M1_TPM pwm_rv32m1_tpm.c) @@ -39,6 +40,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU4 pwm_xmc4xxx_ccu4.c) zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU8 pwm_xmc4xxx_ccu8.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_CTIMER pwm_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_NUMAKER pwm_numaker.c) +zephyr_library_sources_ifdef(CONFIG_PWM_NXP_FLEXIO pwm_nxp_flexio.c) zephyr_library_sources_ifdef(CONFIG_PWM_NXP_S32_EMIOS pwm_nxp_s32_emios.c) zephyr_library_sources_ifdef(CONFIG_PWM_ENE_KB1200 pwm_ene_kb1200.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index d8a412078f9b6a..002ff4dd2dbeb5 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -58,6 +58,8 @@ source "drivers/pwm/Kconfig.mcux" source "drivers/pwm/Kconfig.mcux_sctimer" +source "drivers/pwm/Kconfig.mcux_qtmr" + source "drivers/pwm/Kconfig.xec" source "drivers/pwm/Kconfig.litex" @@ -100,6 +102,8 @@ source "drivers/pwm/Kconfig.numaker" source "drivers/pwm/Kconfig.nxp_s32_emios" +source "drivers/pwm/Kconfig.nxp_flexio" + source "drivers/pwm/Kconfig.ene" endif # PWM diff --git a/drivers/pwm/Kconfig.mcux_qtmr b/drivers/pwm/Kconfig.mcux_qtmr new file mode 100644 index 00000000000000..bb8329bbdaade2 --- /dev/null +++ b/drivers/pwm/Kconfig.mcux_qtmr @@ -0,0 +1,10 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config PWM_MCUX_QTMR + bool "MCUX QMTR PWM driver" + default y + depends on DT_HAS_NXP_QTMR_PWM_ENABLED + depends on CLOCK_CONTROL && PINCTRL + help + Enable QTMR based pwm driver. diff --git a/drivers/pwm/Kconfig.nxp_flexio b/drivers/pwm/Kconfig.nxp_flexio new file mode 100644 index 00000000000000..a1a47670a91a8f --- /dev/null +++ b/drivers/pwm/Kconfig.nxp_flexio @@ -0,0 +1,12 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config PWM_NXP_FLEXIO + bool "NXP Flexio PWM driver" + default y + depends on DT_HAS_NXP_FLEXIO_ENABLED + depends on CLOCK_CONTROL + depends on DT_HAS_NXP_FLEXIO_PWM_ENABLED + select MCUX_FLEXIO + help + Enable flexio based pwm driver. diff --git a/drivers/pwm/pwm_cc13xx_cc26xx_timer.c b/drivers/pwm/pwm_cc13xx_cc26xx_timer.c index 4855c134aa6262..9edb19b647fd84 100644 --- a/drivers/pwm/pwm_cc13xx_cc26xx_timer.c +++ b/drivers/pwm/pwm_cc13xx_cc26xx_timer.c @@ -140,7 +140,7 @@ static int get_timer_inst_number(const struct pwm_cc13xx_cc26xx_config *config) case GPT3_BASE: return 3; default: - __ASSERT_UNREACHABLE; + CODE_UNREACHABLE; } } #else @@ -156,7 +156,7 @@ static int get_timer_peripheral(const struct pwm_cc13xx_cc26xx_config *config) case GPT3_BASE: return PRCM_PERIPH_TIMER3; default: - __ASSERT_UNREACHABLE; + CODE_UNREACHABLE; } } #endif /* CONFIG_PM */ diff --git a/drivers/pwm/pwm_mcux_qtmr.c b/drivers/pwm/pwm_mcux_qtmr.c new file mode 100644 index 00000000000000..b78f43b0436b1f --- /dev/null +++ b/drivers/pwm/pwm_mcux_qtmr.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2024, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_qtmr_pwm + +#include +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(pwm_mcux_qtmr, CONFIG_PWM_LOG_LEVEL); + +#define CHANNEL_COUNT TMR_CNTR_COUNT + +struct pwm_mcux_qtmr_config { + TMR_Type *base; + uint32_t prescaler; + const struct pinctrl_dev_config *pincfg; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; +}; + +struct pwm_mcux_qtmr_data { + struct k_mutex lock; +}; + +static int mcux_qtmr_pwm_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + struct pwm_mcux_qtmr_data *data = dev->data; + uint32_t periodCount, highCount, lowCount; + uint16_t reg; + + if (channel >= CHANNEL_COUNT) { + LOG_ERR("Invalid channel"); + return -EINVAL; + } + + /* Counter values to generate a PWM signal */ + periodCount = period_cycles; + highCount = pulse_cycles; + lowCount = period_cycles - pulse_cycles; + + if (highCount > 0U) { + highCount -= 1U; + } + if (lowCount > 0U) { + lowCount -= 1U; + } + + if ((highCount > 0xFFFFU) || (lowCount > 0xFFFFU)) { + /* This should not be a 16-bit overflow value. If it is, change to a larger divider + * for clock source. + */ + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + /* Set OFLAG pin for output mode and force out a low on the pin */ + config->base->CHANNEL[channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK); + + QTMR_StopTimer(config->base, channel); + + /* Setup the compare registers for PWM output */ + config->base->CHANNEL[channel].COMP1 = (uint16_t)lowCount; + config->base->CHANNEL[channel].COMP2 = (uint16_t)highCount; + + /* Setup the pre-load registers for PWM output */ + config->base->CHANNEL[channel].CMPLD1 = (uint16_t)lowCount; + config->base->CHANNEL[channel].CMPLD2 = (uint16_t)highCount; + + reg = config->base->CHANNEL[channel].CSCTRL; + /* Setup the compare load control for COMP1 and COMP2. + * Load COMP1 when CSCTRL[TCF2] is asserted, load COMP2 when CSCTRL[TCF1] is asserted + */ + reg &= (uint16_t)(~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK)); + reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1)); + config->base->CHANNEL[channel].CSCTRL = reg; + + reg = config->base->CHANNEL[channel].CTRL; + reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK; + if (highCount == periodCount) { + /* Set OFLAG output on compare */ + reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare)); + } else if (periodCount == 0U) { + /* Clear OFLAG output on compare */ + reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ClearOnCompare)); + } else { + /* Toggle OFLAG output using alternating compare register */ + reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg)); + } + + config->base->CHANNEL[channel].CTRL = reg; + + QTMR_StartTimer(config->base, channel, kQTMR_PriSrcRiseEdge); + + k_mutex_unlock(&data->lock); + + return 0; +} + +static int mcux_qtmr_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + uint32_t clock_freq; + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq)) { + return -EINVAL; + } + + *cycles = clock_freq / config->prescaler; + + return 0; +} + +static int mcux_qtmr_pwm_init(const struct device *dev) +{ + const struct pwm_mcux_qtmr_config *config = dev->config; + struct pwm_mcux_qtmr_data *data = dev->data; + qtmr_config_t qtmr_config; + int err; + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + k_mutex_init(&data->lock); + + QTMR_GetDefaultConfig(&qtmr_config); + qtmr_config.primarySource = kQTMR_ClockDivide_1 + (31 - __builtin_clz(config->prescaler)); + + for (int i = 0; i < CHANNEL_COUNT; i++) { + QTMR_Init(config->base, i, &qtmr_config); + } + + return 0; +} + +static const struct pwm_driver_api pwm_mcux_qtmr_driver_api = { + .set_cycles = mcux_qtmr_pwm_set_cycles, + .get_cycles_per_sec = mcux_qtmr_pwm_get_cycles_per_sec, +}; + +#define PWM_MCUX_QTMR_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct pwm_mcux_qtmr_data pwm_mcux_qtmr_data_##n; \ + \ + static const struct pwm_mcux_qtmr_config pwm_mcux_qtmr_config_##n = { \ + .base = (TMR_Type *)DT_INST_REG_ADDR(n), \ + .prescaler = DT_INST_PROP(n, prescaler), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, mcux_qtmr_pwm_init, NULL, &pwm_mcux_qtmr_data_##n, \ + &pwm_mcux_qtmr_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_mcux_qtmr_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_MCUX_QTMR_DEVICE_INIT) diff --git a/drivers/pwm/pwm_nxp_flexio.c b/drivers/pwm/pwm_nxp_flexio.c new file mode 100644 index 00000000000000..4dbafd8250f9e2 --- /dev/null +++ b/drivers/pwm/pwm_nxp_flexio.c @@ -0,0 +1,339 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#define DT_DRV_COMPAT nxp_flexio_pwm + +#include +#include +#include +#include +#include +#include + +#include +#include + + +LOG_MODULE_REGISTER(pwm_nxp_flexio, CONFIG_PWM_LOG_LEVEL); + +#define FLEXIO_PWM_TIMER_CMP_MAX_VALUE (0xFFFFU) +#define FLEXIO_PWM_TIMCMP_CMP_UPPER_SHIFT (0x8U) +#define FLEXIO_MAX_PWM_CHANNELS 8 + +enum pwm_nxp_flexio_polarity { + FLEXIO_PWM_ACTIVE_HIGH = 0x0U, + FLEXIO_PWM_ACTIVE_LOW = 0x1U +}; + +enum pwm_nxp_flexio_timerinit { + /** Timer Initial output is logic one */ + FLEXIO_PWM_TIMER_INIT_HIGH = 0x00U, + /** Timer Initial output is logic zero */ + FLEXIO_PWM_TIMER_INIT_LOW = 0x1U +}; + +enum pwm_nxp_flexio_prescaler { + /* Decrement counter on Flexio clock */ + FLEXIO_PWM_CLK_DIV_1 = 0U, + /* Decrement counter on Flexio clock divided by 16 */ + FLEXIO_PWM_CLK_DIV_16 = 4U, + /* Decrement counter on Flexio clock divided by 256 */ + FLEXIO_PWM_CLK_DIV_256 = 5U +}; + +enum pwm_nxp_flexio_timer_mode { + /** Timer disabled */ + FLEXIO_PWM_TIMER_DISABLED = 0x00U, + /** Timer in 8 bit Pwm High mode */ + FLEXIO_PWM_TIMER_PWM_HIGH = 0x02U, + /** Timer in 8 bit Pwm Low mode */ + FLEXIO_PWM_TIMER_PWM_LOW = 0x06U +}; + +enum pwm_nxp_flexio_timer_pin { + /** Timer Pin output disabled */ + FLEXIO_PWM_TIMER_PIN_OUTPUT_DISABLE = 0x00U, + /** Timer Pin Output mode */ + FLEXIO_PWM_TIMER_PIN_OUTPUT_ENABLE = 0x03U +}; + +struct pwm_nxp_flexio_channel_config { + /** Flexio used pin index */ + uint8_t pin_id; + /** Counter decrement clock prescaler */ + enum pwm_nxp_flexio_prescaler prescaler; + /** Actual Prescaler divisor */ + uint8_t prescaler_div; +}; + +struct pwm_nxp_flexio_pulse_info { + uint8_t pwm_pulse_channels; + struct pwm_nxp_flexio_channel_config *pwm_info; +}; + +struct pwm_nxp_flexio_config { + const struct device *flexio_dev; + FLEXIO_Type *flexio_base; + const struct pinctrl_dev_config *pincfg; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + const struct pwm_nxp_flexio_pulse_info *pulse_info; + const struct nxp_flexio_child *child; +}; + +struct pwm_nxp_flexio_data { + uint32_t period_cycles[FLEXIO_MAX_PWM_CHANNELS]; + uint32_t flexio_clk; +}; + +static int pwm_nxp_flexio_set_cycles(const struct device *dev, + uint32_t channel, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_nxp_flexio_config *config = dev->config; + struct pwm_nxp_flexio_data *data = dev->data; + flexio_timer_config_t timerConfig; + struct pwm_nxp_flexio_channel_config *pwm_info; + FLEXIO_Type *flexio_base = (FLEXIO_Type *)(config->flexio_base); + struct nxp_flexio_child *child = (struct nxp_flexio_child *)(config->child); + enum pwm_nxp_flexio_polarity polarity; + + /* Check received parameters for sanity */ + if (channel >= config->pulse_info->pwm_pulse_channels) { + LOG_ERR("Invalid channel"); + return -EINVAL; + } + + if (period_cycles == 0) { + LOG_ERR("Channel can not be set to inactive level"); + return -ENOTSUP; + } + + if (FLEXIO_PWM_TIMER_CMP_MAX_VALUE <= (uint16_t)pulse_cycles) { + LOG_ERR("Duty cycle is out of range"); + return -EINVAL; + } + + if (FLEXIO_PWM_TIMER_CMP_MAX_VALUE <= (uint16_t)(period_cycles - pulse_cycles)) { + LOG_ERR("low period of the cycle is out of range"); + return -EINVAL; + } + + if (pulse_cycles > period_cycles) { + LOG_ERR("Duty cycle cannot be greater than 100 percent"); + return -EINVAL; + } + + pwm_info = &config->pulse_info->pwm_info[channel]; + + if ((flags & PWM_POLARITY_INVERTED) == 0) { + polarity = FLEXIO_PWM_ACTIVE_HIGH; + } else { + polarity = FLEXIO_PWM_ACTIVE_LOW; + } + + if (polarity == FLEXIO_PWM_ACTIVE_HIGH) { + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitPWM; + + } else { + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitPWMLow; + } + + data->period_cycles[channel] = period_cycles; + + timerConfig.timerCompare = ((uint8_t)(pulse_cycles - 1U)) | + ((uint8_t)(data->period_cycles[channel] - pulse_cycles - 1U) + << FLEXIO_PWM_TIMCMP_CMP_UPPER_SHIFT); + + timerConfig.timerDecrement = pwm_info->prescaler; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + timerConfig.timerEnable = kFLEXIO_TimerEnabledAlways; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + + /* Enable the pin out for the selected timer */ + timerConfig.pinConfig = FLEXIO_PWM_TIMER_PIN_OUTPUT_ENABLE; + timerConfig.pinPolarity = polarity; + + /* Select the pin that the selected timer will output the signal on */ + timerConfig.pinSelect = pwm_info->pin_id; + + FLEXIO_SetTimerConfig(flexio_base, child->res.timer_index[channel], &timerConfig); + +#if (defined(FSL_FEATURE_FLEXIO_HAS_PIN_REGISTER) && FSL_FEATURE_FLEXIO_HAS_PIN_REGISTER) + /* Disable pin override if active to support channels working in cases not 0% 100% */ + if (FLEXIO_GetPinOverride(flexio_base, pwm_info->pin_id)) { + FLEXIO_ConfigPinOverride(flexio_base, pwm_info->pin_id, false); + } +#endif + return 0; +} + +static int pwm_nxp_flexio_get_cycles_per_sec(const struct device *dev, + uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_nxp_flexio_config *config = dev->config; + struct pwm_nxp_flexio_data *data = dev->data; + struct pwm_nxp_flexio_channel_config *pwm_info; + + /* If get_cycles is called directly after init */ + if (data->period_cycles[channel] == 0) { + LOG_ERR("First set the period of this channel to a non zero value"); + return -ENOTSUP; + } + + pwm_info = &config->pulse_info->pwm_info[channel]; + *cycles = (uint64_t)(((data->flexio_clk) * 2) / + ((data->period_cycles[channel]) * (pwm_info->prescaler_div))); + + return 0; +} + +static int mcux_flexio_pwm_init(const struct device *dev) +{ + const struct pwm_nxp_flexio_config *config = dev->config; + struct pwm_nxp_flexio_data *data = dev->data; + flexio_timer_config_t timerConfig; + uint8_t ch_id = 0; + int err; + struct pwm_nxp_flexio_channel_config *pwm_info; + FLEXIO_Type *flexio_base = (FLEXIO_Type *)(config->flexio_base); + struct nxp_flexio_child *child = (struct nxp_flexio_child *)(config->child); + + if (!device_is_ready(config->clock_dev)) { + return -ENODEV; + } + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &data->flexio_clk)) { + return -EINVAL; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + err = nxp_flexio_child_attach(config->flexio_dev, child); + if (err < 0) { + return err; + } + + for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) { + pwm_info = &config->pulse_info->pwm_info[ch_id]; + + /* Reset timer settings */ + (void)memset(&timerConfig, 0, sizeof(timerConfig)); + FLEXIO_SetTimerConfig(flexio_base, child->res.timer_index[ch_id], &timerConfig); + +#if (defined(FSL_FEATURE_FLEXIO_HAS_PIN_REGISTER) && FSL_FEATURE_FLEXIO_HAS_PIN_REGISTER) + /* Reset the value driven on the corresponding pin */ + FLEXIO_SetPinLevel(flexio_base, pwm_info->pin_id, false); + FLEXIO_ConfigPinOverride(flexio_base, pwm_info->pin_id, false); +#endif + /* Timer output is logic one and is not affected by timer reset */ + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + /* Set the timer mode to dual 8-bit counter PWM high */ + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitPWM; + + /* Timer scaling factor w.r.t Flexio Clock */ + timerConfig.timerDecrement = pwm_info->prescaler; + + /* Program the PWM pulse */ + timerConfig.timerCompare = 0; + + /* Configure Timer CFG and CTL bits to support PWM mode */ + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + timerConfig.timerEnable = kFLEXIO_TimerEnabledAlways; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + + /* Enable the pin out and set a default polarity for the selected timer */ + timerConfig.pinConfig = FLEXIO_PWM_TIMER_PIN_OUTPUT_ENABLE; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + + /* Select the pin that the selected timer will output the signal on */ + timerConfig.pinSelect = pwm_info->pin_id; + + FLEXIO_SetTimerConfig(flexio_base, child->res.timer_index[ch_id], &timerConfig); + } + + return 0; +} + +static const struct pwm_driver_api pwm_nxp_flexio_driver_api = { + .set_cycles = pwm_nxp_flexio_set_cycles, + .get_cycles_per_sec = pwm_nxp_flexio_get_cycles_per_sec, +}; + +#define _FLEXIO_PWM_PULSE_GEN_CONFIG(n) \ + { \ + .pin_id = DT_PROP(n, pin_id), \ + .prescaler = _CONCAT(FLEXIO_PWM_CLK_DIV_, DT_PROP(n, prescaler)), \ + .prescaler_div = DT_PROP(n, prescaler), \ + }, + +#define FLEXIO_PWM_PULSE_GEN_CONFIG(n) \ + static struct pwm_nxp_flexio_channel_config flexio_pwm_##n##_init[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _FLEXIO_PWM_PULSE_GEN_CONFIG) \ + }; \ + static const struct pwm_nxp_flexio_pulse_info flexio_pwm_##n##_info = { \ + .pwm_pulse_channels = ARRAY_SIZE(flexio_pwm_##n##_init), \ + .pwm_info = flexio_pwm_##n##_init, \ + }; + +#define FLEXIO_PWM_TIMER_INDEX_INIT(n) \ + static uint8_t flexio_pwm_##n##_timer_index[ARRAY_SIZE(flexio_pwm_##n##_init)]; + +#define FLEXIO_PWM_CHILD_CONFIG(n) \ + static const struct nxp_flexio_child mcux_flexio_pwm_child_##n = { \ + .isr = NULL, \ + .user_data = NULL, \ + .res = { \ + .shifter_index = NULL, \ + .shifter_count = 0, \ + .timer_index = (uint8_t *)flexio_pwm_##n##_timer_index, \ + .timer_count = ARRAY_SIZE(flexio_pwm_##n##_init) \ + } \ + }; + +#define FLEXIO_PWM_PULSE_GEN_GET_CONFIG(n) \ + .pulse_info = &flexio_pwm_##n##_info, + + +#define PWM_NXP_FLEXIO_PWM_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + FLEXIO_PWM_PULSE_GEN_CONFIG(n) \ + FLEXIO_PWM_TIMER_INDEX_INIT(n) \ + FLEXIO_PWM_CHILD_CONFIG(n) \ + static const struct pwm_nxp_flexio_config pwm_nxp_flexio_config_##n = { \ + .flexio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .flexio_base = (FLEXIO_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \ + .clock_subsys = (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name),\ + .child = &mcux_flexio_pwm_child_##n, \ + FLEXIO_PWM_PULSE_GEN_GET_CONFIG(n) \ + }; \ + \ + static struct pwm_nxp_flexio_data pwm_nxp_flexio_data_##n; \ + DEVICE_DT_INST_DEFINE(n, \ + &mcux_flexio_pwm_init, \ + NULL, \ + &pwm_nxp_flexio_data_##n, \ + &pwm_nxp_flexio_config_##n, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_nxp_flexio_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_NXP_FLEXIO_PWM_INIT) diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index 85ff98320dd2a7..eb631cd5ac117f 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -20,4 +20,5 @@ zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c) zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c) zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c) zephyr_library_sources_ifdef(CONFIG_RTC_RPI_PICO rtc_rpi_pico.c) +zephyr_library_sources_ifdef(CONFIG_RTC_RV3028 rtc_rv3028.c) zephyr_library_sources_ifdef(CONFIG_RTC_NUMAKER rtc_numaker.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 46bd2562dd937f..8dd4034ece1223 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -49,6 +49,7 @@ source "drivers/rtc/Kconfig.mc146818" source "drivers/rtc/Kconfig.pcf8523" source "drivers/rtc/Kconfig.pcf8563" source "drivers/rtc/Kconfig.rpi_pico" +source "drivers/rtc/Kconfig.rv3028" source "drivers/rtc/Kconfig.sam" source "drivers/rtc/Kconfig.smartbond" source "drivers/rtc/Kconfig.stm32" diff --git a/drivers/rtc/Kconfig.rv3028 b/drivers/rtc/Kconfig.rv3028 new file mode 100644 index 00000000000000..10cd6ca2998c71 --- /dev/null +++ b/drivers/rtc/Kconfig.rv3028 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 ANITRA system s.r.o. +# SPDX-License-Identifier: Apache-2.0 + +config RTC_RV3028 + bool "Micro Crystal RV3028 I2C extreme low power RTC driver" + default y + depends on DT_HAS_MICROCRYSTAL_RV3028_ENABLED + select I2C + help + Enable the Micro Crystal RV3028 I2C RTC driver. diff --git a/drivers/rtc/rtc_mc146818.c b/drivers/rtc/rtc_mc146818.c index 15d36c623b0949..66257cf8d7461e 100644 --- a/drivers/rtc/rtc_mc146818.c +++ b/drivers/rtc/rtc_mc146818.c @@ -377,13 +377,13 @@ static int rtc_mc146818_alarm_get_time(const struct device *dev, uint16_t id, ui } value = rtc_read(RTC_ALARM_MIN); - if (value <= MAX_SEC) { + if (value <= MAX_MIN) { timeptr->tm_min = value; (*mask) |= RTC_ALARM_TIME_MASK_MINUTE; } value = rtc_read(RTC_ALARM_HOUR); - if (value <= MAX_SEC) { + if (value <= MAX_HOUR) { timeptr->tm_hour = value; (*mask) |= RTC_ALARM_TIME_MASK_HOUR; } diff --git a/drivers/rtc/rtc_rv3028.c b/drivers/rtc/rtc_rv3028.c new file mode 100644 index 00000000000000..da220bef68659a --- /dev/null +++ b/drivers/rtc/rtc_rv3028.c @@ -0,0 +1,986 @@ +/* + * Copyright (c) 2024 ANITRA system s.r.o. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microcrystal_rv3028 + +#include +#include +#include +#include +#include +#include +#include "rtc_utils.h" + +LOG_MODULE_REGISTER(rv3028, CONFIG_RTC_LOG_LEVEL); + +/* RV3028 RAM register addresses */ +#define RV3028_REG_SECONDS 0x00 +#define RV3028_REG_MINUTES 0x01 +#define RV3028_REG_HOURS 0x02 +#define RV3028_REG_WEEKDAY 0x03 +#define RV3028_REG_DATE 0x04 +#define RV3028_REG_MONTH 0x05 +#define RV3028_REG_YEAR 0x06 +#define RV3028_REG_ALARM_MINUTES 0x07 +#define RV3028_REG_ALARM_HOURS 0x08 +#define RV3028_REG_ALARM_WEEKDAY 0x09 +#define RV3028_REG_STATUS 0x0E +#define RV3028_REG_CONTROL1 0x0F +#define RV3028_REG_CONTROL2 0x10 +#define RV3028_REG_EVENT_CONTROL 0x13 +#define RV3028_REG_TS_COUNT 0x14 +#define RV3028_REG_TS_SECONDS 0x15 +#define RV3028_REG_TS_MINUTES 0x16 +#define RV3028_REG_TS_HOURS 0x17 +#define RV3028_REG_TS_DATE 0x18 +#define RV3028_REG_TS_MONTH 0x19 +#define RV3028_REG_TS_YEAR 0x1A +#define RV3028_REG_UNIXTIME0 0x1B +#define RV3028_REG_UNIXTIME1 0x1C +#define RV3028_REG_UNIXTIME2 0x1D +#define RV3028_REG_UNIXTIME3 0x1E +#define RV3028_REG_USER_RAM1 0x1F +#define RV3028_REG_USER_RAM2 0x20 +#define RV3028_REG_EEPROM_ADDRESS 0x25 +#define RV3028_REG_EEPROM_DATA 0x26 +#define RV3028_REG_EEPROM_COMMAND 0x27 +#define RV3028_REG_ID 0x28 +#define RV3028_REG_CLKOUT 0x35 +#define RV3028_REG_OFFSET 0x36 +#define RV3028_REG_BACKUP 0x37 + +#define RV3028_CONTROL1_TD BIT(0) +#define RV3028_CONTROL1_TE GENMASK(2, 1) +#define RV3028_CONTROL1_EERD BIT(3) +#define RV3028_CONTROL1_USEL BIT(4) +#define RV3028_CONTROL1_WADA BIT(5) +#define RV3028_CONTROL1_TRPT BIT(7) + +#define RV3028_CONTROL2_RESET BIT(0) +#define RV3028_CONTROL2_12_24 BIT(1) +#define RV3028_CONTROL2_EIE BIT(2) +#define RV3028_CONTROL2_AIE BIT(3) +#define RV3028_CONTROL2_TIE BIT(4) +#define RV3028_CONTROL2_UIE BIT(5) +#define RV3028_CONTROL2_TSE BIT(7) + +#define RV3028_STATUS_PORF BIT(0) +#define RV3028_STATUS_EVF BIT(1) +#define RV3028_STATUS_AF BIT(2) +#define RV3028_STATUS_TF BIT(3) +#define RV3028_STATUS_UF BIT(4) +#define RV3028_STATUS_BSF BIT(5) +#define RV3028_STATUS_CLKF BIT(6) +#define RV3028_STATUS_EEBUSY BIT(7) + +#define RV3028_CLKOUT_FD GENMASK(2, 0) +#define RV3028_CLKOUT_PORIE BIT(3) +#define RV3028_CLKOUT_CLKSY BIT(6) +#define RV3028_CLKOUT_CLKOE BIT(7) + +#define RV3028_CLKOUT_FD_LOW 0x7 + +#define RV3028_BACKUP_TCE BIT(5) +#define RV3028_BACKUP_TCR GENMASK(1, 0) +#define RV3028_BACKUP_BSM GENMASK(3, 2) + +#define RV3028_BSM_LEVEL 0x3 +#define RV3028_BSM_DIRECT 0x1 +#define RV3028_BSM_DISABLED 0x0 + +/* RV3028 EE command register values */ +#define RV3028_EEPROM_CMD_INIT 0x00 +#define RV3028_EEPROM_CMD_UPDATE 0x11 +#define RV3028_EEPROM_CMD_REFRESH 0x12 +#define RV3028_EEPROM_CMD_WRITE 0x21 +#define RV3028_EEPROM_CMD_READ 0x22 + +#define RV3028_SECONDS_MASK GENMASK(6, 0) +#define RV3028_MINUTES_MASK GENMASK(6, 0) +#define RV3028_HOURS_AMPM BIT(5) +#define RV3028_HOURS_12H_MASK GENMASK(4, 0) +#define RV3028_HOURS_24H_MASK GENMASK(5, 0) +#define RV3028_DATE_MASK GENMASK(5, 0) +#define RV3028_WEEKDAY_MASK GENMASK(2, 0) +#define RV3028_MONTH_MASK GENMASK(4, 0) +#define RV3028_YEAR_MASK GENMASK(7, 0) + +#define RV3028_ALARM_MINUTES_AE_M BIT(7) +#define RV3028_ALARM_MINUTES_MASK GENMASK(6, 0) +#define RV3028_ALARM_HOURS_AE_H BIT(7) +#define RV3028_ALARM_HOURS_AMPM BIT(5) +#define RV3028_ALARM_HOURS_12H_MASK GENMASK(4, 0) +#define RV3028_ALARM_HOURS_24H_MASK GENMASK(5, 0) +#define RV3028_ALARM_DATE_AE_WD BIT(7) +#define RV3028_ALARM_DATE_MASK GENMASK(5, 0) + +/* The RV3028 only supports two-digit years. Leap years are correctly handled from 2000 to 2099 */ +#define RV3028_YEAR_OFFSET (2000 - 1900) + +/* The RV3028 enumerates months 1 to 12 */ +#define RV3028_MONTH_OFFSET 1 + +#define RV3028_EEBUSY_POLL_US 10000 +#define RV3028_EEBUSY_TIMEOUT_MS 100 + +/* RTC alarm time fields supported by the RV3028 */ +#define RV3028_RTC_ALARM_TIME_MASK \ + (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY) + +/* RTC time fields supported by the RV3028 */ +#define RV3028_RTC_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_YEAR) + +/* Helper macro to guard int-gpios related code */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) && \ + (defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE)) +#define RV3028_INT_GPIOS_IN_USE 1 +#endif + +struct rv3028_config { + const struct i2c_dt_spec i2c; +#ifdef RV3028_INT_GPIOS_IN_USE + struct gpio_dt_spec gpio_int; +#endif /* RV3028_INT_GPIOS_IN_USE */ + uint8_t cof; + uint8_t backup; +}; + +struct rv3028_data { + struct k_sem lock; +#if RV3028_INT_GPIOS_IN_USE + const struct device *dev; + struct gpio_callback int_callback; + struct k_work work; + +#ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_callback; + void *alarm_user_data; +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + rtc_update_callback update_callback; + void *update_user_data; +#endif /* CONFIG_RTC_UPDATE */ +#endif /* RV3028_INT_GPIOS_IN_USE */ +}; + +static void rv3028_lock_sem(const struct device *dev) +{ + struct rv3028_data *data = dev->data; + + (void)k_sem_take(&data->lock, K_FOREVER); +} + +static void rv3028_unlock_sem(const struct device *dev) +{ + struct rv3028_data *data = dev->data; + + k_sem_give(&data->lock); +} + +static int rv3028_read_regs(const struct device *dev, uint8_t addr, void *buf, size_t len) +{ + const struct rv3028_config *config = dev->config; + int err; + + err = i2c_write_read_dt(&config->i2c, &addr, sizeof(addr), buf, len); + if (err) { + LOG_ERR("failed to read reg addr 0x%02x, len %d (err %d)", addr, len, err); + return err; + } + + return 0; +} + +static int rv3028_read_reg8(const struct device *dev, uint8_t addr, uint8_t *val) +{ + return rv3028_read_regs(dev, addr, val, sizeof(*val)); +} + +static int rv3028_write_regs(const struct device *dev, uint8_t addr, void *buf, size_t len) +{ + const struct rv3028_config *config = dev->config; + uint8_t block[sizeof(addr) + len]; + int err; + + block[0] = addr; + memcpy(&block[1], buf, len); + + err = i2c_write_dt(&config->i2c, block, sizeof(block)); + if (err) { + LOG_ERR("failed to write reg addr 0x%02x, len %d (err %d)", addr, len, err); + return err; + } + + return 0; +} + +static int rv3028_write_reg8(const struct device *dev, uint8_t addr, uint8_t val) +{ + return rv3028_write_regs(dev, addr, &val, sizeof(val)); +} + +static int rv3028_update_reg8(const struct device *dev, uint8_t addr, uint8_t mask, uint8_t val) +{ + const struct rv3028_config *config = dev->config; + int err; + + err = i2c_reg_update_byte_dt(&config->i2c, addr, mask, val); + if (err) { + LOG_ERR("failed to update reg addr 0x%02x, mask 0x%02x, val 0x%02x (err %d)", addr, + mask, val, err); + return err; + } + + return 0; +} + +static int rv3028_eeprom_wait_busy(const struct device *dev) +{ + uint8_t status = 0; + int err; + int64_t timeout_time = k_uptime_get() + RV3028_EEBUSY_TIMEOUT_MS; + + /* Wait while the EEPROM is busy */ + for (;;) { + err = rv3028_read_reg8(dev, RV3028_REG_STATUS, &status); + if (err) { + return err; + } + + if (!(status & RV3028_STATUS_EEBUSY)) { + break; + } + + if (k_uptime_get() > timeout_time) { + return -ETIME; + } + + k_busy_wait(RV3028_EEBUSY_POLL_US); + } + + return 0; +} + +static int rv3028_exit_eerd(const struct device *dev) +{ + return rv3028_update_reg8(dev, RV3028_REG_CONTROL1, RV3028_CONTROL1_EERD, 0); +} + +static int rv3028_enter_eerd(const struct device *dev) +{ + uint8_t ctrl1; + bool eerd; + int ret; + + ret = rv3028_read_reg8(dev, RV3028_REG_CONTROL1, &ctrl1); + if (ret) { + return ret; + } + + eerd = ctrl1 & RV3028_CONTROL1_EERD; + if (eerd) { + return 0; + } + + ret = rv3028_update_reg8(dev, RV3028_REG_CONTROL1, RV3028_CONTROL1_EERD, + RV3028_CONTROL1_EERD); + + ret = rv3028_eeprom_wait_busy(dev); + if (ret) { + rv3028_exit_eerd(dev); + return ret; + } + + return ret; +} + +static int rv3028_eeprom_command(const struct device *dev, uint8_t command) +{ + int err; + + err = rv3028_write_reg8(dev, RV3028_REG_EEPROM_COMMAND, RV3028_EEPROM_CMD_INIT); + if (err) { + return err; + } + + return rv3028_write_reg8(dev, RV3028_REG_EEPROM_COMMAND, command); +} + +static int rv3028_update(const struct device *dev) +{ + int err; + + err = rv3028_eeprom_command(dev, RV3028_EEPROM_CMD_UPDATE); + if (err) { + goto exit_eerd; + } + + err = rv3028_eeprom_wait_busy(dev); + +exit_eerd: + rv3028_exit_eerd(dev); + + return err; +} + +static int rv3028_refresh(const struct device *dev) +{ + int err; + + err = rv3028_eeprom_command(dev, RV3028_EEPROM_CMD_REFRESH); + if (err) { + goto exit_eerd; + } + + err = rv3028_eeprom_wait_busy(dev); + +exit_eerd: + rv3028_exit_eerd(dev); + + return err; +} + +static int rv3028_update_cfg(const struct device *dev, uint8_t addr, uint8_t mask, uint8_t val) +{ + uint8_t val_old, val_new; + int err; + + err = rv3028_read_reg8(dev, addr, &val_old); + if (err) { + return err; + } + + val_new = (val_old & ~mask) | (val & mask); + if (val_new == val_old) { + return 0; + } + + err = rv3028_enter_eerd(dev); + if (err) { + return err; + } + + err = rv3028_write_reg8(dev, addr, val_new); + if (err) { + rv3028_exit_eerd(dev); + return err; + } + + return rv3028_update(dev); +} + +#if RV3028_INT_GPIOS_IN_USE + +static int rv3028_int_enable_unlocked(const struct device *dev, bool enable) +{ + const struct rv3028_config *config = dev->config; + uint8_t clkout = 0; + int err; + + if (enable || config->cof == RV3028_CLKOUT_FD_LOW) { + /* Disable CLKOUT */ + clkout |= FIELD_PREP(RV3028_CLKOUT_FD, RV3028_CLKOUT_FD_LOW); + } else { + /* Configure CLKOUT frequency */ + clkout |= RV3028_CLKOUT_CLKOE | + FIELD_PREP(RV3028_CLKOUT_FD, config->cof); + } + + /* Configure the CLKOUT register */ + err = rv3028_update_cfg(dev, + RV3028_REG_CLKOUT, + RV3028_CLKOUT_FD | RV3028_CLKOUT_CLKOE, + clkout); + if (err) { + return err; + } + + err = gpio_pin_interrupt_configure_dt(&config->gpio_int, + enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE); + if (err) { + LOG_ERR("failed to %s GPIO interrupt (err %d)", enable ? "enable" : "disable", err); + return err; + } + + return 0; +} + +static void rv3028_work_cb(struct k_work *work) +{ + struct rv3028_data *data = CONTAINER_OF(work, struct rv3028_data, work); + const struct device *dev = data->dev; + rtc_alarm_callback alarm_callback = NULL; + void *alarm_user_data = NULL; + rtc_update_callback update_callback = NULL; + void *update_user_data = NULL; + uint8_t status; + int err; + + rv3028_lock_sem(dev); + + err = rv3028_read_reg8(data->dev, RV3028_REG_STATUS, &status); + if (err) { + goto unlock; + } + +#ifdef CONFIG_RTC_ALARM + if ((status & RV3028_STATUS_AF) && data->alarm_callback != NULL) { + status &= ~(RV3028_STATUS_AF); + alarm_callback = data->alarm_callback; + alarm_user_data = data->alarm_user_data; + } +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE + if ((status & RV3028_STATUS_UF) && data->update_callback != NULL) { + status &= ~(RV3028_STATUS_UF); + update_callback = data->update_callback; + update_user_data = data->update_user_data; + } +#endif /* CONFIG_RTC_UPDATE */ + + err = rv3028_write_reg8(dev, RV3028_REG_STATUS, status); + if (err) { + goto unlock; + } + + /* Check if interrupt occurred between STATUS read/write */ + err = rv3028_read_reg8(dev, RV3028_REG_STATUS, &status); + if (err) { + goto unlock; + } + + if (((status & RV3028_STATUS_AF) && alarm_callback != NULL) || + ((status & RV3028_STATUS_UF) && update_callback != NULL)) { + /* Another interrupt occurred while servicing this one */ + k_work_submit(&data->work); + } + +unlock: + rv3028_unlock_sem(dev); + + if (alarm_callback != NULL) { + alarm_callback(dev, 0U, alarm_user_data); + alarm_callback = NULL; + } + + if (update_callback != NULL) { + update_callback(dev, update_user_data); + update_callback = NULL; + } +} + +static void rv3028_int_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ + struct rv3028_data *data = CONTAINER_OF(cb, struct rv3028_data, int_callback); + + ARG_UNUSED(port); + ARG_UNUSED(pins); + + k_work_submit(&data->work); +} + +#endif /* RV3028_INT_GPIOS_IN_USE */ + +static int rv3028_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + uint8_t date[7]; + int err; + + if (timeptr == NULL || + !rtc_utils_validate_rtc_time(timeptr, RV3028_RTC_TIME_MASK) || + (timeptr->tm_year < RV3028_YEAR_OFFSET)) { + LOG_ERR("invalid time"); + return -EINVAL; + } + + rv3028_lock_sem(dev); + + LOG_DBG("set time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + + date[0] = bin2bcd(timeptr->tm_sec) & RV3028_SECONDS_MASK; + date[1] = bin2bcd(timeptr->tm_min) & RV3028_MINUTES_MASK; + date[2] = bin2bcd(timeptr->tm_hour) & RV3028_HOURS_24H_MASK; + date[3] = bin2bcd(timeptr->tm_wday) & RV3028_WEEKDAY_MASK; + date[4] = bin2bcd(timeptr->tm_mday) & RV3028_DATE_MASK; + date[5] = bin2bcd(timeptr->tm_mon + RV3028_MONTH_OFFSET) & RV3028_MONTH_MASK; + date[6] = bin2bcd(timeptr->tm_year - RV3028_YEAR_OFFSET) & RV3028_YEAR_MASK; + + err = rv3028_write_regs(dev, RV3028_REG_SECONDS, &date, sizeof(date)); + if (err) { + goto unlock; + } + + /* Clear Power On Reset Flag */ + err = rv3028_update_reg8(dev, RV3028_REG_STATUS, RV3028_STATUS_PORF, 0); + +unlock: + rv3028_unlock_sem(dev); + + return err; +} + +static int rv3028_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + uint8_t status; + uint8_t date[7]; + int err; + + if (timeptr == NULL) { + return -EINVAL; + } + + err = rv3028_read_reg8(dev, RV3028_REG_STATUS, &status); + if (err) { + return err; + } + + if (status & RV3028_STATUS_PORF) { + /* Power On Reset Flag indicates invalid data */ + return -ENODATA; + } + + err = rv3028_read_regs(dev, RV3028_REG_SECONDS, date, sizeof(date)); + if (err) { + return err; + } + + memset(timeptr, 0U, sizeof(*timeptr)); + timeptr->tm_sec = bcd2bin(date[0] & RV3028_SECONDS_MASK); + timeptr->tm_min = bcd2bin(date[1] & RV3028_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(date[2] & RV3028_HOURS_24H_MASK); + timeptr->tm_wday = bcd2bin(date[3] & RV3028_WEEKDAY_MASK); + timeptr->tm_mday = bcd2bin(date[4] & RV3028_DATE_MASK); + timeptr->tm_mon = bcd2bin(date[5] & RV3028_MONTH_MASK) - RV3028_MONTH_OFFSET; + timeptr->tm_year = bcd2bin(date[6] & RV3028_YEAR_MASK) + RV3028_YEAR_OFFSET; + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + + LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " + "min = %d, sec = %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + + return 0; +} + +#ifdef CONFIG_RTC_ALARM + +static int rv3028_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) +{ + ARG_UNUSED(dev); + + if (id != 0U) { + LOG_ERR("invalid alarm ID %d", id); + return -EINVAL; + } + + *mask = RV3028_RTC_ALARM_TIME_MASK; + + return 0; +} + +static int rv3028_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + uint8_t regs[3]; + + if (id != 0U) { + LOG_ERR("invalid alarm ID %d", id); + return -EINVAL; + } + + if (mask & ~(RV3028_RTC_ALARM_TIME_MASK)) { + LOG_ERR("unsupported alarm field mask 0x%04x", mask); + return -EINVAL; + } + + if (!rtc_utils_validate_rtc_time(timeptr, mask)) { + LOG_ERR("invalid alarm time"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + regs[0] = bin2bcd(timeptr->tm_min) & RV3028_ALARM_MINUTES_MASK; + } else { + regs[0] = RTC_ALARM_TIME_MASK_MINUTE; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + regs[1] = bin2bcd(timeptr->tm_hour) & RV3028_ALARM_HOURS_24H_MASK; + } else { + regs[1] = RV3028_ALARM_HOURS_AE_H; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + regs[2] = bin2bcd(timeptr->tm_mday) & RV3028_ALARM_DATE_MASK; + } else { + regs[2] = RV3028_ALARM_DATE_AE_WD; + } + + LOG_DBG("set alarm: mday = %d, hour = %d, min = %d, mask = 0x%04x", + timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, mask); + + /* Write registers RV3028_REG_ALARM_MINUTES through RV3028_REG_ALARM_WEEKDAY */ + return rv3028_write_regs(dev, RV3028_REG_ALARM_MINUTES, ®s, sizeof(regs)); +} + +static int rv3028_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + uint8_t regs[3]; + int err; + + if (id != 0U) { + LOG_ERR("invalid alarm ID %d", id); + return -EINVAL; + } + + /* Read registers RV3028_REG_ALARM_MINUTES through RV3028_REG_ALARM_WEEKDAY */ + err = rv3028_read_regs(dev, RV3028_REG_ALARM_MINUTES, ®s, sizeof(regs)); + if (err) { + return err; + } + + memset(timeptr, 0U, sizeof(*timeptr)); + *mask = 0U; + + if ((regs[0] & RV3028_ALARM_MINUTES_AE_M) == 0) { + timeptr->tm_min = bcd2bin(regs[0] & RV3028_ALARM_MINUTES_MASK); + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + + if ((regs[1] & RV3028_ALARM_HOURS_AE_H) == 0) { + timeptr->tm_hour = bcd2bin(regs[1] & RV3028_ALARM_HOURS_24H_MASK); + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + + if ((regs[2] & RV3028_ALARM_DATE_AE_WD) == 0) { + timeptr->tm_mday = bcd2bin(regs[2] & RV3028_ALARM_DATE_MASK); + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + + LOG_DBG("get alarm: mday = %d, hour = %d, min = %d, mask = 0x%04x", + timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, *mask); + + return 0; +} + +static int rv3028_alarm_is_pending(const struct device *dev, uint16_t id) +{ + uint8_t status; + int err; + + if (id != 0U) { + LOG_ERR("invalid alarm ID %d", id); + return -EINVAL; + } + + rv3028_lock_sem(dev); + + err = rv3028_read_reg8(dev, RV3028_REG_STATUS, &status); + if (err) { + goto unlock; + } + + if (status & RV3028_STATUS_AF) { + /* Clear alarm flag */ + status &= ~(RV3028_STATUS_AF); + + err = rv3028_write_reg8(dev, RV3028_REG_STATUS, status); + if (err) { + goto unlock; + } + + /* Alarm pending */ + err = 1; + } + +unlock: + rv3028_unlock_sem(dev); + + return err; +} + +#if RV3028_INT_GPIOS_IN_USE + +static int rv3028_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + const struct rv3028_config *config = dev->config; + struct rv3028_data *data = dev->data; + uint8_t control_2; + int err = 0; + + if (config->gpio_int.port == NULL) { + return -ENOTSUP; + } + + if (id != 0U) { + LOG_ERR("invalid alarm ID %d", id); + return -EINVAL; + } + + rv3028_lock_sem(dev); + + data->alarm_callback = callback; + data->alarm_user_data = user_data; + + err = rv3028_read_reg8(dev, RV3028_REG_CONTROL2, &control_2); + if (err) { + goto unlock; + } + + if (callback != NULL) { + control_2 |= RV3028_CONTROL2_AIE; + } else { + control_2 &= ~(RV3028_CONTROL2_AIE); + } + + if ((control_2 & RV3028_CONTROL2_UIE) == 0U) { + /* Only change INT GPIO if periodic time update interrupt not enabled */ + err = rv3028_int_enable_unlocked(dev, callback != NULL); + if (err) { + goto unlock; + } + } + + err = rv3028_write_reg8(dev, RV3028_REG_CONTROL2, control_2); + if (err) { + goto unlock; + } + +unlock: + rv3028_unlock_sem(dev); + + /* Alarm flag may already be set */ + k_work_submit(&data->work); + + return err; +} + +#endif /* RV3028_INT_GPIOS_IN_USE */ +#endif /* CONFIG_RTC_ALARM */ + +#if RV3028_INT_GPIOS_IN_USE && defined(CONFIG_RTC_UPDATE) + +static int rv3028_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data) +{ + const struct rv3028_config *config = dev->config; + struct rv3028_data *data = dev->data; + uint8_t control_2; + int err; + + if (config->gpio_int.port == NULL) { + return -ENOTSUP; + } + + rv3028_lock_sem(dev); + + data->update_callback = callback; + data->update_user_data = user_data; + + err = rv3028_read_reg8(dev, RV3028_REG_CONTROL2, &control_2); + if (err) { + goto unlock; + } + + if (callback != NULL) { + control_2 |= RV3028_CONTROL2_UIE; + } else { + control_2 &= ~(RV3028_CONTROL2_UIE); + } + + if ((control_2 & RV3028_CONTROL2_AIE) == 0U) { + /* Only change INT GPIO if alarm interrupt not enabled */ + err = rv3028_int_enable_unlocked(dev, callback != NULL); + if (err) { + goto unlock; + } + } + + err = rv3028_write_reg8(dev, RV3028_REG_CONTROL2, control_2); + if (err) { + goto unlock; + } + +unlock: + rv3028_unlock_sem(dev); + + /* Seconds flag may already be set */ + k_work_submit(&data->work); + + return err; +} + +#endif /* RV3028_INT_GPIOS_IN_USE && defined(CONFIG_RTC_UPDATE) */ + +static int rv3028_init(const struct device *dev) +{ + const struct rv3028_config *config = dev->config; + struct rv3028_data *data = dev->data; + uint8_t regs[3]; + uint8_t val; + int err; + + k_sem_init(&data->lock, 1, 1); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + err = rv3028_read_reg8(dev, RV3028_REG_ID, &val); + if (err) { + return -ENODEV; + } + + LOG_DBG("HID: 0x%02x, VID: 0x%02x", (val & 0xF0) >> 0x04, val & 0x0F); + +#if RV3028_INT_GPIOS_IN_USE + if (config->gpio_int.port != NULL) { + if (!gpio_is_ready_dt(&config->gpio_int)) { + LOG_ERR("GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (err) { + LOG_ERR("failed to configure GPIO (err %d)", err); + return -ENODEV; + } + + gpio_init_callback(&data->int_callback, rv3028_int_handler, + BIT(config->gpio_int.pin)); + + err = gpio_add_callback_dt(&config->gpio_int, &data->int_callback); + if (err) { + LOG_ERR("failed to add GPIO callback (err %d)", err); + return -ENODEV; + } + + data->dev = dev; + data->work.handler = rv3028_work_cb; + } +#endif /* RV3028_INT_GPIOS_IN_USE */ + + err = rv3028_read_reg8(dev, RV3028_REG_STATUS, &val); + if (err) { + return -ENODEV; + } + + if (val & RV3028_STATUS_AF) { + LOG_WRN("an alarm may have been missed"); + } + + /* Refresh the settings in the RAM with the settings from the EEPROM */ + err = rv3028_enter_eerd(dev); + if (err) { + return -ENODEV; + } + err = rv3028_refresh(dev); + if (err) { + return -ENODEV; + } + + /* Configure the CLKOUT register */ + val = FIELD_PREP(RV3028_CLKOUT_FD, config->cof) | + (config->cof != RV3028_CLKOUT_FD_LOW ? RV3028_CLKOUT_CLKOE : 0); + err = rv3028_update_cfg(dev, + RV3028_REG_CLKOUT, + RV3028_CLKOUT_FD | RV3028_CLKOUT_CLKOE, + val); + if (err) { + return -ENODEV; + } + + err = rv3028_update_cfg(dev, + RV3028_REG_BACKUP, + RV3028_BACKUP_TCE | RV3028_BACKUP_TCR | RV3028_BACKUP_BSM, + config->backup); + if (err) { + return -ENODEV; + } + + err = rv3028_update_reg8(dev, RV3028_REG_CONTROL1, RV3028_CONTROL1_WADA, + RV3028_CONTROL1_WADA); + if (err) { + return -ENODEV; + } + + /* Disable the alarms */ + err = rv3028_update_reg8(dev, + RV3028_REG_CONTROL2, + RV3028_CONTROL2_AIE | RV3028_CONTROL2_UIE, + 0); + if (err) { + return -ENODEV; + } + + err = rv3028_read_regs(dev, RV3028_REG_ALARM_MINUTES, regs, sizeof(regs)); + if (err) { + return -ENODEV; + } + + regs[0] |= RV3028_ALARM_MINUTES_AE_M; + regs[1] |= RV3028_ALARM_HOURS_AE_H; + regs[2] |= RV3028_ALARM_DATE_AE_WD; + + err = rv3028_write_regs(dev, RV3028_REG_ALARM_MINUTES, regs, sizeof(regs)); + if (err) { + return -ENODEV; + } + + return 0; +} + +static const struct rtc_driver_api rv3028_driver_api = { + .set_time = rv3028_set_time, + .get_time = rv3028_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rv3028_alarm_get_supported_fields, + .alarm_set_time = rv3028_alarm_set_time, + .alarm_get_time = rv3028_alarm_get_time, + .alarm_is_pending = rv3028_alarm_is_pending, +#if RV3028_INT_GPIOS_IN_USE + .alarm_set_callback = rv3028_alarm_set_callback, +#endif /* RV3028_INT_GPIOS_IN_USE */ +#endif /* CONFIG_RTC_ALARM */ +#if RV3028_INT_GPIOS_IN_USE && defined(CONFIG_RTC_UPDATE) + .update_set_callback = rv3028_update_set_callback, +#endif /* RV3028_INT_GPIOS_IN_USE && defined(CONFIG_RTC_UPDATE) */ +}; + +#define RV3028_BSM_FROM_DT_INST(inst) \ + UTIL_CAT(RV3028_BSM_, DT_INST_STRING_UPPER_TOKEN(inst, backup_switch_mode)) + +#define RV3028_BACKUP_FROM_DT_INST(inst) \ + ((FIELD_PREP(RV3028_BACKUP_BSM, RV3028_BSM_FROM_DT_INST(inst))) | \ + (FIELD_PREP(RV3028_BACKUP_TCR, DT_INST_ENUM_IDX_OR(inst, trickle_resistor_ohms, 0))) | \ + (DT_INST_NODE_HAS_PROP(inst, trickle_resistor_ohms) ? RV3028_BACKUP_TCE : 0)) + +#define RV3028_INIT(inst) \ + static const struct rv3028_config rv3028_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .cof = DT_INST_ENUM_IDX_OR(inst, clkout_frequency, RV3028_CLKOUT_FD_LOW), \ + .backup = RV3028_BACKUP_FROM_DT_INST(inst), \ + IF_ENABLED(RV3028_INT_GPIOS_IN_USE, \ + (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0})))}; \ + \ + static struct rv3028_data rv3028_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, &rv3028_init, NULL, &rv3028_data_##inst, \ + &rv3028_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &rv3028_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RV3028_INIT) diff --git a/drivers/rtc/rtc_shell.c b/drivers/rtc/rtc_shell.c index 714d63c6759b5f..a87056c6ed7070 100644 --- a/drivers/rtc/rtc_shell.c +++ b/drivers/rtc/rtc_shell.c @@ -217,6 +217,16 @@ static int cmd_get(const struct shell *sh, size_t argc, char **argv) return 0; } +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_lookup(idx, NULL); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + #define RTC_GET_HELP \ ("Get current time (UTC)\n" \ "Usage: rtc get ") @@ -225,10 +235,12 @@ static int cmd_get(const struct shell *sh, size_t argc, char **argv) ("Set UTC time\n" \ "Usage: rtc set | | ") +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + SHELL_STATIC_SUBCMD_SET_CREATE(sub_rtc, /* Alphabetically sorted */ - SHELL_CMD_ARG(set, NULL, RTC_SET_HELP, cmd_set, 3, 0), - SHELL_CMD_ARG(get, NULL, RTC_GET_HELP, cmd_get, 2, 0), + SHELL_CMD_ARG(set, &dsub_device_name, RTC_SET_HELP, cmd_set, 3, 0), + SHELL_CMD_ARG(get, &dsub_device_name, RTC_GET_HELP, cmd_get, 2, 0), SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(rtc, &sub_rtc, "RTC commands", NULL); diff --git a/drivers/sdhc/rcar_mmc.c b/drivers/sdhc/rcar_mmc.c index 8d637f0fd577e0..8cea5f6fb9a668 100644 --- a/drivers/sdhc/rcar_mmc.c +++ b/drivers/sdhc/rcar_mmc.c @@ -566,7 +566,7 @@ static int rcar_mmc_dma_rx_tx_data(const struct device *dev, struct sdhc_data *d reg |= RCAR_MMC_EXTMODE_DMA_EN; rcar_mmc_write_reg32(dev, RCAR_MMC_EXTMODE, reg); - dma_addr = z_mem_phys_addr(data->data); + dma_addr = k_mem_phys_addr(data->data); rcar_mmc_write_reg32(dev, RCAR_MMC_DMA_ADDR_L, dma_addr); rcar_mmc_write_reg32(dev, RCAR_MMC_DMA_ADDR_H, 0); @@ -830,7 +830,7 @@ static int rcar_mmc_rx_tx_data(const struct device *dev, struct sdhc_data *data, int ret = 0; #ifdef CONFIG_RCAR_MMC_DMA_SUPPORT - if (!(z_mem_phys_addr(data->data) >> 32)) { + if (!(k_mem_phys_addr(data->data) >> 32)) { ret = rcar_mmc_dma_rx_tx_data(dev, data, is_read); } else #endif @@ -2167,7 +2167,7 @@ static int rcar_mmc_init(const struct device *dev) exit_unmap: #if defined(DEVICE_MMIO_IS_IN_RAM) && defined(CONFIG_MMU) - z_phys_unmap((uint8_t *)DEVICE_MMIO_GET(dev), DEVICE_MMIO_ROM_PTR(dev)->size); + k_mem_unmap_phys_bare((uint8_t *)DEVICE_MMIO_GET(dev), DEVICE_MMIO_ROM_PTR(dev)->size); #endif return ret; } diff --git a/drivers/sensor/bosch/bme280/CMakeLists.txt b/drivers/sensor/bosch/bme280/CMakeLists.txt index 115c11359788a3..7ce886907f671f 100644 --- a/drivers/sensor/bosch/bme280/CMakeLists.txt +++ b/drivers/sensor/bosch/bme280/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources(bme280.c bme280_spi.c bme280_i2c.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API bme280_decoder.c bme280_async.c) diff --git a/drivers/sensor/bosch/bme280/bme280.c b/drivers/sensor/bosch/bme280/bme280.c index f2bd7514c01906..8c0f1bead3a3ac 100644 --- a/drivers/sensor/bosch/bme280/bme280.c +++ b/drivers/sensor/bosch/bme280/bme280.c @@ -26,38 +26,6 @@ LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL); #warning "BME280 driver enabled without any devices" #endif -struct bme280_data { - /* Compensation parameters. */ - uint16_t dig_t1; - int16_t dig_t2; - int16_t dig_t3; - uint16_t dig_p1; - int16_t dig_p2; - int16_t dig_p3; - int16_t dig_p4; - int16_t dig_p5; - int16_t dig_p6; - int16_t dig_p7; - int16_t dig_p8; - int16_t dig_p9; - uint8_t dig_h1; - int16_t dig_h2; - uint8_t dig_h3; - int16_t dig_h4; - int16_t dig_h5; - int8_t dig_h6; - - /* Compensated values. */ - int32_t comp_temp; - uint32_t comp_press; - uint32_t comp_humidity; - - /* Carryover between temperature and pressure/humidity compensation. */ - int32_t t_fine; - - uint8_t chip_id; -}; - struct bme280_config { union bme280_bus bus; const struct bme280_bus_io *bus_io; @@ -90,7 +58,7 @@ static inline int bme280_reg_write(const struct device *dev, uint8_t reg, * Compensation code taken from BME280 datasheet, Section 4.2.3 * "Compensation formula". */ -static void bme280_compensate_temp(struct bme280_data *data, int32_t adc_temp) +static int32_t bme280_compensate_temp(struct bme280_data *data, int32_t adc_temp) { int32_t var1, var2; @@ -101,10 +69,10 @@ static void bme280_compensate_temp(struct bme280_data *data, int32_t adc_temp) ((int32_t)data->dig_t3)) >> 14; data->t_fine = var1 + var2; - data->comp_temp = (data->t_fine * 5 + 128) >> 8; + return (data->t_fine * 5 + 128) >> 8; } -static void bme280_compensate_press(struct bme280_data *data, int32_t adc_press) +static uint32_t bme280_compensate_press(struct bme280_data *data, int32_t adc_press) { int64_t var1, var2, p; @@ -118,8 +86,7 @@ static void bme280_compensate_press(struct bme280_data *data, int32_t adc_press) /* Avoid exception caused by division by zero. */ if (var1 == 0) { - data->comp_press = 0U; - return; + return 0; } p = 1048576 - adc_press; @@ -128,10 +95,10 @@ static void bme280_compensate_press(struct bme280_data *data, int32_t adc_press) var2 = (((int64_t)data->dig_p8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)data->dig_p7) << 4); - data->comp_press = (uint32_t)p; + return (uint32_t)p; } -static void bme280_compensate_humidity(struct bme280_data *data, +static uint32_t bme280_compensate_humidity(struct bme280_data *data, int32_t adc_humidity) { int32_t h; @@ -146,7 +113,7 @@ static void bme280_compensate_humidity(struct bme280_data *data, ((int32_t)data->dig_h1)) >> 4)); h = (h > 419430400 ? 419430400 : h); - data->comp_humidity = (uint32_t)(h >> 12); + return (uint32_t)(h >> 12); } static int bme280_wait_until_ready(const struct device *dev) @@ -166,10 +133,10 @@ static int bme280_wait_until_ready(const struct device *dev) return 0; } -static int bme280_sample_fetch(const struct device *dev, - enum sensor_channel chan) +int bme280_sample_fetch_helper(const struct device *dev, + enum sensor_channel chan, struct bme280_reading *reading) { - struct bme280_data *data = dev->data; + struct bme280_data *dev_data = dev->data; uint8_t buf[8]; int32_t adc_press, adc_temp, adc_humidity; int size = 6; @@ -197,7 +164,7 @@ static int bme280_sample_fetch(const struct device *dev, return ret; } - if (data->chip_id == BME280_CHIP_ID) { + if (dev_data->chip_id == BME280_CHIP_ID) { size = 8; } ret = bme280_reg_read(dev, BME280_REG_PRESS_MSB, buf, size); @@ -208,17 +175,24 @@ static int bme280_sample_fetch(const struct device *dev, adc_press = (buf[0] << 12) | (buf[1] << 4) | (buf[2] >> 4); adc_temp = (buf[3] << 12) | (buf[4] << 4) | (buf[5] >> 4); - bme280_compensate_temp(data, adc_temp); - bme280_compensate_press(data, adc_press); + reading->comp_temp = bme280_compensate_temp(dev_data, adc_temp); + reading->comp_press = bme280_compensate_press(dev_data, adc_press); - if (data->chip_id == BME280_CHIP_ID) { + if (dev_data->chip_id == BME280_CHIP_ID) { adc_humidity = (buf[6] << 8) | buf[7]; - bme280_compensate_humidity(data, adc_humidity); + reading->comp_humidity = bme280_compensate_humidity(dev_data, adc_humidity); } return 0; } +int bme280_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct bme280_data *data = dev->data; + + return bme280_sample_fetch_helper(dev, chan, &data->reading); +} + static int bme280_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) @@ -228,21 +202,21 @@ static int bme280_channel_get(const struct device *dev, switch (chan) { case SENSOR_CHAN_AMBIENT_TEMP: /* - * data->comp_temp has a resolution of 0.01 degC. So + * comp_temp has a resolution of 0.01 degC. So * 5123 equals 51.23 degC. */ - val->val1 = data->comp_temp / 100; - val->val2 = data->comp_temp % 100 * 10000; + val->val1 = data->reading.comp_temp / 100; + val->val2 = data->reading.comp_temp % 100 * 10000; break; case SENSOR_CHAN_PRESS: /* - * data->comp_press has 24 integer bits and 8 + * comp_press has 24 integer bits and 8 * fractional. Output value of 24674867 represents * 24674867/256 = 96386.2 Pa = 963.862 hPa */ - val->val1 = (data->comp_press >> 8) / 1000U; - val->val2 = (data->comp_press >> 8) % 1000 * 1000U + - (((data->comp_press & 0xff) * 1000U) >> 8); + val->val1 = (data->reading.comp_press >> 8) / 1000U; + val->val2 = (data->reading.comp_press >> 8) % 1000 * 1000U + + (((data->reading.comp_press & 0xff) * 1000U) >> 8); break; case SENSOR_CHAN_HUMIDITY: /* The BMP280 doesn't have a humidity sensor */ @@ -250,12 +224,12 @@ static int bme280_channel_get(const struct device *dev, return -ENOTSUP; } /* - * data->comp_humidity has 22 integer bits and 10 + * comp_humidity has 22 integer bits and 10 * fractional. Output value of 47445 represents * 47445/1024 = 46.333 %RH */ - val->val1 = (data->comp_humidity >> 10); - val->val2 = (((data->comp_humidity & 0x3ff) * 1000U * 1000U) >> 10); + val->val1 = (data->reading.comp_humidity >> 10); + val->val2 = (((data->reading.comp_humidity & 0x3ff) * 1000U * 1000U) >> 10); break; default: return -ENOTSUP; @@ -267,6 +241,10 @@ static int bme280_channel_get(const struct device *dev, static const struct sensor_driver_api bme280_api_funcs = { .sample_fetch = bme280_sample_fetch, .channel_get = bme280_channel_get, +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = bme280_submit, + .get_decoder = bme280_get_decoder, +#endif }; static int bme280_read_compensation(const struct device *dev) diff --git a/drivers/sensor/bosch/bme280/bme280.h b/drivers/sensor/bosch/bme280/bme280.h index afc4ce275dcee7..125659cb58616d 100644 --- a/drivers/sensor/bosch/bme280/bme280.h +++ b/drivers/sensor/bosch/bme280/bme280.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #define DT_DRV_COMPAT bosch_bme280 @@ -158,4 +160,64 @@ extern const struct bme280_bus_io bme280_bus_io_i2c; BME280_TEMP_OVER | \ BME280_MODE_SLEEP) +struct bme280_reading { + /* Compensated values. */ + int32_t comp_temp; + uint32_t comp_press; + uint32_t comp_humidity; +}; + +struct bme280_data { + /* Compensation parameters. */ + uint16_t dig_t1; + int16_t dig_t2; + int16_t dig_t3; + uint16_t dig_p1; + int16_t dig_p2; + int16_t dig_p3; + int16_t dig_p4; + int16_t dig_p5; + int16_t dig_p6; + int16_t dig_p7; + int16_t dig_p8; + int16_t dig_p9; + uint8_t dig_h1; + int16_t dig_h2; + uint8_t dig_h3; + int16_t dig_h4; + int16_t dig_h5; + int8_t dig_h6; + + /* Carryover between temperature and pressure/humidity compensation. */ + int32_t t_fine; + + uint8_t chip_id; + + struct bme280_reading reading; +}; + +/* + * RTIO + */ + +struct bme280_decoder_header { + uint64_t timestamp; +} __attribute__((__packed__)); + +struct bme280_encoded_data { + struct bme280_decoder_header header; + struct bme280_reading reading; +}; + +int bme280_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); + +int bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +int bme280_sample_fetch(const struct device *dev, + enum sensor_channel chan); + +int bme280_sample_fetch_helper(const struct device *dev, + enum sensor_channel chan, + struct bme280_reading *reading); + #endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */ diff --git a/drivers/sensor/bosch/bme280/bme280_async.c b/drivers/sensor/bosch/bme280/bme280_async.c new file mode 100644 index 00000000000000..562beb4f09058b --- /dev/null +++ b/drivers/sensor/bosch/bme280/bme280_async.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "bme280.h" + +LOG_MODULE_DECLARE(BME280, CONFIG_SENSOR_LOG_LEVEL); + +int bme280_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + uint32_t min_buf_len = sizeof(struct bme280_encoded_data); + int rc; + uint8_t *buf; + uint32_t buf_len; + + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + const struct sensor_chan_spec *const channels = cfg->channels; + const size_t num_channels = cfg->count; + + /* Check if the requested channels are supported */ + for (size_t i = 0; i < num_channels; i++) { + switch (channels[i].chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_HUMIDITY: + case SENSOR_CHAN_PRESS: + case SENSOR_CHAN_ALL: + break; + default: + LOG_ERR("Unsupported channel type %d", channels[i].chan_type); + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + return -ENOTSUP; + } + } + + rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); + if (rc != 0) { + LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); + rtio_iodev_sqe_err(iodev_sqe, rc); + return rc; + } + + struct bme280_encoded_data *edata; + + edata = (struct bme280_encoded_data *)buf; + + edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + + rc = bme280_sample_fetch_helper(dev, SENSOR_CHAN_ALL, &edata->reading); + if (rc != 0) { + LOG_ERR("Failed to fetch samples"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return rc; + } + + rtio_iodev_sqe_ok(iodev_sqe, 0); + + return 0; +} diff --git a/drivers/sensor/bosch/bme280/bme280_decoder.c b/drivers/sensor/bosch/bme280/bme280_decoder.c new file mode 100644 index 00000000000000..7158fd37d5a8ce --- /dev/null +++ b/drivers/sensor/bosch/bme280/bme280_decoder.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2024 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bme280.h" +#include + +static int bme280_decoder_get_frame_count(const uint8_t *buffer, + struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + ARG_UNUSED(buffer); + ARG_UNUSED(chan_spec); + + /* This sensor lacks a FIFO; there will always only be one frame at a time. */ + *frame_count = 1; + return 0; +} + +static int bme280_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, + size_t *frame_size) +{ + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_HUMIDITY: + case SENSOR_CHAN_PRESS: + *base_size = sizeof(struct sensor_q31_sample_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + +#define BME280_HUM_SHIFT (22) +#define BME280_PRESS_SHIFT (24) +#define BME280_TEMP_SHIFT (24) + +static void bme280_convert_double_to_q31(double reading, int32_t shift, q31_t *out) +{ + reading = reading * pow(2, 31 - shift); + + int64_t reading_round = (reading < 0) ? (reading - 0.5) : (reading + 0.5); + int32_t reading_q31 = CLAMP(reading_round, INT32_MIN, INT32_MAX); + + if (reading_q31 < 0) { + reading_q31 = abs(reading_q31); + reading_q31 = ~reading_q31; + reading_q31++; + } + + *out = reading_q31; +} + +/* Refer to bme280.c bme280_channel_get() */ +static void bme280_convert_signed_temp_raw_to_q31(int32_t reading, q31_t *out) +{ + double temp_double = reading / 100.0; + + bme280_convert_double_to_q31(temp_double, BME280_TEMP_SHIFT, out); +} + +static void bme280_convert_unsigned_pressure_raw_to_q31(uint32_t reading, q31_t *out) +{ + double press_double = (reading / 256.0) / 1000.0; /* Pa -> hPa */ + + bme280_convert_double_to_q31(press_double, BME280_PRESS_SHIFT, out); +} + +static void bme280_convert_unsigned_humidity_raw_to_q31(uint32_t reading, q31_t *out) +{ + double hum_double = (reading / 1024.0); + + bme280_convert_double_to_q31(hum_double, BME280_HUM_SHIFT, out); +} + +static int bme280_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct bme280_encoded_data *edata = (const struct bme280_encoded_data *)buffer; + + if (*fit != 0) { + return 0; + } + + struct sensor_q31_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + bme280_convert_signed_temp_raw_to_q31(edata->reading.comp_temp, + &out->readings[0].temperature); + out->shift = BME280_TEMP_SHIFT; + break; + case SENSOR_CHAN_PRESS: + bme280_convert_unsigned_pressure_raw_to_q31(edata->reading.comp_press, + &out->readings[0].pressure); + out->shift = BME280_PRESS_SHIFT; + break; + case SENSOR_CHAN_HUMIDITY: + bme280_convert_unsigned_humidity_raw_to_q31(edata->reading.comp_humidity, + &out->readings[0].humidity); + out->shift = BME280_HUM_SHIFT; + break; + default: + return -EINVAL; + } + + *fit = 1; + + return 1; +} + + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = bme280_decoder_get_frame_count, + .get_size_info = bme280_decoder_get_size_info, + .decode = bme280_decoder_decode, +}; + +int bme280_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + + return 0; +} diff --git a/drivers/sensor/current_amp/current_amp.c b/drivers/sensor/current_amp/current_amp.c index d760e4b34b0186..e9d5e1a09a217b 100644 --- a/drivers/sensor/current_amp/current_amp.c +++ b/drivers/sensor/current_amp/current_amp.c @@ -61,11 +61,11 @@ static int get(const struct device *dev, enum sensor_channel chan, struct sensor i_ma = raw_val; current_sense_amplifier_scale_dt(config, &i_ma); - LOG_DBG("%d/%d, %dmV, current:%duA", data->raw, + LOG_DBG("%d/%d, %dmV, current:%dmA", data->raw, (1 << data->sequence.resolution) - 1, raw_val, i_ma); val->val1 = i_ma / 1000; - val->val2 = i_ma % 1000; + val->val2 = (i_ma % 1000) * 1000; return 0; } diff --git a/drivers/sensor/ens160/ens160.c b/drivers/sensor/ens160/ens160.c index a2b0fb7103e570..c5420b7cd39d54 100644 --- a/drivers/sensor/ens160/ens160.c +++ b/drivers/sensor/ens160/ens160.c @@ -148,6 +148,7 @@ static int ens160_channel_get(const struct device *dev, enum sensor_channel chan case SENSOR_CHAN_ENS160_AQI: val->val1 = data->aqi; val->val2 = 0; + break; default: return -ENOTSUP; } diff --git a/drivers/sensor/seeed/grove/Kconfig b/drivers/sensor/seeed/grove/Kconfig index 9563bdd7b3aa63..a91c66c099637d 100644 --- a/drivers/sensor/seeed/grove/Kconfig +++ b/drivers/sensor/seeed/grove/Kconfig @@ -16,7 +16,6 @@ config GROVE_LIGHT_SENSOR bool "The Seeed Grove Light Sensor" default y depends on DT_HAS_SEEED_GROVE_LIGHT_ENABLED - depends on !MINIMAL_LIBC select ADC help Setting this value will enable driver support for the Grove Light @@ -26,7 +25,6 @@ config GROVE_TEMPERATURE_SENSOR bool "The Seeed Grove Temperature Sensor" default y depends on DT_HAS_SEEED_GROVE_TEMPERATURE_ENABLED - depends on !MINIMAL_LIBC select ADC help Setting this value will enable driver support for the Grove diff --git a/drivers/sensor/sensirion/shtcx/shtcx.c b/drivers/sensor/sensirion/shtcx/shtcx.c index 9e670087493e67..1abd4694a98605 100644 --- a/drivers/sensor/sensirion/shtcx/shtcx.c +++ b/drivers/sensor/sensirion/shtcx/shtcx.c @@ -237,10 +237,13 @@ static int shtcx_init(const struct device *dev) return 0; } +#define SHTCX_CHIP(inst) \ + (DT_INST_NODE_HAS_COMPAT(inst, sensirion_shtc1) ? CHIP_SHTC1 : CHIP_SHTC3) + #define SHTCX_CONFIG(inst) \ { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ - .chip = DT_INST_ENUM_IDX(inst, chip), \ + .chip = SHTCX_CHIP(inst), \ .measure_mode = DT_INST_ENUM_IDX(inst, measure_mode), \ .clock_stretching = DT_INST_PROP(inst, clock_stretching) \ } diff --git a/drivers/sensor/st/CMakeLists.txt b/drivers/sensor/st/CMakeLists.txt index 31b191490b5c55..b833043ae6c666 100644 --- a/drivers/sensor/st/CMakeLists.txt +++ b/drivers/sensor/st/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory_ifdef(CONFIG_LSM6DSV16X lsm6dsv16x) add_subdirectory_ifdef(CONFIG_LSM9DS0_GYRO lsm9ds0_gyro) add_subdirectory_ifdef(CONFIG_LSM9DS0_MFD lsm9ds0_mfd) add_subdirectory_ifdef(CONFIG_QDEC_STM32 qdec_stm32) +add_subdirectory_ifdef(CONFIG_STM32_DIGI_TEMP stm32_digi_temp) add_subdirectory_ifdef(CONFIG_STM32_TEMP stm32_temp) add_subdirectory_ifdef(CONFIG_STM32_VBAT stm32_vbat) add_subdirectory_ifdef(CONFIG_STM32_VREF stm32_vref) diff --git a/drivers/sensor/st/Kconfig b/drivers/sensor/st/Kconfig index bb1cbd6b6a09e5..a3f03a36b668db 100644 --- a/drivers/sensor/st/Kconfig +++ b/drivers/sensor/st/Kconfig @@ -32,6 +32,7 @@ source "drivers/sensor/st/lsm6dsv16x/Kconfig" source "drivers/sensor/st/lsm9ds0_gyro/Kconfig" source "drivers/sensor/st/lsm9ds0_mfd/Kconfig" source "drivers/sensor/st/qdec_stm32/Kconfig" +source "drivers/sensor/st/stm32_digi_temp/Kconfig" source "drivers/sensor/st/stm32_temp/Kconfig" source "drivers/sensor/st/stm32_vbat/Kconfig" source "drivers/sensor/st/stm32_vref/Kconfig" diff --git a/drivers/sensor/st/hts221/hts221.c b/drivers/sensor/st/hts221/hts221.c index 677607c42a6030..846cccc6409b13 100644 --- a/drivers/sensor/st/hts221/hts221.c +++ b/drivers/sensor/st/hts221/hts221.c @@ -191,8 +191,6 @@ int hts221_init(const struct device *dev) LOG_ERR("Failed to initialize interrupt."); return status; } -#else - LOG_INF("Cannot enable trigger without drdy-gpios"); #endif return 0; diff --git a/drivers/sensor/st/lps22hh/lps22hh.c b/drivers/sensor/st/lps22hh/lps22hh.c index 01c698ba3c6223..1ea4f2afb5b8e2 100644 --- a/drivers/sensor/st/lps22hh/lps22hh.c +++ b/drivers/sensor/st/lps22hh/lps22hh.c @@ -39,15 +39,36 @@ static int lps22hh_sample_fetch(const struct device *dev, uint32_t raw_press; int16_t raw_temp; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); - - if (lps22hh_pressure_raw_get(ctx, &raw_press) < 0) { - LOG_DBG("Failed to read sample"); - return -EIO; - } - if (lps22hh_temperature_raw_get(ctx, &raw_temp) < 0) { - LOG_DBG("Failed to read sample"); - return -EIO; + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL + || chan == SENSOR_CHAN_PRESS + || chan == SENSOR_CHAN_AMBIENT_TEMP); + + switch (chan) { + case SENSOR_CHAN_PRESS: + if (lps22hh_pressure_raw_get(ctx, &raw_press) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + break; + case SENSOR_CHAN_AMBIENT_TEMP: + if (lps22hh_temperature_raw_get(ctx, &raw_temp) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + break; + case SENSOR_CHAN_ALL: + if (lps22hh_pressure_raw_get(ctx, &raw_press) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + if (lps22hh_temperature_raw_get(ctx, &raw_temp) < 0) { + LOG_DBG("Failed to read sample"); + return -EIO; + } + break; + default: + LOG_ERR("Unsupported sensor channel"); + return -ENOTSUP; } data->sample_press = raw_press; diff --git a/drivers/sensor/st/stm32_digi_temp/CMakeLists.txt b/drivers/sensor/st/stm32_digi_temp/CMakeLists.txt new file mode 100644 index 00000000000000..1f155f3219dedf --- /dev/null +++ b/drivers/sensor/st/stm32_digi_temp/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(stm32_digi_temp.c) diff --git a/drivers/sensor/st/stm32_digi_temp/Kconfig b/drivers/sensor/st/stm32_digi_temp/Kconfig new file mode 100644 index 00000000000000..e44814ee541f36 --- /dev/null +++ b/drivers/sensor/st/stm32_digi_temp/Kconfig @@ -0,0 +1,18 @@ +# STM32 digital temperature sensor configuration options + +# Copyright (c) 2024 Aurelien Jarno +# SPDX-License-Identifier: Apache-2.0 + +config STM32_DIGI_TEMP + bool "STM32 Digital Temperature Sensor" + default y + depends on DT_HAS_ST_STM32_DIGI_TEMP_ENABLED + depends on SOC_FAMILY_STM32 + help + Enable the driver for STM32 digital temperature sensor. This sensor + is different from the STM32 analog temperature sensor, which is read + by an ADC. While both drivers have similar code footprint, the analog + temperature driver also requires the ADC driver to be enabled. The + sensors differ in precision, accuracy and power consumption. Users + are encouraged to consult the datasheet to select the sensor that + best suits their needs. diff --git a/drivers/sensor/st/stm32_digi_temp/stm32_digi_temp.c b/drivers/sensor/st/stm32_digi_temp/stm32_digi_temp.c new file mode 100644 index 00000000000000..d862bb7a29a391 --- /dev/null +++ b/drivers/sensor/st/stm32_digi_temp/stm32_digi_temp.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2024 Aurelien Jarno + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_stm32_digi_temp + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(stm32_digi_temp, CONFIG_SENSOR_LOG_LEVEL); + +/* Constants */ +#define ONE_MHZ 1000000 /* Hz */ +#define TS1_T0_VAL0 30 /* °C */ +#define TS1_T0_VAL1 130 /* °C */ +#define SAMPLING_TIME 15 /* best precision */ + +struct stm32_digi_temp_data { + struct k_sem sem_isr; + struct k_mutex mutex; + + /* Peripheral clock frequency */ + uint32_t pclk_freq; + /* Engineering value of the frequency measured at T0 in Hz */ + uint32_t t0_freq; + /* Engineering value of the T0 temperature in °C */ + uint16_t t0; + /* Engineering value of the ramp coefficient in Hz / °C */ + uint16_t ramp_coeff; + + /* Raw sensor value */ + uint16_t raw; +}; + +struct stm32_digi_temp_config { + /* DTS instance. */ + DTS_TypeDef *base; + /* Clock configuration. */ + struct stm32_pclken pclken; + /* Interrupt configuration. */ + void (*irq_config)(const struct device *dev); +}; + +static void stm32_digi_temp_isr(const struct device *dev) +{ + struct stm32_digi_temp_data *data = dev->data; + const struct stm32_digi_temp_config *cfg = dev->config; + DTS_TypeDef *dts = cfg->base; + + /* Clear interrupt */ + SET_BIT(dts->ICIFR, DTS_ICIFR_TS1_CITEF); + + /* Give semaphore */ + k_sem_give(&data->sem_isr); +} + +static int stm32_digi_temp_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + struct stm32_digi_temp_data *data = dev->data; + DTS_TypeDef *dts = cfg->base; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) { + return -ENOTSUP; + } + + k_mutex_lock(&data->mutex, K_FOREVER); + + /* Wait for the sensor to be ready (~40µS delay after enabling it) */ + while (READ_BIT(dts->SR, DTS_SR_TS1_RDY) == 0) { + k_yield(); + } + + /* Trigger a measurement */ + SET_BIT(dts->CFGR1, DTS_CFGR1_TS1_START); + CLEAR_BIT(dts->CFGR1, DTS_CFGR1_TS1_START); + + /* Wait for interrupt */ + k_sem_take(&data->sem_isr, K_FOREVER); + + /* Read value */ + data->raw = READ_REG(dts->DR); + + k_mutex_unlock(&data->mutex); + + return 0; +} + +static int stm32_digi_temp_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct stm32_digi_temp_data *data = dev->data; + float meas_freq, temp; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) { + return -ENOTSUP; + } + + meas_freq = ((float)data->pclk_freq * SAMPLING_TIME) / data->raw; + temp = data->t0 + (meas_freq - data->t0_freq) / data->ramp_coeff; + + return sensor_value_from_float(val, temp); +} + +static void stm32_digi_temp_configure(const struct device *dev) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + struct stm32_digi_temp_data *data = dev->data; + DTS_TypeDef *dts = cfg->base; + int clk_div; + + /* Use the prescaler to obtain an internal frequency lower than 1 MHz. + * Allowed values are between 0 and 127. + */ + clk_div = MIN(DIV_ROUND_UP(data->pclk_freq, ONE_MHZ), 127); + MODIFY_REG(dts->CFGR1, DTS_CFGR1_HSREF_CLK_DIV_Msk, + clk_div << DTS_CFGR1_HSREF_CLK_DIV_Pos); + + /* Select PCLK as reference clock */ + MODIFY_REG(dts->CFGR1, DTS_CFGR1_REFCLK_SEL_Msk, + 0 << DTS_CFGR1_REFCLK_SEL_Pos); + + /* Select trigger */ + MODIFY_REG(dts->CFGR1, DTS_CFGR1_TS1_INTRIG_SEL_Msk, + 0 << DTS_CFGR1_TS1_INTRIG_SEL_Pos); + + /* Set sampling time */ + MODIFY_REG(dts->CFGR1, DTS_CFGR1_TS1_SMP_TIME_Msk, + SAMPLING_TIME << DTS_CFGR1_TS1_SMP_TIME_Pos); +} + +static void stm32_digi_temp_enable(const struct device *dev) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + DTS_TypeDef *dts = cfg->base; + + /* Enable the sensor */ + SET_BIT(dts->CFGR1, DTS_CFGR1_TS1_EN); + + /* Enable interrupt */ + SET_BIT(dts->ITENR, DTS_ITENR_TS1_ITEEN); +} + +#ifdef CONFIG_PM_DEVICE +static void stm32_digi_temp_disable(const struct device *dev) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + DTS_TypeDef *dts = cfg->base; + + /* Disable interrupt */ + CLEAR_BIT(dts->ITENR, DTS_ITENR_TS1_ITEEN); + + /* Disable the sensor */ + CLEAR_BIT(dts->CFGR1, DTS_CFGR1_TS1_EN); +} +#endif + +static int stm32_digi_temp_init(const struct device *dev) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + struct stm32_digi_temp_data *data = dev->data; + DTS_TypeDef *dts = cfg->base; + + /* enable clock for subsystem */ + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + + if (!device_is_ready(clk)) { + LOG_ERR("Clock control device not ready"); + return -ENODEV; + } + + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken) != 0) { + LOG_ERR("Could not enable DTS clock"); + return -EIO; + } + + /* Save the peripheral clock frequency in the data structure to avoid + * querying it for each call to the channel_get method. + */ + if (clock_control_get_rate(clk, (clock_control_subsys_t) &cfg->pclken, + &data->pclk_freq) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclken)"); + return -EIO; + } + + /* Save the calibration data in the data structure to avoid reading + * them for each call to the channel_get method, as this requires + * enabling the peripheral clock. + */ + data->ramp_coeff = dts->RAMPVALR & DTS_RAMPVALR_TS1_RAMP_COEFF; + data->t0_freq = (dts->T0VALR1 & DTS_T0VALR1_TS1_FMT0) * 100; /* 0.1 kHz -> Hz */ + + /* T0 temperature from the datasheet */ + switch (dts->T0VALR1 >> DTS_T0VALR1_TS1_T0_Pos) { + case 0: + data->t0 = TS1_T0_VAL0; + break; + case 1: + data->t0 = TS1_T0_VAL1; + break; + default: + LOG_ERR("Unknown T0 temperature value"); + return -EIO; + } + + /* Init mutex and semaphore */ + k_mutex_init(&data->mutex); + k_sem_init(&data->sem_isr, 0, 1); + + /* Configure and enable the sensor */ + cfg->irq_config(dev); + stm32_digi_temp_configure(dev); + stm32_digi_temp_enable(dev); + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int stm32_digi_temp_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct stm32_digi_temp_config *cfg = dev->config; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + int err; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + /* enable clock */ + err = clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken); + if (err != 0) { + LOG_ERR("Could not enable DTS clock"); + return err; + } + /* Enable sensor */ + stm32_digi_temp_enable(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + /* Disable sensor */ + stm32_digi_temp_disable(dev); + /* Stop device clock */ + err = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken); + if (err != 0) { + LOG_ERR("Could not disable DTS clock"); + return err; + } + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + +static const struct sensor_driver_api stm32_digi_temp_driver_api = { + .sample_fetch = stm32_digi_temp_sample_fetch, + .channel_get = stm32_digi_temp_channel_get, +}; + +#define STM32_DIGI_TEMP_INIT(index) \ +static void stm32_digi_temp_irq_config_func_##index(const struct device *dev) \ +{ \ + IRQ_CONNECT(DT_INST_IRQN(index), \ + DT_INST_IRQ(index, priority), \ + stm32_digi_temp_isr, DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQN(index)); \ +} \ + \ +static struct stm32_digi_temp_data stm32_digi_temp_dev_data_##index; \ + \ +static const struct stm32_digi_temp_config stm32_digi_temp_dev_config_##index = { \ + .base = (DTS_TypeDef *)DT_INST_REG_ADDR(index), \ + .pclken = { \ + .enr = DT_INST_CLOCKS_CELL(index, bits), \ + .bus = DT_INST_CLOCKS_CELL(index, bus) \ + }, \ + .irq_config = stm32_digi_temp_irq_config_func_##index, \ +}; \ + \ +PM_DEVICE_DT_INST_DEFINE(index, stm32_digi_temp_pm_action); \ + \ +SENSOR_DEVICE_DT_INST_DEFINE(index, stm32_digi_temp_init, \ + PM_DEVICE_DT_INST_GET(index), \ + &stm32_digi_temp_dev_data_##index, \ + &stm32_digi_temp_dev_config_##index, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &stm32_digi_temp_driver_api); \ + +DT_INST_FOREACH_STATUS_OKAY(STM32_DIGI_TEMP_INIT) diff --git a/drivers/sensor/ti/tmag5273/tmag5273.c b/drivers/sensor/ti/tmag5273/tmag5273.c index 0ef91725deef87..7c7cd92a25b0d6 100644 --- a/drivers/sensor/ti/tmag5273/tmag5273.c +++ b/drivers/sensor/ti/tmag5273/tmag5273.c @@ -102,17 +102,17 @@ static int tmag5273_reset_device_status(const struct device *dev) /** * @brief checks for DIAG_FAIL errors and reads out the DEVICE_STATUS register if necessary * - * Prints a human readable representation to the log, if \c CONFIG_LOG is activated. - * - * @param drv_cfg[in] driver instance configuration - * @param device_status[out] DEVICE_STATUS register if DIAG_FAIL is set + * @param[in] drv_cfg driver instance configuration + * @param[out] device_status DEVICE_STATUS register if DIAG_FAIL is set * * @retval 0 on success - * @retval "!= 0" on error (see @ref i2c_reg_read_byte for error codes) + * @retval "!= 0" on error + * - \c -EIO on any set error device status bit + * - see @ref i2c_reg_read_byte for error codes * * @note - * If tmag5273_config.ignore_diag_fail is se - * - \a device_status will be always set to \c 0, + * If tmag5273_config.ignore_diag_fail is set + * - \a device_status will be always set to \c 0, * - the function always returns \c 0. */ static int tmag5273_check_device_status(const struct tmag5273_config *drv_cfg, @@ -144,23 +144,23 @@ static int tmag5273_check_device_status(const struct tmag5273_config *drv_cfg, } if ((*device_status & TMAG5273_VCC_UV_ER_MSK) == TMAG5273_VCC_UV_ERR) { - LOG_WRN("VCC undervoltage detected"); + LOG_ERR("VCC under voltage detected"); } #ifdef CONFIG_CRC if (drv_cfg->crc_enabled && ((*device_status & TMAG5273_OTP_CRC_ER_MSK) == TMAG5273_OTP_CRC_ERR)) { - LOG_WRN("OTP CRC error detected"); + LOG_ERR("OTP CRC error detected"); } #endif if ((*device_status & TMAG5273_INT_ER_MSK) == TMAG5273_INT_ERR) { - LOG_WRN("INT pin error detected"); + LOG_ERR("INT pin error detected"); } if ((*device_status & TMAG5273_OSC_ER_MSK) == TMAG5273_OSC_ERR) { - LOG_WRN("Oscillator error detected"); + LOG_ERR("Oscillator error detected"); } - return 0; + return -EIO; } /** @@ -689,11 +689,6 @@ static int tmag5273_sample_fetch(const struct device *dev, enum sensor_channel c return retval; } - if ((i2c_buffer[TMAG5273_REG_CONV_STATUS - TMAG5273_REG_RESULT_BEGIN] & - TMAG5273_DIAG_STATUS_MSK) == TMAG5273_DIAG_FAIL) { - return -EIO; - } - bool all_channels = (chan == SENSOR_CHAN_ALL); bool all_xyz = all_channels || (chan == SENSOR_CHAN_MAGN_XYZ); bool all_angle_magnitude = all_channels || ((int)chan == TMAG5273_CHAN_ANGLE_MAGNITUDE); @@ -1118,7 +1113,7 @@ static int tmag5273_init(const struct device *dev) return -EINVAL; } - tmag5273_check_device_status(drv_cfg, ®data); + (void)tmag5273_check_device_status(drv_cfg, ®data); retval = tmag5273_reset_device_status(dev); if (retval < 0) { diff --git a/drivers/serial/Kconfig.emul b/drivers/serial/Kconfig.emul index e61130a13c77e2..dd243bade5f0bb 100644 --- a/drivers/serial/Kconfig.emul +++ b/drivers/serial/Kconfig.emul @@ -8,6 +8,7 @@ config UART_EMUL default y depends on DT_HAS_ZEPHYR_UART_EMUL_ENABLED select SERIAL_SUPPORT_INTERRUPT + select SERIAL_SUPPORT_ASYNC select RING_BUFFER select EXPERIMENTAL help diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 158731404e63e0..930dd00e3d8691 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -31,7 +31,8 @@ config UART_NRFX_UARTE config UART_NRFX_UARTE_LEGACY_SHIM bool "Legacy UARTE shim" depends on UART_NRFX_UARTE - depends on !SOC_SERIES_NRF54LX && !SOC_SERIES_NRF54HX + depends on !SOC_SERIES_NRF54LX + depends on RISCV || !SOC_SERIES_NRF54HX # New shim takes more ROM. Until it is fixed use legacy shim. default y diff --git a/drivers/serial/Kconfig.nrfx_uart_instance b/drivers/serial/Kconfig.nrfx_uart_instance index 71b25dbeba07f0..7f135d2f997c55 100644 --- a/drivers/serial/Kconfig.nrfx_uart_instance +++ b/drivers/serial/Kconfig.nrfx_uart_instance @@ -54,6 +54,7 @@ config UART_$(nrfx_uart_num)_NRF_HW_ASYNC depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) depends on UART_ASYNC_API depends on UART_NRFX_UARTE_LEGACY_SHIM + 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 diff --git a/drivers/serial/Kconfig.psoc6 b/drivers/serial/Kconfig.psoc6 index 66981e3766c40e..4f0bb2c8fca0a8 100644 --- a/drivers/serial/Kconfig.psoc6 +++ b/drivers/serial/Kconfig.psoc6 @@ -11,5 +11,6 @@ config UART_PSOC6 select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select USE_INFINEON_UART + select PINCTRL help This option enables the SCB[UART] driver for PSoC-6 SoC family. diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 2dc0f8495fdf1d..2dc8029c7f911a 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 Fabian Blatz + * Copyright (c) 2024 grandcentrix GmbH * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,13 +23,10 @@ struct uart_emul_config { size_t latch_buffer_size; }; -struct uart_emul_work { - struct k_work work; - const struct device *dev; -}; - /* Device run time data */ struct uart_emul_data { + const struct device *dev; + struct uart_config cfg; int errors; @@ -44,10 +42,38 @@ struct uart_emul_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN bool rx_irq_en; bool tx_irq_en; - struct uart_emul_work irq_work; + struct k_work irq_work; + uart_irq_callback_user_data_t irq_cb; void *irq_cb_udata; #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#ifdef CONFIG_UART_ASYNC_API + bool rx_async_en; + bool rx_stopping; + bool rx_release_on_timeout; + + struct k_work tx_work; + struct k_work rx_work; + struct k_work rx_disable_work; + struct k_work_delayable rx_timeout_work; + + uart_callback_t uart_callback; + void *callback_user_data; + + const uint8_t *tx_buf; + size_t tx_buf_len; + size_t tx_buf_offset; + + uint8_t *rx_buf; + size_t rx_buf_len; + size_t rx_buf_offset; + size_t rx_buf_data_len; + int32_t rx_buf_timeout; + + uint8_t *rx_buf_next; + size_t rx_buf_next_len; +#endif /* CONFIG_UART_ASYNC_API */ }; /* @@ -213,9 +239,8 @@ static int uart_emul_irq_rx_ready(const struct device *dev) static void uart_emul_irq_handler(struct k_work *work) { - struct uart_emul_work *uwork = CONTAINER_OF(work, struct uart_emul_work, work); - const struct device *dev = uwork->dev; - struct uart_emul_data *data = dev->data; + struct uart_emul_data *data = CONTAINER_OF(work, struct uart_emul_data, irq_work); + const struct device *dev = data->dev; uart_irq_callback_user_data_t cb = data->irq_cb; void *udata = data->irq_cb_udata; @@ -267,7 +292,7 @@ static void uart_emul_irq_tx_enable(const struct device *dev) } if (submit_irq_work) { - (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work); } } @@ -282,7 +307,7 @@ static void uart_emul_irq_rx_enable(const struct device *dev) } if (submit_irq_work) { - (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &data->irq_work); } } @@ -331,6 +356,497 @@ static int uart_emul_irq_update(const struct device *dev) } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API +static void uart_emul_post_event(const struct device *dev, struct uart_event *evt) +{ + struct uart_emul_data *data = dev->data; + + if (!data->uart_callback) { + LOG_DBG("No async callback configured for uart_emul device %p", dev); + } + + data->uart_callback(dev, evt, data->callback_user_data); +} + +static void uart_emul_simple_event(const struct device *dev, enum uart_event_type type) +{ + uart_emul_post_event(dev, &(struct uart_event){.type = type}); +} + +static void uart_emul_async_switch_buf_nolock(struct uart_emul_data *data) +{ + data->rx_buf = data->rx_buf_next; + data->rx_buf_len = data->rx_buf_next_len; + data->rx_buf_offset = 0; + data->rx_buf_data_len = 0; + data->rx_buf_next = NULL; + data->rx_buf_next_len = 0; +} + +static void uart_emul_async_rx_timeout_handler(struct k_work *_work) +{ + struct k_work_delayable *work = k_work_delayable_from_work(_work); + struct uart_emul_data *data = CONTAINER_OF(work, struct uart_emul_data, rx_timeout_work); + const struct device *dev = data->dev; + + uint8_t *rx_buf; + size_t rx_buf_len; + size_t rx_buf_offset; + size_t rx_buf_data_len; + bool rx_en; + bool rx_buf_released = false; + bool rx_stopped = false; + + K_SPINLOCK(&data->rx_lock) { + rx_en = data->rx_async_en; + rx_buf = data->rx_buf; + rx_buf_len = data->rx_buf_len; + rx_buf_offset = data->rx_buf_offset; + rx_buf_data_len = data->rx_buf_data_len; + + data->rx_buf_offset += rx_buf_data_len; + data->rx_buf_data_len = 0; + + if (data->rx_buf_offset >= rx_buf_len || + (rx_buf_data_len > 0 && data->rx_release_on_timeout)) { + rx_buf_released = true; + uart_emul_async_switch_buf_nolock(data); + if (data->rx_buf == NULL) { + /* There was no second buffer scheduled, so stop receiving */ + rx_stopped = true; + data->rx_async_en = false; + } + } + } + + if (!rx_en || rx_buf == NULL || rx_buf_data_len == 0) { + return; + } + + struct uart_event rx_rdy_event = { + .type = UART_RX_RDY, + .data.rx = { + .buf = rx_buf, + .offset = rx_buf_offset, + .len = rx_buf_data_len, + }, + }; + + uart_emul_post_event(dev, &rx_rdy_event); + + if (rx_buf_released) { + struct uart_event rx_buf_released_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = rx_buf, + }; + + uart_emul_post_event(dev, &rx_buf_released_event); + } + if (rx_stopped) { + uart_emul_simple_event(dev, UART_RX_DISABLED); + } +} + +static void uart_emul_async_rx_handler(struct k_work *work) +{ + struct uart_emul_data *data = CONTAINER_OF(work, struct uart_emul_data, rx_work); + const struct device *dev = data->dev; + + bool rx_en = false; + bool empty = true; + + do { + bool rx_rdy = false; + bool buf_request = false; + + uint8_t *rx_buf = NULL; + size_t buf_len; + size_t offset; + size_t data_len; + + K_SPINLOCK(&data->rx_lock) { + rx_en = data->rx_async_en; + rx_buf = data->rx_buf; + buf_len = data->rx_buf_len; + offset = data->rx_buf_offset; + data_len = data->rx_buf_data_len; + empty = ring_buf_is_empty(data->rx_rb); + + if (!rx_en) { + K_SPINLOCK_BREAK; + } + + if (rx_buf == NULL) { + uart_emul_async_switch_buf_nolock(data); + rx_buf = data->rx_buf; + buf_len = data->rx_buf_len; + offset = data->rx_buf_offset; + data_len = data->rx_buf_data_len; + } + + if (rx_buf == NULL) { + /* During the last iteration the buffer was released but the + * application did not provide a new buffer. Stop RX and quit now. + */ + data->rx_async_en = false; + K_SPINLOCK_BREAK; + } + + if (empty) { + K_SPINLOCK_BREAK; + } + + buf_request = data_len == 0 && data->rx_buf_next == NULL; + + uint32_t read = ring_buf_get(data->rx_rb, &rx_buf[offset + data_len], + buf_len - (offset + data_len)); + data_len += read; + data->rx_buf_data_len = data_len; + + if (offset + data_len >= data->rx_buf_len) { + rx_rdy = true; + data->rx_buf = NULL; + data->rx_buf_len = 0; + data->rx_buf_offset = 0; + data->rx_buf_data_len = 0; + } + } + + if (!rx_en) { + break; + } + + if (rx_buf == NULL) { + uart_emul_simple_event(dev, UART_RX_DISABLED); + break; + } + + if (empty && data->rx_buf_timeout != SYS_FOREVER_US) { + (void)k_work_reschedule_for_queue(&uart_emul_work_q, &data->rx_timeout_work, + K_USEC(data->rx_buf_timeout)); + } + + if (buf_request) { + uart_emul_simple_event(dev, UART_RX_BUF_REQUEST); + } + + if (rx_rdy) { + struct uart_event rx_rdy_event = { + .type = UART_RX_RDY, + .data.rx = { + .buf = rx_buf, + .offset = offset, + .len = data_len, + }, + }; + + uart_emul_post_event(dev, &rx_rdy_event); + + struct uart_event rx_buf_released_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = rx_buf, + }; + + uart_emul_post_event(dev, &rx_buf_released_event); + } + } while (rx_en && !empty); +} + +static void uart_emul_async_tx_handler(struct k_work *work) +{ + struct uart_emul_data *data = CONTAINER_OF(work, struct uart_emul_data, tx_work); + const struct device *dev = data->dev; + const struct uart_emul_config *config = dev->config; + + uint32_t written; + + const uint8_t *tx_buf = NULL; + size_t tx_buf_len = 0; + size_t tx_buf_offset = 0; + bool tx_done = true; + + K_SPINLOCK(&data->tx_lock) { + tx_buf = data->tx_buf; + tx_buf_len = data->tx_buf_len; + tx_buf_offset = data->tx_buf_offset; + + if (!tx_buf) { + K_SPINLOCK_BREAK; + } + + written = ring_buf_put(data->tx_rb, &data->tx_buf[tx_buf_offset], + tx_buf_len - tx_buf_offset); + tx_done = written == (tx_buf_len - tx_buf_offset); + if (!tx_done) { + data->tx_buf_offset += written; + K_SPINLOCK_BREAK; + } + data->tx_buf = NULL; + data->tx_buf_len = 0; + data->tx_buf_offset = 0; + } + + if (!tx_buf) { + return; + } + + if (config->loopback && written) { + uint32_t loop_written = uart_emul_put_rx_data(dev, &tx_buf[tx_buf_offset], written); + + if (loop_written < written) { + LOG_WRN("Lost %" PRIu32 " bytes on loopback", written - loop_written); + } + } + if (data->tx_data_ready_cb) { + (data->tx_data_ready_cb)(dev, ring_buf_size_get(data->tx_rb), data->user_data); + } + + if ((config->loopback && written) || !written) { + /* When using the loopback fixture, just allow to drop all bytes in the ring buffer + * not consumed by tx_data_ready_cb(). + */ + + uint32_t flushed = uart_emul_flush_tx_data(dev); + + if (flushed) { + if (written) { + LOG_DBG("Flushed %" PRIu32 " unused bytes from tx buffer", flushed); + } else { + LOG_WRN("Flushed %" PRIu32 + " unused bytes from tx buffer to break out of infinite " + "loop! Consume or flush the bytes from the tx ring buffer " + "in your test case to prevent this!", + flushed); + } + } + } + + if (!tx_done) { + /* We are not done yet, yield back into workqueue. + * + * This would basically be an infinite loop when tx_data_ready_cb() does not consume + * the bytes in the tx ring buffer. + */ + k_work_submit_to_queue(&uart_emul_work_q, &data->tx_work); + return; + } + + struct uart_event tx_done_event = { + .type = UART_TX_DONE, + .data.tx = { + .buf = tx_buf, + .len = tx_buf_len, + }, + }; + + uart_emul_post_event(dev, &tx_done_event); +} + +static void uart_emul_rx_stop(const struct device *dev, struct uart_emul_data *data) +{ + uint8_t *rx_buf = NULL; + size_t rx_buf_offset = 0; + size_t rx_buf_data_len = 0; + + k_work_cancel_delayable(&data->rx_timeout_work); + + K_SPINLOCK(&data->rx_lock) { + if (!data->rx_async_en) { + K_SPINLOCK_BREAK; + } + rx_buf = data->rx_buf; + rx_buf_offset = data->rx_buf_offset; + rx_buf_data_len = data->rx_buf_data_len; + + data->rx_buf = NULL; + data->rx_buf_len = 0; + data->rx_buf_offset = 0; + data->rx_buf_data_len = 0; + data->rx_buf_next = NULL; + data->rx_buf_next_len = 0; + data->rx_async_en = false; + data->rx_stopping = false; + } + + if (rx_buf == NULL) { + return; + } + + if (rx_buf_data_len > 0) { + struct uart_event rx_rdy_event = { + .type = UART_RX_RDY, + .data.rx = { + .buf = rx_buf, + .offset = rx_buf_offset, + .len = rx_buf_data_len, + }, + }; + + uart_emul_post_event(dev, &rx_rdy_event); + } + + struct uart_event rx_buf_released_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = rx_buf, + }; + + uart_emul_post_event(dev, &rx_buf_released_event); + uart_emul_simple_event(dev, UART_RX_DISABLED); +} + +static void uart_emul_async_rx_disable_handler(struct k_work *work) +{ + struct uart_emul_data *data = CONTAINER_OF(work, struct uart_emul_data, rx_disable_work); + const struct device *dev = data->dev; + + uart_emul_rx_stop(dev, data); +} + +static int uart_emul_callback_set(const struct device *dev, uart_callback_t callback, + void *user_data) +{ + struct uart_emul_data *data = dev->data; + + data->uart_callback = callback; + data->callback_user_data = user_data; + + return 0; +} + +static int uart_emul_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) +{ + struct uart_emul_data *data = dev->data; + int ret = 0; + + K_SPINLOCK(&data->tx_lock) { + if (data->tx_buf) { + ret = -EBUSY; + K_SPINLOCK_BREAK; + } + + data->tx_buf = buf; + data->tx_buf_len = len; + data->tx_buf_offset = 0; + + k_work_submit_to_queue(&uart_emul_work_q, &data->tx_work); + } + + return ret; +} + +static int uart_emul_tx_abort(const struct device *dev) +{ + struct uart_emul_data *data = dev->data; + const uint8_t *tx_buf = NULL; + size_t tx_buf_sent; + + K_SPINLOCK(&data->tx_lock) { + tx_buf = data->tx_buf; + tx_buf_sent = data->tx_buf_offset; + + data->tx_buf = NULL; + data->tx_buf_len = 0; + data->tx_buf_offset = 0; + + k_work_cancel(&data->tx_work); + } + + if (!tx_buf) { + return -EFAULT; + } + + struct uart_event tx_aborted_event = { + .type = UART_TX_ABORTED, + .data.tx = { + .buf = tx_buf, + .len = tx_buf_sent, + }, + }; + + uart_emul_post_event(dev, &tx_aborted_event); + + return 0; +} + +static int uart_emul_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + struct uart_emul_data *data = dev->data; + int ret = 0; + + K_SPINLOCK(&data->rx_lock) { + if (!data->rx_async_en) { + ret = -EACCES; + K_SPINLOCK_BREAK; + } + + if (data->rx_buf_next != NULL) { + ret = -EBUSY; + K_SPINLOCK_BREAK; + } + + data->rx_buf_next = buf; + data->rx_buf_next_len = len; + } + + return ret; +} + +static int uart_emul_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) +{ + struct uart_emul_data *data = dev->data; + int ret = 0; + bool rx_stopping; + + K_SPINLOCK(&data->rx_lock) { + rx_stopping = data->rx_stopping; + k_work_cancel(&data->rx_disable_work); + } + + if (rx_stopping) { + uart_emul_rx_stop(dev, data); + } + + K_SPINLOCK(&data->rx_lock) { + if (data->rx_async_en) { + ret = -EBUSY; + K_SPINLOCK_BREAK; + } + + data->rx_async_en = true; + data->rx_buf = buf; + data->rx_buf_len = len; + data->rx_buf_timeout = timeout; + data->rx_buf_offset = 0; + data->rx_buf_data_len = 0; + data->rx_buf_next = NULL; + data->rx_buf_next_len = 0; + + if (!ring_buf_is_empty(data->rx_rb)) { + (void)k_work_submit_to_queue(&uart_emul_work_q, &data->rx_work); + } + } + + return ret; +} + +static int uart_emul_rx_disable(const struct device *dev) +{ + struct uart_emul_data *data = dev->data; + int ret = 0; + + K_SPINLOCK(&data->rx_lock) { + if (!data->rx_async_en) { + ret = -EFAULT; + K_SPINLOCK_BREAK; + } + data->rx_stopping = true; + k_work_submit_to_queue(&uart_emul_work_q, &data->rx_disable_work); + } + + return ret; +} +#endif /* CONFIG_UART_ASYNC_API */ + static const struct uart_driver_api uart_emul_api = { .poll_in = uart_emul_poll_in, .poll_out = uart_emul_poll_out, @@ -353,6 +869,14 @@ static const struct uart_driver_api uart_emul_api = { .irq_update = uart_emul_irq_update, .irq_is_pending = uart_emul_irq_is_pending, #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API + .callback_set = uart_emul_callback_set, + .tx = uart_emul_tx, + .tx_abort = uart_emul_tx_abort, + .rx_enable = uart_emul_rx_enable, + .rx_buf_rsp = uart_emul_rx_buf_rsp, + .rx_disable = uart_emul_rx_disable, +#endif /* CONFIG_UART_ASYNC_API */ }; void uart_emul_callback_tx_data_ready_set(const struct device *dev, @@ -364,17 +888,19 @@ void uart_emul_callback_tx_data_ready_set(const struct device *dev, drv_data->user_data = user_data; } -uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t size) +uint32_t uart_emul_put_rx_data(const struct device *dev, const uint8_t *data, size_t size) { struct uart_emul_data *drv_data = dev->data; uint32_t count; __unused bool empty; __unused bool irq_en; + __unused bool rx_en; K_SPINLOCK(&drv_data->rx_lock) { count = ring_buf_put(drv_data->rx_rb, data, size); empty = ring_buf_is_empty(drv_data->rx_rb); IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (irq_en = drv_data->rx_irq_en;)); + IF_ENABLED(CONFIG_UART_ASYNC_API, (rx_en = drv_data->rx_async_en;)); } if (count < size) { @@ -383,7 +909,12 @@ uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t s IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( if (count > 0 && irq_en && !empty) { - (void)k_work_submit_to_queue(&uart_emul_work_q, &drv_data->irq_work.work); + (void)k_work_submit_to_queue(&uart_emul_work_q, &drv_data->irq_work); + } + )) + IF_ENABLED(CONFIG_UART_ASYNC_API, ( + if (count > 0 && rx_en && !empty) { + (void)k_work_submit_to_queue(&uart_emul_work_q, &drv_data->rx_work); } )) @@ -435,14 +966,16 @@ void uart_emul_set_errors(const struct device *dev, int errors) drv_data->errors |= errors; } +void uart_emul_set_release_buffer_on_timeout(const struct device *dev, bool release_on_timeout) +{ + __unused struct uart_emul_data *drv_data = dev->data; + + IF_ENABLED(CONFIG_UART_ASYNC_API, (drv_data->rx_release_on_timeout = release_on_timeout;)); +} + #define UART_EMUL_RX_FIFO_SIZE(inst) (DT_INST_PROP(inst, rx_fifo_size)) #define UART_EMUL_TX_FIFO_SIZE(inst) (DT_INST_PROP(inst, tx_fifo_size)) -#define UART_EMUL_IRQ_WORK_INIT(inst) \ - IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ - (.irq_work = {.dev = DEVICE_DT_INST_GET(inst), \ - .work = Z_WORK_INITIALIZER(uart_emul_irq_handler)},)) - #define DEFINE_UART_EMUL(inst) \ \ RING_BUF_DECLARE(uart_emul_##inst##_rx_rb, UART_EMUL_RX_FIFO_SIZE(inst)); \ @@ -453,9 +986,18 @@ void uart_emul_set_errors(const struct device *dev, int errors) .latch_buffer_size = DT_INST_PROP(inst, latch_buffer_size), \ }; \ static struct uart_emul_data uart_emul_data_##inst = { \ + .dev = DEVICE_DT_INST_GET(inst), \ .rx_rb = &uart_emul_##inst##_rx_rb, \ .tx_rb = &uart_emul_##inst##_tx_rb, \ - UART_EMUL_IRQ_WORK_INIT(inst) \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (.irq_work = Z_WORK_INITIALIZER(uart_emul_irq_handler),)) \ + IF_ENABLED(CONFIG_UART_ASYNC_API, \ + (.tx_work = Z_WORK_INITIALIZER(uart_emul_async_tx_handler), \ + .rx_timeout_work = Z_WORK_DELAYABLE_INITIALIZER( \ + uart_emul_async_rx_timeout_handler), \ + .rx_work = Z_WORK_INITIALIZER(uart_emul_async_rx_handler), \ + .rx_disable_work = Z_WORK_INITIALIZER( \ + uart_emul_async_rx_disable_handler),)) \ }; \ \ DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &uart_emul_data_##inst, &uart_emul_cfg_##inst, \ diff --git a/drivers/serial/uart_ifx_cat1.c b/drivers/serial/uart_ifx_cat1.c index 68222ec314cd62..c54bafa57251b5 100644 --- a/drivers/serial/uart_ifx_cat1.c +++ b/drivers/serial/uart_ifx_cat1.c @@ -227,6 +227,10 @@ static int ifx_cat1_uart_configure(const struct device *dev, result = cyhal_uart_set_baud(&data->obj, cfg->baudrate, NULL); } + /* Set RTS/CTS flow control pins as NC so cyhal will skip initialization */ + data->obj.pin_cts = NC; + data->obj.pin_rts = NC; + /* Enable RTS/CTS flow control */ if ((result == CY_RSLT_SUCCESS) && cfg->flow_ctrl) { result = cyhal_uart_enable_flow_control(&data->obj, true, true); diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index cc2c9b90594d85..990f4f3fb2ac67 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -25,12 +25,12 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); #include /* Generalize PPI or DPPI channel management */ -#if defined(CONFIG_HAS_HW_NRF_PPI) +#if defined(PPI_PRESENT) #include #define gppi_channel_t nrf_ppi_channel_t #define gppi_channel_alloc nrfx_ppi_channel_alloc #define gppi_channel_enable nrfx_ppi_channel_enable -#elif defined(CONFIG_HAS_HW_NRF_DPPIC) +#elif defined(DPPI_PRESENT) #include #define gppi_channel_t uint8_t #define gppi_channel_alloc nrfx_dppi_channel_alloc @@ -39,39 +39,49 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); #error "No PPI or DPPI" #endif +/* Execute macro f(x) for all instances. */ +#define UARTE_FOR_EACH_INSTANCE(f, sep, off_code) \ + NRFX_FOREACH_PRESENT(UARTE, f, sep, off_code, _) -#if (defined(CONFIG_HAS_HW_NRF_UARTE0) && \ - defined(CONFIG_UART_0_INTERRUPT_DRIVEN)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE1) && \ - defined(CONFIG_UART_1_INTERRUPT_DRIVEN)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE2) && \ - defined(CONFIG_UART_2_INTERRUPT_DRIVEN)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE3) && \ - defined(CONFIG_UART_3_INTERRUPT_DRIVEN)) +/* Determine if any instance is using interrupt driven API. */ +#define IS_INT_DRIVEN(unused, prefix, i, _) \ + (IS_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##i) && \ + IS_ENABLED(CONFIG_UART_##prefix##i##_INTERRUPT_DRIVEN)) + +#if UARTE_FOR_EACH_INSTANCE(IS_INT_DRIVEN, (||), (0)) #define UARTE_INTERRUPT_DRIVEN 1 #endif -#if (defined(CONFIG_HAS_HW_NRF_UARTE0) && !defined(CONFIG_UART_0_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE1) && !defined(CONFIG_UART_1_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE2) && !defined(CONFIG_UART_2_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE3) && !defined(CONFIG_UART_3_ASYNC)) +/* Determine if any instance is not using asynchronous API. */ +#define IS_NOT_ASYNC(unused, prefix, i, _) \ + (IS_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##i) && \ + !IS_ENABLED(CONFIG_UART_##prefix##i##_ASYNC)) + +#if UARTE_FOR_EACH_INSTANCE(IS_NOT_ASYNC, (||), (0)) #define UARTE_ANY_NONE_ASYNC 1 #endif -#if (defined(CONFIG_HAS_HW_NRF_UARTE0) && defined(CONFIG_UART_0_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE1) && defined(CONFIG_UART_1_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE2) && defined(CONFIG_UART_2_ASYNC)) || \ - (defined(CONFIG_HAS_HW_NRF_UARTE3) && defined(CONFIG_UART_3_ASYNC)) +/* Determine if any instance is using asynchronous API. */ +#define IS_ASYNC(unused, prefix, i, _) \ + (IS_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##i) && \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ASYNC)) + +#if UARTE_FOR_EACH_INSTANCE(IS_ASYNC, (||), (0)) #define UARTE_ANY_ASYNC 1 #endif -#if defined(CONFIG_UART_0_NRF_HW_ASYNC) || defined(CONFIG_UART_1_NRF_HW_ASYNC) || \ - defined(CONFIG_UART_2_NRF_HW_ASYNC) || defined(CONFIG_UART_3_NRF_HW_ASYNC) +/* Determine if any instance is using asynchronous API with HW byte counting. */ +#define IS_HW_ASYNC(unused, prefix, i, _) IS_ENABLED(CONFIG_UART_##prefix##i##_NRF_HW_ASYNC) + +#if UARTE_FOR_EACH_INSTANCE(IS_HW_ASYNC, (||), (0)) #define UARTE_HW_ASYNC 1 #endif -#if defined(CONFIG_UART_0_ENHANCED_POLL_OUT) || defined(CONFIG_UART_1_ENHANCED_POLL_OUT) || \ - defined(CONFIG_UART_2_ENHANCED_POLL_OUT) || defined(CONFIG_UART_3_ENHANCED_POLL_OUT) +/* Determine if any instance is using enhanced poll_out feature. */ +#define IS_ENHANCED_POLL_OUT(unused, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ENHANCED_POLL_OUT) + +#if UARTE_FOR_EACH_INSTANCE(IS_ENHANCED_POLL_OUT, (||), (0)) #define UARTE_ENHANCED_POLL_OUT 1 #endif @@ -506,6 +516,20 @@ static int wait_tx_ready(const struct device *dev) return key; } +#if defined(UARTE_ANY_ASYNC) || defined(CONFIG_PM_DEVICE) +static int pins_state_change(const struct device *dev, bool on) +{ + const struct uarte_nrfx_config *config = dev->config; + + if (config->flags & UARTE_CFG_FLAG_GPIO_MGMT) { + return pinctrl_apply_state(config->pcfg, + on ? PINCTRL_STATE_DEFAULT : PINCTRL_STATE_SLEEP); + } + + return 0; +} +#endif + #ifdef UARTE_ANY_ASYNC /* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case @@ -516,7 +540,7 @@ static int wait_tx_ready(const struct device *dev) #endif /* UARTE_ANY_ASYNC */ -static void uarte_enable(const struct device *dev, uint32_t mask) +static int uarte_enable(const struct device *dev, uint32_t mask) { #ifdef UARTE_ANY_ASYNC const struct uarte_nrfx_config *config = dev->config; @@ -524,8 +548,14 @@ static void uarte_enable(const struct device *dev, uint32_t mask) if (data->async) { bool disabled = data->async->low_power_mask == 0; + int ret; data->async->low_power_mask |= mask; + ret = pins_state_change(dev, true); + if (ret < 0) { + return ret; + } + if (HW_RX_COUNTING_ENABLED(data) && disabled) { const nrfx_timer_t *timer = &config->timer; @@ -538,6 +568,8 @@ static void uarte_enable(const struct device *dev, uint32_t mask) } #endif nrf_uarte_enable(get_uarte_instance(dev)); + + return 0; } /* At this point we should have irq locked and any previous transfer completed. @@ -561,7 +593,7 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len) nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_TXSTOPPED); if (config->flags & UARTE_CFG_FLAG_LOW_POWER) { - uarte_enable(dev, UARTE_LOW_POWER_TX); + (void)uarte_enable(dev, UARTE_LOW_POWER_TX); nrf_uarte_int_enable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK); } @@ -843,6 +875,7 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, struct uarte_nrfx_data *data = dev->data; const struct uarte_nrfx_config *cfg = dev->config; NRF_UARTE_Type *uarte = get_uarte_instance(dev); + int ret = 0; if (cfg->disable_rx) { __ASSERT(false, "TX only UARTE instance"); @@ -896,7 +929,7 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, if (cfg->flags & UARTE_CFG_FLAG_LOW_POWER) { unsigned int key = irq_lock(); - uarte_enable(dev, UARTE_LOW_POWER_RX); + ret = uarte_enable(dev, UARTE_LOW_POWER_RX); irq_unlock(key); } @@ -1269,6 +1302,10 @@ static void async_uart_release(const struct device *dev, uint32_t dir_mask) } uart_disable(dev); + int err = pins_state_change(dev, false); + + (void)err; + __ASSERT_NO_MSG(err == 0); } irq_unlock(key); @@ -1865,14 +1902,21 @@ static int uarte_nrfx_pm_action(const struct device *dev, const struct uarte_nrfx_config *cfg = dev->config; int ret; +#ifdef UARTE_ANY_ASYNC + /* If low power mode for asynchronous mode is used then there is nothing to do here. + * In low power mode UARTE is turned off whenever there is no activity. + */ + if (data->async && (cfg->flags & UARTE_CFG_FLAG_LOW_POWER)) { + return 0; + } +#endif + 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; - } + + ret = pins_state_change(dev, true); + if (ret < 0) { + return ret; } nrf_uarte_enable(uarte); @@ -1941,12 +1985,9 @@ static int uarte_nrfx_pm_action(const struct device *dev, wait_for_tx_stopped(dev); uart_disable(dev); - if (cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT) { - ret = pinctrl_apply_state(cfg->pcfg, - PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; - } + ret = pins_state_change(dev, false); + if (ret < 0) { + return ret; } break; @@ -2074,18 +2115,7 @@ static int uarte_nrfx_pm_action(const struct device *dev, DT_PHANDLE(UARTE(idx), memory_regions)))))), \ ()) -#ifdef CONFIG_HAS_HW_NRF_UARTE0 -UART_NRF_UARTE_DEVICE(0); -#endif - -#ifdef CONFIG_HAS_HW_NRF_UARTE1 -UART_NRF_UARTE_DEVICE(1); -#endif - -#ifdef CONFIG_HAS_HW_NRF_UARTE2 -UART_NRF_UARTE_DEVICE(2); -#endif +#define COND_UART_NRF_UARTE_DEVICE(unused, prefix, i, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##i, (UART_NRF_UARTE_DEVICE(prefix##i);)) -#ifdef CONFIG_HAS_HW_NRF_UARTE3 -UART_NRF_UARTE_DEVICE(3); -#endif +UARTE_FOR_EACH_INSTANCE(COND_UART_NRF_UARTE_DEVICE, (), ()) diff --git a/drivers/serial/uart_psoc6.c b/drivers/serial/uart_psoc6.c index 6bf09b22b7174b..32c1d9e125f6bc 100644 --- a/drivers/serial/uart_psoc6.c +++ b/drivers/serial/uart_psoc6.c @@ -12,12 +12,9 @@ * - Error handling is not implemented. * - The driver works only in polling mode, interrupt mode is not implemented. */ -#include -#include -#include -#include -#include #include +#include +#include #include "cy_syslib.h" #include "cy_sysclk.h" @@ -50,8 +47,7 @@ struct cypress_psoc6_config { #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_config_func_t irq_config_func; #endif - uint32_t num_pins; - struct soc_gpio_pin pins[]; + const struct pinctrl_dev_config *pcfg; }; #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -104,9 +100,14 @@ static const cy_stc_scb_uart_config_t uartConfig = { */ static int uart_psoc6_init(const struct device *dev) { + int ret; const struct cypress_psoc6_config *config = dev->config; - soc_gpio_list_configure(config->pins, config->num_pins); + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } /* Connect assigned divider to be a clock source for UART */ Cy_SysClk_PeriphAssignDivider(config->periph_id, @@ -344,14 +345,13 @@ static const struct uart_driver_api uart_psoc6_driver_api = { #endif #define CY_PSOC6_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ CY_PSOC6_UART_DECL_DATA(n) \ CY_PSOC6_UART_IRQ_FUNC(n) \ static const struct cypress_psoc6_config cy_psoc6_uart##n##_config = { \ .base = (CySCB_Type *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ - \ - .num_pins = CY_PSOC6_DT_INST_NUM_PINS(n), \ - .pins = CY_PSOC6_DT_INST_PINS(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ \ CY_PSOC6_UART_IRQ_SET_FUNC(n) \ }; \ diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index f7c8cc6fc791cf..07fb6a2455be67 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -56,3 +56,4 @@ zephyr_library_sources_ifdef(CONFIG_SPI_INFINEON_CAT1 spi_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_SPI_SEDI spi_sedi.c) zephyr_library_sources_ifdef(CONFIG_SPI_NPCX_SPIP spi_npcx_spip.c) zephyr_library_sources_ifdef(CONFIG_SPI_GRLIB_SPIMCTRL spi_grlib_spimctrl.c) +zephyr_library_sources_ifdef(CONFIG_SPI_MAX32 spi_max32.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9dc7908552f7e7..b77b5a1e9ba272 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -156,4 +156,6 @@ source "drivers/spi/Kconfig.mchp_mss" source "drivers/spi/Kconfig.grlib_spimctrl" +source "drivers/spi/Kconfig.max32" + endif # SPI diff --git a/drivers/spi/Kconfig.ambiq b/drivers/spi/Kconfig.ambiq index 04113482f1be60..1a2499459881bc 100644 --- a/drivers/spi/Kconfig.ambiq +++ b/drivers/spi/Kconfig.ambiq @@ -15,6 +15,19 @@ config SPI_AMBIQ help Enable driver for Ambiq SPI. +config SPI_AMBIQ_DMA + bool "AMBIQ APOLLO SPI DMA Support" + depends on SPI_AMBIQ + help + Enable DMA for Ambiq SPI. + +config SPI_DMA_TCB_BUFFER_SIZE + int "DMA Transfer Control Buffer size in words." + default 1024 + depends on SPI_AMBIQ_DMA + help + DMA Transfer Control Buffer size in words + config MSPI_AMBIQ bool "AMBIQ MSPI driver" default y diff --git a/drivers/spi/Kconfig.max32 b/drivers/spi/Kconfig.max32 new file mode 100644 index 00000000000000..ca75a3725915d4 --- /dev/null +++ b/drivers/spi/Kconfig.max32 @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SPI_MAX32 + bool "MAX32 MCU SPI controller driver" + default y + depends on DT_HAS_ADI_MAX32_SPI_ENABLED + help + Enable SPI support on the MAX32 family of processors. + +if SPI_MAX32 + +config SPI_MAX32_INTERRUPT + bool "MAX32 MCU SPI Interrupt Support" + help + Enable interrupt support for MAX32 MCU SPI driver. + +endif # SPI_MAX32 diff --git a/drivers/spi/Kconfig.psoc6 b/drivers/spi/Kconfig.psoc6 index 21b4bfe596bcdd..5b7fe353d81901 100644 --- a/drivers/spi/Kconfig.psoc6 +++ b/drivers/spi/Kconfig.psoc6 @@ -8,5 +8,6 @@ config SPI_PSOC6 default y depends on DT_HAS_CYPRESS_PSOC6_SPI_ENABLED select USE_INFINEON_SPI + select PINCTRL help This option enables the SCB[SPI] driver for PSoC-6 SoC family. diff --git a/drivers/spi/spi_ambiq.c b/drivers/spi/spi_ambiq.c index 61d71e3f567160..3690816e205aa4 100644 --- a/drivers/spi/spi_ambiq.c +++ b/drivers/spi/spi_ambiq.c @@ -28,20 +28,62 @@ struct spi_ambiq_config { uint32_t clock_freq; const struct pinctrl_dev_config *pcfg; ambiq_spi_pwr_func_t pwr_func; + void (*irq_config_func)(void); }; struct spi_ambiq_data { struct spi_context ctx; am_hal_iom_config_t iom_cfg; - void *IOMHandle; + void *iom_handler; + int inst_idx; }; -#define SPI_BASE (((const struct spi_ambiq_config *)(dev)->config)->base) -#define REG_STAT 0x248 -#define IDLE_STAT 0x4 -#define SPI_STAT(dev) (SPI_BASE + REG_STAT) +typedef void (*spi_context_update_trx)(struct spi_context *ctx, uint8_t dfs, uint32_t len); + #define SPI_WORD_SIZE 8 +#define SPI_CS_INDEX 3 + +#ifdef CONFIG_SPI_AMBIQ_DMA +static __aligned(32) struct { + __aligned(32) uint32_t buf[CONFIG_SPI_DMA_TCB_BUFFER_SIZE]; +} spi_dma_tcb_buf[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)] __attribute__((__section__(".nocache"))); + +static void spi_ambiq_callback(void *callback_ctxt, uint32_t status) +{ + const struct device *dev = callback_ctxt; + struct spi_ambiq_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + spi_context_complete(ctx, dev, (status == AM_HAL_STATUS_SUCCESS) ? 0 : -EIO); +} + +static void spi_ambiq_reset(const struct device *dev) +{ + struct spi_ambiq_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + /* cancel timed out transaction */ + am_hal_iom_disable(data->iom_handler); + /* NULL config to trigger reconfigure on next xfer */ + ctx->config = NULL; + /* signal any thread waiting on sync semaphore */ + spi_context_complete(ctx, dev, -ETIMEDOUT); + /* clean up for next xfer */ + k_sem_reset(&ctx->sync); +} +#endif + +static void spi_ambiq_isr(const struct device *dev) +{ + uint32_t ui32Status; + struct spi_ambiq_data *data = dev->data; + + am_hal_iom_interrupt_status_get(data->iom_handler, false, &ui32Status); + am_hal_iom_interrupt_clear(data->iom_handler, ui32Status); + am_hal_iom_interrupt_service(data->iom_handler, ui32Status); +} + static int spi_config(const struct device *dev, const struct spi_config *config) { struct spi_ambiq_data *data = dev->data; @@ -57,12 +99,7 @@ static int spi_config(const struct device *dev, const struct spi_config *config) return 0; } - if (config->operation & SPI_HALF_DUPLEX) { - LOG_ERR("Half-duplex not supported"); - return -ENOTSUP; - } - - if (SPI_WORD_SIZE_GET(config->operation) != 8) { + if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) { LOG_ERR("Word size must be %d", SPI_WORD_SIZE); return -ENOTSUP; } @@ -110,75 +147,224 @@ static int spi_config(const struct device *dev, const struct spi_config *config) return -ENOTSUP; } - data->iom_cfg.ui32ClockFreq = cfg->clock_freq; + /* Select slower of two: SPI bus frequency for SPI device or SPI master clock frequency */ + data->iom_cfg.ui32ClockFreq = + (config->frequency ? MIN(config->frequency, cfg->clock_freq) : cfg->clock_freq); ctx->config = config; +#ifdef CONFIG_SPI_AMBIQ_DMA + data->iom_cfg.pNBTxnBuf = spi_dma_tcb_buf[data->inst_idx].buf; + data->iom_cfg.ui32NBTxnBufLength = CONFIG_SPI_DMA_TCB_BUFFER_SIZE; +#endif + /* Disable IOM instance as it cannot be configured when enabled*/ - ret = am_hal_iom_disable(data->IOMHandle); + ret = am_hal_iom_disable(data->iom_handler); - ret = am_hal_iom_configure(data->IOMHandle, &data->iom_cfg); + ret = am_hal_iom_configure(data->iom_handler, &data->iom_cfg); - ret = am_hal_iom_enable(data->IOMHandle); + ret = am_hal_iom_enable(data->iom_handler); return ret; } -static int spi_ambiq_xfer(const struct device *dev, const struct spi_config *config) +static int spi_ambiq_xfer_half_duplex(const struct device *dev, am_hal_iom_dir_e dir, + am_hal_iom_transfer_t trans, bool cont) { struct spi_ambiq_data *data = dev->data; struct spi_context *ctx = &data->ctx; + bool is_last = false; + uint32_t rem_num, cur_num = 0; + size_t count = 0; int ret = 0; + spi_context_update_trx ctx_update; - am_hal_iom_transfer_t trans = {0}; - - if (ctx->tx_len) { - trans.ui64Instr = *ctx->tx_buf; - trans.ui32InstrLen = 1; - spi_context_update_tx(ctx, 1, 1); - - if (ctx->rx_buf != NULL) { - if (ctx->tx_len > 0) { - /* The instruction length can only be 0~5. */ - if (ctx->tx_len > 4) { - spi_context_complete(ctx, dev, 0); - return -ENOTSUP; + if (dir == AM_HAL_IOM_FULLDUPLEX) { + return -EINVAL; + } else if (dir == AM_HAL_IOM_RX) { + trans.eDirection = AM_HAL_IOM_RX; + count = ctx->rx_count; + ctx_update = spi_context_update_rx; + } else if (dir == AM_HAL_IOM_TX) { + trans.eDirection = AM_HAL_IOM_TX; + count = ctx->tx_count; + ctx_update = spi_context_update_tx; + } + /* Only instruction */ + if ((!count) && (trans.ui32InstrLen)) { + trans.bContinue = cont; +#ifdef CONFIG_SPI_AMBIQ_DMA + if (AM_HAL_STATUS_SUCCESS != + am_hal_iom_nonblocking_transfer(data->iom_handler, &trans, spi_ambiq_callback, + (void *)dev)) { + spi_ambiq_reset(dev); + return -EIO; + } + ret = spi_context_wait_for_completion(ctx); +#else + ret = am_hal_iom_blocking_transfer(data->iom_handler, &trans); +#endif + } else { + for (size_t i = 0; i < count; i++) { + if (dir == AM_HAL_IOM_RX) { + rem_num = ctx->rx_len; + } else { + rem_num = ctx->tx_len; + } + while (rem_num) { + cur_num = (rem_num > AM_HAL_IOM_MAX_TXNSIZE_SPI) + ? AM_HAL_IOM_MAX_TXNSIZE_SPI + : rem_num; + if ((i == (count - 1)) && (cur_num == rem_num)) { + is_last = true; } - - /* Put the remaining TX data in instruction. */ - trans.ui32InstrLen += ctx->tx_len; - for (int i = 0; i < trans.ui32InstrLen - 1; i++) { - trans.ui64Instr = (trans.ui64Instr << 8) | (*ctx->tx_buf); - spi_context_update_tx(ctx, 1, 1); + trans.bContinue = (is_last == true) ? cont : true; + trans.ui32NumBytes = cur_num; + trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; + trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; +#ifdef CONFIG_SPI_AMBIQ_DMA + if (AM_HAL_STATUS_SUCCESS != + am_hal_iom_nonblocking_transfer( + data->iom_handler, &trans, + ((is_last == true) ? spi_ambiq_callback : NULL), + (void *)dev)) { + spi_ambiq_reset(dev); + return -EIO; + } + if (is_last) { + ret = spi_context_wait_for_completion(ctx); } +#else + ret = am_hal_iom_blocking_transfer(data->iom_handler, &trans); +#endif + rem_num -= cur_num; + ctx_update(ctx, 1, cur_num); } + } + } - /* Set RX direction and hold CS to continue to receive data. */ - trans.eDirection = AM_HAL_IOM_RX; - trans.bContinue = true; - trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; - trans.ui32NumBytes = ctx->rx_len; - ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); - } else if (ctx->tx_buf != NULL) { - /* Set TX direction to send data and release CS after transmission. */ + return ret; +} + +static int spi_ambiq_xfer_full_duplex(const struct device *dev, am_hal_iom_dir_e dir, + am_hal_iom_transfer_t trans, bool cont) +{ + struct spi_ambiq_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + bool trx_once = (ctx->tx_len == ctx->rx_len); + int ret = 0; + + if (dir != AM_HAL_IOM_FULLDUPLEX) { + return -EINVAL; + } + /* Tx and Rx length must be the same for am_hal_iom_spi_blocking_fullduplex */ + trans.eDirection = dir; + trans.ui32NumBytes = MIN(ctx->rx_len, ctx->tx_len); + trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; + trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; + trans.bContinue = (trx_once) ? cont : true; + spi_context_update_tx(ctx, 1, trans.ui32NumBytes); + spi_context_update_rx(ctx, 1, trans.ui32NumBytes); + + ret = am_hal_iom_spi_blocking_fullduplex(data->iom_handler, &trans); + + /* Transfer the remaining bytes */ + if (!trx_once) { + if (ctx->tx_len) { trans.eDirection = AM_HAL_IOM_TX; - trans.bContinue = false; trans.ui32NumBytes = ctx->tx_len; trans.pui32TxBuffer = (uint32_t *)ctx->tx_buf; - ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); + } else if (ctx->rx_len) { + trans.eDirection = AM_HAL_IOM_RX; + trans.ui32NumBytes = ctx->rx_len; + trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; } + trans.bContinue = cont; + ret = am_hal_iom_blocking_transfer(data->iom_handler, &trans); + } + + return ret; +} + +static int spi_ambiq_fill_instruction(const struct device *dev, am_hal_iom_transfer_t *trans, + uint32_t len) +{ + struct spi_ambiq_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + int ret = 0; + + /* + * The instruction length can only be: + * 0~AM_HAL_IOM_MAX_OFFSETSIZE. + * split transaction if oversize + */ + if (trans->ui32InstrLen + len > AM_HAL_IOM_MAX_OFFSETSIZE) { + ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_TX, *trans, true); } else { - /* Set RX direction to receive data and release CS after transmission. */ - trans.ui64Instr = 0; - trans.ui32InstrLen = 0; - trans.eDirection = AM_HAL_IOM_RX; - trans.bContinue = false; - trans.pui32RxBuffer = (uint32_t *)ctx->rx_buf; - trans.ui32NumBytes = ctx->rx_len; - ret = am_hal_iom_blocking_transfer(data->IOMHandle, &trans); + trans->ui32InstrLen += len; + for (int i = 0; i < len; i++) { +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + trans->ui32Instr = (trans->ui32Instr << 8) | (*ctx->tx_buf); +#else + trans->ui64Instr = (trans->ui64Instr << 8) | (*ctx->tx_buf); +#endif + spi_context_update_tx(ctx, 1, 1); + } } + return ret; +} + +static int spi_ambiq_xfer(const struct device *dev, const struct spi_config *config) +{ + struct spi_ambiq_data *data = dev->data; + const struct spi_ambiq_config *cfg = dev->config; + struct spi_context *ctx = &data->ctx; + int ret = 0; + bool cont = (config->operation & SPI_HOLD_ON_CS) ? true : false; - spi_context_complete(ctx, dev, 0); + am_hal_iom_transfer_t trans = {0}; + /* TODO Need to get iom_nce from different nodes of spi */ +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + trans.uPeerInfo.ui32SpiChipSelect = cfg->pcfg->states->pins[SPI_CS_INDEX].iom_nce; +#else + trans.uPeerInfo.ui32SpiChipSelect = cfg->pcfg->states->pins[SPI_CS_INDEX].iom_nce % 4; +#endif + + /* There's data to send */ + if (spi_context_tx_on(ctx)) { + /* Always put the first byte to instuction */ + ret = spi_ambiq_fill_instruction(dev, &trans, 1); + /* There's data to Receive */ + if (spi_context_rx_on(ctx)) { + /* Regard the first tx_buf as cmd if there are more than one buffer */ + if (ctx->rx_count > 1) { + ret = spi_ambiq_fill_instruction(dev, &trans, ctx->tx_len); + /* Skip the cmd buffer for rx. */ + spi_context_update_rx(ctx, 1, ctx->rx_len); + } + if ((!(config->operation & SPI_HALF_DUPLEX)) && (spi_context_tx_on(ctx))) { + ret = spi_ambiq_xfer_full_duplex(dev, AM_HAL_IOM_FULLDUPLEX, trans, + cont); + } else { + ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans, + cont); + } + } else { /* There's no data to Receive */ + /* Regard the first tx_buf as cmd if there are more than one buffer */ + if (ctx->tx_count > 1) { + ret = spi_ambiq_fill_instruction(dev, &trans, ctx->tx_len); + } + ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_TX, trans, cont); + } + } else { /* There's no data to send */ + ret = spi_ambiq_xfer_half_duplex(dev, AM_HAL_IOM_RX, trans, cont); + } + +#ifndef CONFIG_SPI_AMBIQ_DMA + if (!cont) { + spi_context_complete(ctx, dev, ret); + } +#endif return ret; } @@ -189,28 +375,39 @@ static int spi_ambiq_transceive(const struct device *dev, const struct spi_confi struct spi_ambiq_data *data = dev->data; int ret; + if (!tx_bufs && !rx_bufs) { + return 0; + } + + /* context setup */ + spi_context_lock(&data->ctx, false, NULL, NULL, config); + ret = spi_config(dev, config); if (ret) { + spi_context_release(&data->ctx, ret); return ret; } - if (!tx_bufs && !rx_bufs) { - return 0; - } - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); ret = spi_ambiq_xfer(dev, config); + spi_context_release(&data->ctx, ret); + return ret; } static int spi_ambiq_release(const struct device *dev, const struct spi_config *config) { struct spi_ambiq_data *data = dev->data; + am_hal_iom_status_t iom_status; + + am_hal_iom_status_get(data->iom_handler, &iom_status); - if (!sys_read32(SPI_STAT(dev))) { + if ((iom_status.bStatIdle != IOM0_STATUS_IDLEST_IDLE) || + (iom_status.bStatCmdAct == IOM0_STATUS_CMDACT_ACTIVE) || + (iom_status.ui32NumPendTransactions)) { return -EBUSY; } @@ -228,14 +425,33 @@ static int spi_ambiq_init(const struct device *dev) { struct spi_ambiq_data *data = dev->data; const struct spi_ambiq_config *cfg = dev->config; - int ret; + int ret = 0; - ret = am_hal_iom_initialize((cfg->base - REG_IOM_BASEADDR) / cfg->size, &data->IOMHandle); + if (AM_HAL_STATUS_SUCCESS != + am_hal_iom_initialize((cfg->base - REG_IOM_BASEADDR) / cfg->size, &data->iom_handler)) { + LOG_ERR("Fail to initialize SPI\n"); + return -ENXIO; + } ret = cfg->pwr_func(); - ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + ret |= pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("Fail to config SPI pins\n"); + goto end; + } +#ifdef CONFIG_SPI_AMBIQ_DMA + am_hal_iom_interrupt_clear(data->iom_handler, AM_HAL_IOM_INT_CQUPD | AM_HAL_IOM_INT_ERR); + am_hal_iom_interrupt_enable(data->iom_handler, AM_HAL_IOM_INT_CQUPD | AM_HAL_IOM_INT_ERR); + cfg->irq_config_func(); +#endif +end: + if (ret < 0) { + am_hal_iom_uninitialize(data->iom_handler); + } else { + spi_context_unlock_unconditionally(&data->ctx); + } return ret; } @@ -249,14 +465,21 @@ static int spi_ambiq_init(const struct device *dev) k_busy_wait(PWRCTRL_MAX_WAIT_US); \ return 0; \ } \ + static void spi_irq_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), spi_ambiq_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + }; \ static struct spi_ambiq_data spi_ambiq_data##n = { \ SPI_CONTEXT_INIT_LOCK(spi_ambiq_data##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_ambiq_data##n, ctx)}; \ + SPI_CONTEXT_INIT_SYNC(spi_ambiq_data##n, ctx), .inst_idx = n}; \ static const struct spi_ambiq_config spi_ambiq_config##n = { \ .base = DT_INST_REG_ADDR(n), \ .size = DT_INST_REG_SIZE(n), \ .clock_freq = DT_INST_PROP(n, clock_frequency), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .irq_config_func = spi_irq_config_func_##n, \ .pwr_func = pwr_on_ambiq_spi_##n}; \ DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, NULL, &spi_ambiq_data##n, &spi_ambiq_config##n, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_ambiq_driver_api); diff --git a/drivers/spi/spi_esp32_spim.c b/drivers/spi/spi_esp32_spim.c index d209fd85b04865..5bcec47577f716 100644 --- a/drivers/spi/spi_esp32_spim.c +++ b/drivers/spi/spi_esp32_spim.c @@ -216,16 +216,34 @@ static int spi_esp32_init(const struct device *dev) int err; const struct spi_esp32_config *cfg = dev->config; struct spi_esp32_data *data = dev->data; + spi_hal_context_t *hal = &data->hal; if (!cfg->clock_dev) { return -EINVAL; } + if (!device_is_ready(cfg->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + /* Enables SPI peripheral */ + err = clock_control_on(cfg->clock_dev, cfg->clock_subsys); + if (err < 0) { + LOG_ERR("Error enabling SPI clock"); + return err; + } + + spi_ll_master_init(hal->hw); + if (cfg->dma_enabled) { spi_esp32_init_dma(dev); } #ifdef CONFIG_SPI_ESP32_INTERRUPT + spi_ll_disable_int(cfg->spi); + spi_ll_clear_int_stat(cfg->spi); + data->irq_line = esp_intr_alloc(cfg->irq_source, 0, (ISR_HANDLER)spi_esp32_isr, @@ -285,19 +303,6 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev, return 0; } - if (!device_is_ready(cfg->clock_dev)) { - LOG_ERR("clock control device not ready"); - return -ENODEV; - } - - /* enables SPI peripheral */ - if (clock_control_on(cfg->clock_dev, cfg->clock_subsys)) { - LOG_ERR("Could not enable SPI clock"); - return -EIO; - } - - spi_ll_master_init(hal->hw); - ctx->config = spi_cfg; if (spi_cfg->operation & SPI_HALF_DUPLEX) { diff --git a/drivers/spi/spi_gecko.c b/drivers/spi/spi_gecko.c index d07485793b02f4..3c79bdb4e2f1bc 100644 --- a/drivers/spi/spi_gecko.c +++ b/drivers/spi/spi_gecko.c @@ -33,7 +33,10 @@ LOG_MODULE_REGISTER(spi_gecko); #define CLOCK_USART(id) _CONCAT(cmuClock_USART, id) #define GET_GECKO_USART_CLOCK(n) CLOCK_USART(DT_INST_PROP(n, peripheral_id)) #else -#if (USART_COUNT <= 2) +#if (USART_COUNT == 1) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : -1) +#elif (USART_COUNT == 2) #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ : ((ref) == USART1) ? cmuClock_USART1 \ : -1) @@ -81,6 +84,7 @@ struct spi_gecko_data { struct spi_gecko_config { USART_TypeDef *base; CMU_Clock_TypeDef clock; + uint32_t clock_frequency; #ifdef CONFIG_PINCTRL const struct pinctrl_dev_config *pcfg; #else @@ -101,6 +105,7 @@ static int spi_config(const struct device *dev, { const struct spi_gecko_config *gecko_config = dev->config; struct spi_gecko_data *data = dev->data; + uint32_t spi_frequency = CMU_ClockFreqGet(gecko_config->clock) / 2; if (config->operation & SPI_HALF_DUPLEX) { LOG_ERR("Half-duplex not supported"); @@ -138,6 +143,20 @@ static int spi_config(const struct device *dev, return -ENOTSUP; } + /* Set frequency to the minimum of what the device supports, what the + * user has configured the controller to, and the max frequency for the + * transaction. + */ + if (gecko_config->clock_frequency > spi_frequency) { + LOG_ERR("SPI clock-frequency too high"); + return -EINVAL; + } + spi_frequency = MIN(gecko_config->clock_frequency, spi_frequency); + if (config->frequency) { + spi_frequency = MIN(config->frequency, spi_frequency); + } + USART_BaudrateSyncSet(gecko_config->base, 0, spi_frequency); + /* Set Loopback */ if (config->operation & SPI_MODE_LOOP) { gecko_config->base->CTRL |= USART_CTRL_LOOPBK; @@ -377,7 +396,8 @@ static const struct spi_driver_api spi_gecko_api = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .base = (USART_TypeDef *) \ DT_INST_REG_ADDR(n), \ - .clock = GET_GECKO_USART_CLOCK(n) \ + .clock = GET_GECKO_USART_CLOCK(n), \ + .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000) \ }; \ DEVICE_DT_INST_DEFINE(n, \ spi_gecko_init, \ @@ -398,6 +418,7 @@ static const struct spi_driver_api spi_gecko_api = { .base = (USART_TypeDef *) \ DT_INST_REG_ADDR(n), \ .clock = GET_GECKO_USART_CLOCK(n), \ + .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000), \ .pin_rx = { DT_INST_PROP_BY_IDX(n, location_rx, 1), \ DT_INST_PROP_BY_IDX(n, location_rx, 2), \ gpioModeInput, 1}, \ diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 1fa3ea167d7384..70f42122cf4e16 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -122,31 +122,34 @@ static uint32_t bits2bytes(uint32_t bits) static __aligned(32) uint32_t dummy_rx_tx_buffer __nocache; /* This function is executed in the interrupt context */ -static void dma_callback(const struct device *dev, void *arg, +static void dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, int status) { - /* arg directly holds the spi device */ - struct spi_stm32_data *data = arg; + ARG_UNUSED(dma_dev); + + /* arg holds SPI DMA data + * Passed in spi_stm32_dma_tx/rx_load() + */ + struct spi_stm32_data *spi_dma_data = arg; if (status < 0) { LOG_ERR("DMA callback error with channel %d.", channel); - data->status_flags |= SPI_STM32_DMA_ERROR_FLAG; + spi_dma_data->status_flags |= SPI_STM32_DMA_ERROR_FLAG; } else { /* identify the origin of this callback */ - if (channel == data->dma_tx.channel) { + if (channel == spi_dma_data->dma_tx.channel) { /* this part of the transfer ends */ - data->status_flags |= SPI_STM32_DMA_TX_DONE_FLAG; - } else if (channel == data->dma_rx.channel) { + spi_dma_data->status_flags |= SPI_STM32_DMA_TX_DONE_FLAG; + } else if (channel == spi_dma_data->dma_rx.channel) { /* this part of the transfer ends */ - data->status_flags |= SPI_STM32_DMA_RX_DONE_FLAG; + spi_dma_data->status_flags |= SPI_STM32_DMA_RX_DONE_FLAG; } else { - LOG_ERR("DMA callback channel %d is not valid.", - channel); - data->status_flags |= SPI_STM32_DMA_ERROR_FLAG; + LOG_ERR("DMA callback channel %d is not valid.", channel); + spi_dma_data->status_flags |= SPI_STM32_DMA_ERROR_FLAG; } } - k_sem_give(&data->status_sem); + k_sem_give(&spi_dma_data->status_sem); } static int spi_stm32_dma_tx_load(const struct device *dev, const uint8_t *buf, @@ -197,7 +200,7 @@ static int spi_stm32_dma_tx_load(const struct device *dev, const uint8_t *buf, /* direction is given by the DT */ stream->dma_cfg.head_block = blk_cfg; - /* give the client dev as arg, as the callback comes from the dma */ + /* give the dma channel data as arg, as the callback comes from the dma */ stream->dma_cfg.user_data = data; /* pass our client origin to the dma: data->dma_tx.dma_channel */ ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.channel, @@ -463,7 +466,7 @@ static void spi_stm32_cs_control(const struct device *dev, bool on) LL_PWR_UnselectSUBGHZSPI_NSS(); } } -#endif +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_spi_subghz) */ } static void spi_stm32_complete(const struct device *dev, int status) @@ -483,7 +486,7 @@ static void spi_stm32_complete(const struct device *dev, int status) } #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_spi_fifo) @@ -491,7 +494,7 @@ static void spi_stm32_complete(const struct device *dev, int status) while (ll_func_rx_is_not_empty(spi)) { (void) LL_SPI_ReceiveData8(spi); } -#endif +#endif /* compat st_stm32_spi_fifo*/ if (LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { while (ll_func_spi_is_busy(spi)) { @@ -557,7 +560,7 @@ static void spi_stm32_isr(const struct device *dev) spi_stm32_complete(dev, err); } } -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ static int spi_stm32_configure(const struct device *dev, const struct spi_config *config) @@ -788,7 +791,7 @@ static int transceive(const struct device *dev, if (asynchronous) { return -ENOTSUP; } -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); @@ -824,7 +827,7 @@ static int transceive(const struct device *dev, while (ll_func_rx_is_not_empty(spi)) { (void) LL_SPI_ReceiveData8(spi); } -#endif +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_spi_fifo) */ LL_SPI_Enable(spi); @@ -842,13 +845,13 @@ static int transceive(const struct device *dev, } #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ -#if CONFIG_SOC_SERIES_STM32H7X +#ifdef CONFIG_SOC_SERIES_STM32H7X /* * Add a small delay after enabling to prevent transfer stalling at high * system clock frequency (see errata sheet ES0392). */ k_busy_wait(WAIT_1US); -#endif +#endif /* CONFIG_SOC_SERIES_STM32H7X */ /* This is turned off in spi_stm32_complete(). */ spi_stm32_cs_control(dev, true); @@ -870,7 +873,7 @@ static int transceive(const struct device *dev, ll_func_enable_int_tx_empty(spi); ret = spi_context_wait_for_completion(&data->ctx); -#else +#else /* CONFIG_SPI_STM32_INTERRUPT */ do { ret = spi_stm32_shift_frames(cfg, data); } while (!ret && spi_stm32_transfer_ongoing(data)); @@ -883,7 +886,7 @@ static int transceive(const struct device *dev, } #endif /* CONFIG_SPI_SLAVE */ -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ end: spi_context_release(&data->ctx, ret); @@ -979,6 +982,7 @@ static int transceive_dma(const struct device *dev, struct spi_stm32_data *data = dev->data; SPI_TypeDef *spi = cfg->spi; int ret; + int err; if (!tx_bufs && !rx_bufs) { return 0; @@ -1062,7 +1066,7 @@ static int transceive_dma(const struct device *dev, #ifdef SPI_SR_FTLVL while (LL_SPI_GetTxFIFOLevel(spi) > 0) { } -#endif +#endif /* SPI_SR_FTLVL */ #ifdef CONFIG_SPI_STM32_ERRATA_BUSY WAIT_FOR(ll_func_spi_dma_busy(spi) != 0, @@ -1072,7 +1076,7 @@ static int transceive_dma(const struct device *dev, /* wait until spi is no more busy (spi TX fifo is really empty) */ while (ll_func_spi_dma_busy(spi) == 0) { } -#endif +#endif /* CONFIG_SPI_STM32_ERRATA_BUSY */ #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) /* toggle the DMA transfer request */ @@ -1095,8 +1099,14 @@ static int transceive_dma(const struct device *dev, LL_SPI_DisableDMAReq_TX(spi); LL_SPI_DisableDMAReq_RX(spi); - dma_stop(data->dma_rx.dma_dev, data->dma_rx.channel); - dma_stop(data->dma_tx.dma_dev, data->dma_tx.channel); + err = dma_stop(data->dma_rx.dma_dev, data->dma_rx.channel); + if (err) { + LOG_DBG("Rx dma_stop failed with error %d", err); + } + err = dma_stop(data->dma_tx.dma_dev, data->dma_tx.channel); + if (err) { + LOG_DBG("Tx dma_stop failed with error %d", err); + } #ifdef CONFIG_SPI_SLAVE if (spi_context_is_slave(&data->ctx) && !ret) { @@ -1159,7 +1169,7 @@ static inline bool spi_stm32_is_subghzspi(const struct device *dev) #else ARG_UNUSED(dev); return false; -#endif +#endif /* st_stm32_spi_subghz */ } static int spi_stm32_init(const struct device *dev) @@ -1201,7 +1211,7 @@ static int spi_stm32_init(const struct device *dev) #ifdef CONFIG_SPI_STM32_INTERRUPT cfg->irq_config(dev); -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ #ifdef CONFIG_SPI_STM32_DMA if ((data->dma_rx.dma_dev != NULL) && @@ -1305,7 +1315,7 @@ static void spi_stm32_irq_config_func_##id(const struct device *dev) \ #define STM32_SPI_IRQ_HANDLER_DECL(id) #define STM32_SPI_IRQ_HANDLER_FUNC(id) #define STM32_SPI_IRQ_HANDLER(id) -#endif +#endif /* CONFIG_SPI_STM32_INTERRUPT */ #define SPI_DMA_CHANNEL_INIT(index, dir, dir_cap, src_dev, dest_dev) \ .dma_dev = DEVICE_DT_GET(STM32_DMA_CTLR(index, dir)), \ @@ -1333,7 +1343,7 @@ static void spi_stm32_irq_config_func_##id(const struct device *dev) \ STM32_DMA_FEATURES(index, dir)), \ -#if CONFIG_SPI_STM32_DMA +#ifdef CONFIG_SPI_STM32_DMA #define SPI_DMA_CHANNEL(id, dir, DIR, src, dest) \ .dma_##dir = { \ COND_CODE_1(DT_INST_DMAS_HAS_NAME(id, dir), \ @@ -1346,7 +1356,7 @@ static void spi_stm32_irq_config_func_##id(const struct device *dev) \ #else #define SPI_DMA_CHANNEL(id, dir, DIR, src, dest) #define SPI_DMA_STATUS_SEM(id) -#endif +#endif /* CONFIG_SPI_STM32_DMA */ #define SPI_SUPPORTS_FIFO(id) DT_INST_NODE_HAS_PROP(id, fifo_enable) #define SPI_GET_FIFO_PROP(id) DT_INST_PROP(id, fifo_enable) diff --git a/drivers/spi/spi_max32.c b/drivers/spi/spi_max32.c new file mode 100644 index 00000000000000..3dc6ecf18a4b4c --- /dev/null +++ b/drivers/spi/spi_max32.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max32_spi + +#include +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(spi_max32, CONFIG_SPI_LOG_LEVEL); +#include "spi_context.h" + +struct max32_spi_config { + mxc_spi_regs_t *regs; + const struct pinctrl_dev_config *pctrl; + const struct device *clock; + struct max32_perclk perclk; +#ifdef CONFIG_SPI_MAX32_INTERRUPT + void (*irq_config_func)(const struct device *dev); +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ +}; + +/* Device run time data */ +struct max32_spi_data { + struct spi_context ctx; + const struct device *dev; + mxc_spi_req_t req; + uint8_t dummy[2]; +#ifdef CONFIG_SPI_ASYNC + struct k_work async_work; +#endif /* CONFIG_SPI_ASYNC */ +}; + +#ifdef CONFIG_SPI_MAX32_INTERRUPT +static void spi_max32_callback(mxc_spi_req_t *req, int error); +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ + +static int spi_configure(const struct device *dev, const struct spi_config *config) +{ + int ret = 0; + const struct max32_spi_config *cfg = dev->config; + mxc_spi_regs_t *regs = cfg->regs; + struct max32_spi_data *data = dev->data; + + if (spi_context_configured(&data->ctx, config)) { + return 0; + } + + if (SPI_OP_MODE_GET(config->operation) & SPI_OP_MODE_SLAVE) { + return -ENOTSUP; + } + + int master_mode = 1; + int quad_mode = 0; + int num_slaves = 1; + int ss_polarity = (config->operation & SPI_CS_ACTIVE_HIGH) ? 1 : 0; + unsigned int spi_speed = (unsigned int)config->frequency; + + ret = Wrap_MXC_SPI_Init(regs, master_mode, quad_mode, num_slaves, ss_polarity, spi_speed); + if (ret) { + return ret; + } + + int cpol = (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) ? 1 : 0; + int cpha = (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) ? 1 : 0; + + if (cpol && cpha) { + ret = MXC_SPI_SetMode(regs, SPI_MODE_3); + } else if (cpha) { + ret = MXC_SPI_SetMode(regs, SPI_MODE_2); + } else if (cpol) { + ret = MXC_SPI_SetMode(regs, SPI_MODE_1); + } else { + ret = MXC_SPI_SetMode(regs, SPI_MODE_0); + } + if (ret) { + return ret; + } + + ret = MXC_SPI_SetDataSize(regs, SPI_WORD_SIZE_GET(config->operation)); + if (ret) { + return ret; + } + +#if defined(CONFIG_SPI_EXTENDED_MODES) + switch (config->operation & SPI_LINES_MASK) { + case SPI_LINES_QUAD: + ret = MXC_SPI_SetWidth(regs, SPI_WIDTH_QUAD); + break; + case SPI_LINES_DUAL: + ret = MXC_SPI_SetWidth(regs, SPI_WIDTH_DUAL); + break; + case SPI_LINES_OCTAL: + ret = -ENOTSUP; + break; + case SPI_LINES_SINGLE: + default: + ret = MXC_SPI_SetWidth(regs, SPI_WIDTH_STANDARD); + break; + } + + if (ret) { + return ret; + } +#endif + + data->ctx.config = config; + + return ret; +} + +static inline int spi_max32_get_dfs_shift(const struct spi_context *ctx) +{ + if (SPI_WORD_SIZE_GET(ctx->config->operation) < 9) { + return 0; + } + + return 1; +} + +static void spi_max32_setup(mxc_spi_regs_t *spi, mxc_spi_req_t *req) +{ + req->rxCnt = 0; + req->txCnt = 0; + + if (spi->ctrl0 & ADI_MAX32_SPI_CTRL_MASTER_MODE) { + MXC_SPI_SetSlave(spi, req->ssIdx); + } + + if (req->rxData && req->rxLen) { + MXC_SETFIELD(spi->ctrl1, MXC_F_SPI_CTRL1_RX_NUM_CHAR, + req->rxLen << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS); + spi->dma |= MXC_F_SPI_DMA_RX_FIFO_EN; + } else { + spi->ctrl1 &= ~MXC_F_SPI_CTRL1_RX_NUM_CHAR; + spi->dma &= ~MXC_F_SPI_DMA_RX_FIFO_EN; + } + + if (req->txLen) { + MXC_SETFIELD(spi->ctrl1, MXC_F_SPI_CTRL1_TX_NUM_CHAR, + req->txLen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS); + spi->dma |= MXC_F_SPI_DMA_TX_FIFO_EN; + } else { + spi->ctrl1 &= ~MXC_F_SPI_CTRL1_TX_NUM_CHAR; + spi->dma &= ~MXC_F_SPI_DMA_TX_FIFO_EN; + } + + spi->dma |= (ADI_MAX32_SPI_DMA_TX_FIFO_CLEAR | ADI_MAX32_SPI_DMA_RX_FIFO_CLEAR); + spi->ctrl0 |= MXC_F_SPI_CTRL0_EN; + MXC_SPI_ClearFlags(spi); +} + +#ifndef CONFIG_SPI_MAX32_INTERRUPT +static int spi_max32_transceive_sync(mxc_spi_regs_t *spi, struct max32_spi_data *data, + uint8_t dfs_shift) +{ + int ret = 0; + mxc_spi_req_t *req = &data->req; + uint32_t remain, flags, tx_len, rx_len; + + MXC_SPI_ClearTXFIFO(spi); + MXC_SPI_ClearRXFIFO(spi); + + tx_len = req->txLen << dfs_shift; + rx_len = req->rxLen << dfs_shift; + do { + remain = tx_len - req->txCnt; + if (remain > 0) { + if (!data->req.txData) { + req->txCnt += MXC_SPI_WriteTXFIFO(spi, data->dummy, + MIN(remain, sizeof(data->dummy))); + } else { + req->txCnt += + MXC_SPI_WriteTXFIFO(spi, &req->txData[req->txCnt], remain); + } + if (!(spi->ctrl0 & MXC_F_SPI_CTRL0_START)) { + spi->ctrl0 |= MXC_F_SPI_CTRL0_START; + } + } + + if (req->rxCnt < rx_len) { + req->rxCnt += MXC_SPI_ReadRXFIFO(spi, &req->rxData[req->rxCnt], + rx_len - req->rxCnt); + } + } while ((req->txCnt < tx_len) || (req->rxCnt < rx_len)); + + do { + flags = MXC_SPI_GetFlags(spi); + } while (!(flags & ADI_MAX32_SPI_INT_FL_MST_DONE)); + MXC_SPI_ClearFlags(spi); + + return ret; +} +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ + +static int spi_max32_transceive(const struct device *dev) +{ + int ret = 0; + const struct max32_spi_config *cfg = dev->config; + struct max32_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + uint32_t len; + uint8_t dfs_shift; + + MXC_SPI_ClearTXFIFO(cfg->regs); + + dfs_shift = spi_max32_get_dfs_shift(ctx); + + len = spi_context_max_continuous_chunk(ctx); + data->req.txLen = len >> dfs_shift; + data->req.txData = (uint8_t *)ctx->tx_buf; + data->req.rxLen = len >> dfs_shift; + data->req.rxData = ctx->rx_buf; + + data->req.rxData = ctx->rx_buf; + data->req.rxLen = len >> dfs_shift; + if (!data->req.rxData) { + /* Pass a dummy buffer to HAL if receive buffer is NULL, otherwise + * corrupt data is read during subsequent transactions. + */ + data->req.rxData = data->dummy; + data->req.rxLen = 0; + } + data->req.spi = cfg->regs; + data->req.ssIdx = ctx->config->slave; + data->req.ssDeassert = 0; + data->req.txCnt = 0; + data->req.rxCnt = 0; + spi_max32_setup(cfg->regs, &data->req); +#ifdef CONFIG_SPI_MAX32_INTERRUPT + MXC_SPI_SetTXThreshold(cfg->regs, 1); + if (data->req.rxLen) { + MXC_SPI_SetRXThreshold(cfg->regs, 2); + MXC_SPI_EnableInt(cfg->regs, ADI_MAX32_SPI_INT_EN_RX_THD); + } + MXC_SPI_EnableInt(cfg->regs, ADI_MAX32_SPI_INT_EN_TX_THD | ADI_MAX32_SPI_INT_EN_MST_DONE); + + if (!data->req.txData) { + data->req.txCnt = + MXC_SPI_WriteTXFIFO(cfg->regs, data->dummy, MIN(len, sizeof(data->dummy))); + } else { + data->req.txCnt = MXC_SPI_WriteTXFIFO(cfg->regs, data->req.txData, len); + } + + MXC_SPI_StartTransmission(cfg->regs); +#else + ret = spi_max32_transceive_sync(cfg->regs, data, dfs_shift); + if (ret) { + ret = -EIO; + } else { + spi_context_update_tx(ctx, 1, len); + spi_context_update_rx(ctx, 1, len); + } +#endif + + return ret; +} + +static int transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool async, spi_callback_t cb, void *userdata) +{ + int ret = 0; + const struct max32_spi_config *cfg = dev->config; + struct max32_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + bool hw_cs_ctrl = true; + +#ifndef CONFIG_SPI_MAX32_INTERRUPT + if (async) { + return -ENOTSUP; + } +#endif + + spi_context_lock(ctx, async, cb, userdata, config); + + ret = spi_configure(dev, config); + if (ret != 0) { + spi_context_release(ctx, ret); + return -EIO; + } + + spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); + + /* Check if CS GPIO exists */ + if (spi_cs_is_gpio(config)) { + hw_cs_ctrl = false; + } + MXC_SPI_HWSSControl(cfg->regs, hw_cs_ctrl); + + /* Assert the CS line if HW control disabled */ + if (!hw_cs_ctrl) { + spi_context_cs_control(ctx, true); + } else { + cfg->regs->ctrl0 = + (cfg->regs->ctrl0 & ~MXC_F_SPI_CTRL0_START) | MXC_F_SPI_CTRL0_SS_CTRL; + } + +#ifdef CONFIG_SPI_MAX32_INTERRUPT + do { + ret = spi_max32_transceive(dev); + if (!ret) { + ret = spi_context_wait_for_completion(ctx); + if (ret || async) { + break; + } + } else { + break; + } + } while ((spi_context_tx_on(ctx) || spi_context_rx_on(ctx))); +#else + do { + ret = spi_max32_transceive(dev); + if (ret) { + break; + } + } while (spi_context_tx_on(ctx) || spi_context_rx_on(ctx)); + +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ + + /* Deassert the CS line if hw control disabled */ + if (!async) { + if (!hw_cs_ctrl) { + spi_context_cs_control(ctx, false); + } else { + cfg->regs->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | MXC_F_SPI_CTRL0_SS_CTRL | + MXC_F_SPI_CTRL0_EN); + cfg->regs->ctrl0 |= MXC_F_SPI_CTRL0_EN; + } + } + + spi_context_release(ctx, ret); + + return ret; +} + +static int api_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int api_transceive_async(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +#ifdef CONFIG_SPI_MAX32_INTERRUPT +static void spi_max32_callback(mxc_spi_req_t *req, int error) +{ + struct max32_spi_data *data = CONTAINER_OF(req, struct max32_spi_data, req); + struct spi_context *ctx = &data->ctx; + const struct device *dev = data->dev; + uint32_t len; + + len = spi_context_max_continuous_chunk(ctx); + spi_context_update_tx(ctx, 1, len); + spi_context_update_rx(ctx, 1, len); +#ifdef CONFIG_SPI_ASYNC + if (ctx->asynchronous && ((spi_context_tx_on(ctx) || spi_context_rx_on(ctx)))) { + k_work_submit(&data->async_work); + } else { + if (spi_cs_is_gpio(ctx->config)) { + spi_context_cs_control(ctx, false); + } else { + req->spi->ctrl0 &= ~(MXC_F_SPI_CTRL0_START | MXC_F_SPI_CTRL0_SS_CTRL | + MXC_F_SPI_CTRL0_EN); + req->spi->ctrl0 |= MXC_F_SPI_CTRL0_EN; + } + spi_context_complete(ctx, dev, error == E_NO_ERROR ? 0 : -EIO); + } +#else + spi_context_complete(ctx, dev, error == E_NO_ERROR ? 0 : -EIO); +#endif +} + +#ifdef CONFIG_SPI_ASYNC +void spi_max32_async_work_handler(struct k_work *work) +{ + struct max32_spi_data *data = CONTAINER_OF(work, struct max32_spi_data, async_work); + const struct device *dev = data->dev; + int ret; + + ret = spi_max32_transceive(dev); + if (ret) { + spi_context_complete(&data->ctx, dev, -EIO); + } +} +#endif /* CONFIG_SPI_ASYNC */ + +static void spi_max32_isr(const struct device *dev) +{ + const struct max32_spi_config *cfg = dev->config; + struct max32_spi_data *data = dev->data; + mxc_spi_req_t *req = &data->req; + mxc_spi_regs_t *spi = cfg->regs; + uint32_t flags, remain; + uint8_t dfs_shift = spi_max32_get_dfs_shift(&data->ctx); + + flags = MXC_SPI_GetFlags(spi); + MXC_SPI_ClearFlags(spi); + + remain = (req->txLen << dfs_shift) - req->txCnt; + if (flags & ADI_MAX32_SPI_INT_FL_TX_THD) { + if (remain) { + if (!data->req.txData) { + req->txCnt += MXC_SPI_WriteTXFIFO(cfg->regs, data->dummy, + MIN(remain, sizeof(data->dummy))); + } else { + req->txCnt += + MXC_SPI_WriteTXFIFO(spi, &req->txData[req->txCnt], remain); + } + } else { + MXC_SPI_DisableInt(spi, ADI_MAX32_SPI_INT_EN_TX_THD); + } + } + + remain = (req->rxLen << dfs_shift) - req->rxCnt; + if (remain) { + req->rxCnt += MXC_SPI_ReadRXFIFO(spi, &req->rxData[req->rxCnt], remain); + remain = (req->rxLen << dfs_shift) - req->rxCnt; + if (remain >= MXC_SPI_FIFO_DEPTH) { + MXC_SPI_SetRXThreshold(spi, 2); + } else { + MXC_SPI_SetRXThreshold(spi, remain); + } + } else { + MXC_SPI_DisableInt(spi, ADI_MAX32_SPI_INT_EN_RX_THD); + } + + if ((req->txLen == req->txCnt) && (req->rxLen == req->rxCnt)) { + MXC_SPI_DisableInt(spi, ADI_MAX32_SPI_INT_EN_TX_THD | ADI_MAX32_SPI_INT_EN_RX_THD); + if (flags & ADI_MAX32_SPI_INT_FL_MST_DONE) { + MXC_SPI_DisableInt(spi, ADI_MAX32_SPI_INT_EN_MST_DONE); + spi_max32_callback(req, 0); + } + } +} +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ + +static int api_release(const struct device *dev, const struct spi_config *config) +{ + struct max32_spi_data *data = dev->data; + + if (!spi_context_configured(&data->ctx, config)) { + return -EINVAL; + } + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int spi_max32_init(const struct device *dev) +{ + int ret = 0; + const struct max32_spi_config *const cfg = dev->config; + mxc_spi_regs_t *regs = cfg->regs; + struct max32_spi_data *data = dev->data; + + if (!device_is_ready(cfg->clock)) { + return -ENODEV; + } + + MXC_SPI_Shutdown(regs); + + ret = clock_control_on(cfg->clock, (clock_control_subsys_t)&cfg->perclk); + if (ret) { + return ret; + } + + ret = pinctrl_apply_state(cfg->pctrl, PINCTRL_STATE_DEFAULT); + if (ret) { + return ret; + } + + ret = spi_context_cs_configure_all(&data->ctx); + if (ret < 0) { + return ret; + } + + data->dev = dev; + +#ifdef CONFIG_SPI_MAX32_INTERRUPT + cfg->irq_config_func(dev); +#ifdef CONFIG_SPI_ASYNC + k_work_init(&data->async_work, spi_max32_async_work_handler); +#endif +#endif + + spi_context_unlock_unconditionally(&data->ctx); + + return ret; +} + +/* SPI driver APIs structure */ +static const struct spi_driver_api spi_max32_api = { + .transceive = api_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = api_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ + .release = api_release, +}; + +/* SPI driver registration */ +#ifdef CONFIG_SPI_MAX32_INTERRUPT +#define SPI_MAX32_CONFIG_IRQ_FUNC(n) .irq_config_func = spi_max32_irq_config_func_##n, + +#define SPI_MAX32_IRQ_CONFIG_FUNC(n) \ + static void spi_max32_irq_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), spi_max32_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } +#else +#define SPI_MAX32_CONFIG_IRQ_FUNC(n) +#define SPI_MAX32_IRQ_CONFIG_FUNC(n) +#endif /* CONFIG_SPI_MAX32_INTERRUPT */ + +#define DEFINE_SPI_MAX32(_num) \ + PINCTRL_DT_INST_DEFINE(_num); \ + SPI_MAX32_IRQ_CONFIG_FUNC(_num) \ + static const struct max32_spi_config max32_spi_config_##_num = { \ + .regs = (mxc_spi_regs_t *)DT_INST_REG_ADDR(_num), \ + .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(_num), \ + .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(_num)), \ + .perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \ + .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \ + SPI_MAX32_CONFIG_IRQ_FUNC(_num)}; \ + static struct max32_spi_data max32_spi_data_##_num = { \ + SPI_CONTEXT_INIT_LOCK(max32_spi_data_##_num, ctx), \ + SPI_CONTEXT_INIT_SYNC(max32_spi_data_##_num, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(_num), ctx)}; \ + DEVICE_DT_INST_DEFINE(_num, spi_max32_init, NULL, &max32_spi_data_##_num, \ + &max32_spi_config_##_num, PRE_KERNEL_2, CONFIG_SPI_INIT_PRIORITY, \ + &spi_max32_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_SPI_MAX32) diff --git a/drivers/spi/spi_mcux_lpspi.c b/drivers/spi/spi_mcux_lpspi.c index 5432debd68a3e5..0d5b7b27f48578 100644 --- a/drivers/spi/spi_mcux_lpspi.c +++ b/drivers/spi/spi_mcux_lpspi.c @@ -75,6 +75,7 @@ struct spi_mcux_data { #ifdef CONFIG_SPI_RTIO struct rtio *r; + struct mpsc io_q; struct rtio_iodev iodev; struct rtio_iodev_sqe *txn_head; struct rtio_iodev_sqe *txn_curr; @@ -702,7 +703,7 @@ static int spi_mcux_init(const struct device *dev) data->dt_spec.bus = dev; data->iodev.api = &spi_iodev_api; data->iodev.data = &data->dt_spec; - rtio_mpsc_init(&data->iodev.iodev_sq); + mpsc_init(&data->io_q); #endif err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); @@ -803,7 +804,7 @@ static void spi_mcux_iodev_next(const struct device *dev, bool completion) return; } - struct rtio_mpsc_node *next = rtio_mpsc_pop(&data->iodev.iodev_sq); + struct mpsc_node *next = mpsc_pop(&data->io_q); if (next != NULL) { struct rtio_iodev_sqe *next_sqe = CONTAINER_OF(next, struct rtio_iodev_sqe, q); @@ -832,7 +833,7 @@ static void spi_mcux_iodev_submit(const struct device *dev, { struct spi_mcux_data *data = dev->data; - rtio_mpsc_push(&data->iodev.iodev_sq, &iodev_sqe->q); + mpsc_push(&data->io_q, &iodev_sqe->q); spi_mcux_iodev_next(dev, false); } diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 08012b389c55bc..e1ce774af52290 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -5,8 +5,10 @@ */ #include +#include #include #include +#include #include #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 #include @@ -64,10 +66,28 @@ struct spi_nrfx_config { #endif uint32_t wake_pin; nrfx_gpiote_t wake_gpiote; +#ifdef CONFIG_DCACHE + uint32_t mem_attr; +#endif }; static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context); +static inline void finalize_spi_transaction(const struct device *dev, bool deactivate_cs) +{ + struct spi_nrfx_data *dev_data = dev->data; + const struct spi_nrfx_config *dev_config = dev->config; + void *reg = dev_config->spim.p_reg; + + if (deactivate_cs) { + spi_context_cs_control(&dev_data->ctx, false); + } + + if (NRF_SPIM_IS_320MHZ_SPIM(reg) && !(dev_data->ctx.config->operation & SPI_HOLD_ON_CS)) { + nrfy_spim_disable(reg); + } +} + static inline uint32_t get_nrf_spim_frequency(uint32_t frequency) { /* Get the highest supported frequency not exceeding the requested one. @@ -193,7 +213,7 @@ static int configure(const struct device *dev, } result = nrfx_spim_init(&dev_config->spim, &config, - event_handler, dev_data); + event_handler, (void *)dev); if (result != NRFX_SUCCESS) { LOG_ERR("Failed to initialize nrfx driver: %08x", result); return -EIO; @@ -298,6 +318,8 @@ static void finish_transaction(const struct device *dev, int error) spi_context_complete(ctx, dev, error); dev_data->busy = false; + + finalize_spi_transaction(dev, true); } static void transfer_next_chunk(const struct device *dev) @@ -328,6 +350,11 @@ static void transfer_next_chunk(const struct device *dev) } memcpy(dev_data->tx_buffer, tx_buf, chunk_len); +#ifdef CONFIG_DCACHE + if (dev_config->mem_attr & DT_MEM_CACHEABLE) { + sys_cache_data_flush_range(dev_data->tx_buffer, chunk_len); + } +#endif tx_buf = dev_data->tx_buffer; } @@ -377,7 +404,11 @@ static void transfer_next_chunk(const struct device *dev) static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context) { - struct spi_nrfx_data *dev_data = p_context; + const struct device *dev = p_context; + struct spi_nrfx_data *dev_data = dev->data; +#ifdef CONFIG_DCACHE + const struct spi_nrfx_config *dev_config = dev->config; +#endif if (p_event->type == NRFX_SPIM_EVENT_DONE) { /* Chunk length is set to 0 when a transaction is aborted @@ -395,6 +426,11 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context) if (spi_context_rx_buf_on(&dev_data->ctx) && p_event->xfer_desc.p_rx_buffer != NULL && p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) { +#ifdef CONFIG_DCACHE + if (dev_config->mem_attr & DT_MEM_CACHEABLE) { + sys_cache_data_invd_range(dev_data->rx_buffer, dev_data->chunk_len); + } +#endif (void)memcpy(dev_data->ctx.rx_buf, dev_data->rx_buffer, dev_data->chunk_len); @@ -417,6 +453,7 @@ static int transceive(const struct device *dev, { struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; + void *reg = dev_config->spim.p_reg; int error; spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); @@ -439,6 +476,9 @@ static int transceive(const struct device *dev, } spi_context_buffers_setup(&dev_data->ctx, tx_bufs, rx_bufs, 1); + if (NRF_SPIM_IS_320MHZ_SPIM(reg)) { + nrfy_spim_enable(reg); + } spi_context_cs_control(&dev_data->ctx, true); transfer_next_chunk(dev); @@ -467,9 +507,9 @@ static int transceive(const struct device *dev, #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 anomaly_58_workaround_clear(dev_data); #endif + } else if (error) { + finalize_spi_transaction(dev, true); } - - spi_context_cs_control(&dev_data->ctx, false); } spi_context_release(&dev_data->ctx, error); @@ -511,6 +551,7 @@ static int spi_nrfx_release(const struct device *dev, } spi_context_unlock_unconditionally(&dev_data->ctx); + finalize_spi_transaction(dev, false); return 0; } @@ -612,6 +653,7 @@ static int spi_nrfx_init(const struct device *dev) #define SPIM(idx) DT_NODELABEL(spi##idx) #define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) #define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop) +#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions) #define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \ @@ -621,6 +663,13 @@ static int spi_nrfx_init(const struct device *dev) ()) \ )) +#define SPIM_GET_MEM_ATTR(idx) \ + COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \ + (COND_CODE_1(DT_NODE_HAS_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr), \ + (DT_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr)), \ + (0))), \ + (0)) + #define SPI_NRFX_SPIM_DEFINE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ static void irq_connect##idx(void) \ @@ -669,6 +718,8 @@ 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)), \ + IF_ENABLED(CONFIG_DCACHE, \ + (.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \ }; \ BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ @@ -685,7 +736,7 @@ static int spi_nrfx_init(const struct device *dev) #define SPIM_MEMORY_SECTION(idx) \ COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \ (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ - DT_PHANDLE(SPIM(idx), memory_regions)))))), \ + SPIM_MEM_REGION(idx)))))), \ ()) #ifdef CONFIG_HAS_HW_NRF_SPIM0 diff --git a/drivers/spi/spi_psoc6.c b/drivers/spi/spi_psoc6.c index 7b6a30d3a65405..817c94899b2741 100644 --- a/drivers/spi/spi_psoc6.c +++ b/drivers/spi/spi_psoc6.c @@ -31,8 +31,7 @@ struct spi_psoc6_config { CySCB_Type *base; uint32_t periph_id; void (*irq_config_func)(const struct device *dev); - uint32_t num_pins; - struct soc_gpio_pin pins[]; + const struct pinctrl_dev_config *pcfg; }; struct spi_psoc6_transfer { @@ -377,7 +376,12 @@ static int spi_psoc6_init(const struct device *dev) const struct spi_psoc6_config *config = dev->config; struct spi_psoc6_data *data = dev->data; - soc_gpio_list_configure(config->pins, config->num_pins); + + /* Configure dt provided device signals when available */ + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } Cy_SysClk_PeriphAssignDivider(config->periph_id, CY_SYSCLK_DIV_8_BIT, @@ -408,12 +412,12 @@ static const struct spi_driver_api spi_psoc6_driver_api = { }; #define SPI_PSOC6_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ static void spi_psoc6_spi##n##_irq_cfg(const struct device *port); \ static const struct spi_psoc6_config spi_psoc6_config_##n = { \ .base = (CySCB_Type *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ - .num_pins = CY_PSOC6_DT_INST_NUM_PINS(n), \ - .pins = CY_PSOC6_DT_INST_PINS(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .irq_config_func = spi_psoc6_spi##n##_irq_cfg, \ }; \ static struct spi_psoc6_data spi_psoc6_dev_data_##n = { \ diff --git a/drivers/spi/spi_sam.c b/drivers/spi/spi_sam.c index 7cb6e8dc90c6fb..fb42cb6a553732 100644 --- a/drivers/spi/spi_sam.c +++ b/drivers/spi/spi_sam.c @@ -53,6 +53,7 @@ struct spi_sam_data { #ifdef CONFIG_SPI_RTIO struct rtio *r; /* context for thread calls */ + struct mpsc io_q; struct rtio_iodev iodev; struct rtio_iodev_sqe *txn_head; struct rtio_iodev_sqe *txn_curr; @@ -691,7 +692,7 @@ static void spi_sam_iodev_next(const struct device *dev, bool completion) return; } - struct rtio_mpsc_node *next = rtio_mpsc_pop(&data->iodev.iodev_sq); + struct mpsc_node *next = mpsc_pop(&data->io_q); if (next != NULL) { struct rtio_iodev_sqe *next_sqe = CONTAINER_OF(next, struct rtio_iodev_sqe, q); @@ -736,7 +737,7 @@ static void spi_sam_iodev_submit(const struct device *dev, { struct spi_sam_data *data = dev->data; - rtio_mpsc_push(&data->iodev.iodev_sq, &iodev_sqe->q); + mpsc_push(&data->io_q, &iodev_sqe->q); spi_sam_iodev_next(dev, false); } #endif @@ -866,7 +867,7 @@ static int spi_sam_init(const struct device *dev) data->dt_spec.bus = dev; data->iodev.api = &spi_iodev_api; data->iodev.data = &data->dt_spec; - rtio_mpsc_init(&data->iodev.iodev_sq); + mpsc_init(&data->io_q); #endif spi_context_unlock_unconditionally(&data->ctx); diff --git a/drivers/timer/Kconfig.mcux_lptmr b/drivers/timer/Kconfig.mcux_lptmr index 8879cb3b558c45..851c49ebbfb6f0 100644 --- a/drivers/timer/Kconfig.mcux_lptmr +++ b/drivers/timer/Kconfig.mcux_lptmr @@ -6,11 +6,21 @@ config MCUX_LPTMR_TIMER bool "MCUX LPTMR timer" default y - depends on DT_HAS_NXP_KINETIS_LPTMR_ENABLED + depends on DT_HAS_NXP_KINETIS_LPTMR_ENABLED || \ + MCUX_KINETIS_LPTMR depends on !COUNTER_MCUX_LPTMR - depends on PM select SYSTEM_TIMER_HAS_DISABLE_SUPPORT help This module implements a kernel device driver for the NXP MCUX Low Power Timer (LPTMR) and provides the standard "system clock driver" interfaces. + +config MCUX_KINETIS_LPTMR + bool + default y + depends on DT_HAS_NXP_KINETIS_LPTMR_ENABLED + select DEPRECATED + help + The compatible string "nxp,kinetis-lptmr" should + be swiched to "nxp,lptmr" in DT. The former will + be removed eventually. diff --git a/drivers/timer/ambiq_stimer.c b/drivers/timer/ambiq_stimer.c index e2c9d9976f4717..e0cfa948aa13d9 100644 --- a/drivers/timer/ambiq_stimer.c +++ b/drivers/timer/ambiq_stimer.c @@ -35,12 +35,41 @@ const int32_t z_sys_timer_irq_for_test = TIMER_IRQ; #endif -/* Value of STIMER counter when the previous kernel tick was announced */ -static atomic_t g_last_count; +/* Elapsed ticks since the previous kernel tick was announced, It will get accumulated every time + * stimer_isr is triggered, or sys_clock_set_timeout/sys_clock_elapsed API is called. + * It will be cleared after sys_clock_announce is called,. + */ +static uint32_t g_tick_elapsed; + +/* Value of STIMER counter when the previous timer API is called, this value is + * aligned to tick boundary. It is updated along with the g_tick_elapsed value. + */ +static uint32_t g_last_time_stamp; /* Spinlock to sync between Compare ISR and update of Compare register */ static struct k_spinlock g_lock; +static void update_tick_counter(void) +{ + /* Read current cycle count. */ + uint32_t now = am_hal_stimer_counter_get(); + + /* If current cycle count is smaller than the last time stamp, a counter overflow happened. + * We need to extend the current counter value to 64 bits and add it with 0xFFFFFFFF + * to get the correct elapsed cycles. + */ + uint64_t now_64 = (g_last_time_stamp <= now) ? (uint64_t)now : (uint64_t)now + COUNTER_MAX; + + /* Get elapsed cycles */ + uint32_t elapsed_cycle = (now_64 - g_last_time_stamp); + + /* Get elapsed ticks. */ + uint32_t dticks = elapsed_cycle / CYC_PER_TICK; + + g_last_time_stamp += dticks * CYC_PER_TICK; + g_tick_elapsed += dticks; +} + static void stimer_isr(const void *arg) { ARG_UNUSED(arg); @@ -52,22 +81,34 @@ static void stimer_isr(const void *arg) k_spinlock_key_t key = k_spin_lock(&g_lock); - uint32_t now = am_hal_stimer_counter_get(); - uint32_t dticks = (uint32_t)((now - g_last_count) / CYC_PER_TICK); - - g_last_count += dticks * CYC_PER_TICK; + /*Calculate the elapsed ticks based on the current cycle count*/ + update_tick_counter(); if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { - uint32_t next = g_last_count + CYC_PER_TICK; - if ((int32_t)(next - now) < MIN_DELAY) { - next += CYC_PER_TICK; - } - am_hal_stimer_compare_delta_set(0, next - g_last_count); + /* Get the counter value to trigger the next tick interrupt. */ + uint64_t next = (uint64_t)g_last_time_stamp + CYC_PER_TICK; + + /* Read current cycle count. */ + uint32_t now = am_hal_stimer_counter_get(); + + /* If current cycle count is smaller than the last time stamp, a counter + * overflow happened. We need to extend the current counter value to 64 bits + * and add 0xFFFFFFFF to get the correct elapsed cycles. + */ + uint64_t now_64 = (g_last_time_stamp <= now) ? (uint64_t)now + : (uint64_t)now + COUNTER_MAX; + + uint32_t delta = (now_64 + MIN_DELAY < next) ? (next - now_64) : MIN_DELAY; + + /* Set delta. */ + am_hal_stimer_compare_delta_set(0, delta); } k_spin_unlock(&g_lock, key); - sys_clock_announce(dticks); + + sys_clock_announce(g_tick_elapsed); + g_tick_elapsed = 0; } } @@ -79,17 +120,40 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) return; } - if (ticks == K_TICKS_FOREVER) { - return; - } - - ticks = MIN(MAX_TICKS, ticks); - /* If tick is 0, set delta cyc to MIN_DELAY to trigger tick isr asap */ - uint32_t cyc = MAX(ticks * CYC_PER_TICK, MIN_DELAY); + /* Adjust the ticks to the range of [1, MAX_TICKS]. */ + ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks; + ticks = CLAMP(ticks, 1, (int32_t)MAX_TICKS); k_spinlock_key_t key = k_spin_lock(&g_lock); - am_hal_stimer_compare_delta_set(0, cyc); + /* Update the internal tick counter*/ + update_tick_counter(); + + /* Get current hardware counter value.*/ + uint32_t now = am_hal_stimer_counter_get(); + + /* last: the last recorded counter value. + * now_64: current counter value. Extended to uint64_t to easy the handing of hardware + * counter overflow. + * next: counter values where to trigger the scheduled timeout. + * last < now_64 < next + */ + uint64_t last = (uint64_t)g_last_time_stamp; + uint64_t now_64 = (g_last_time_stamp <= now) ? (uint64_t)now : (uint64_t)now + COUNTER_MAX; + uint64_t next = now_64 + ticks * CYC_PER_TICK; + + uint32_t gap = next - last; + uint32_t gap_aligned = (gap / CYC_PER_TICK) * CYC_PER_TICK; + uint64_t next_aligned = last + gap_aligned; + + uint32_t delta = next_aligned - now_64; + + if (delta <= MIN_DELAY) { + /*If the delta value is smaller than MIN_DELAY, trigger a interrupt immediately*/ + am_hal_stimer_int_set(AM_HAL_STIMER_INT_COMPAREA); + } else { + am_hal_stimer_compare_delta_set(0, delta); + } k_spin_unlock(&g_lock, key); } @@ -101,10 +165,10 @@ uint32_t sys_clock_elapsed(void) } k_spinlock_key_t key = k_spin_lock(&g_lock); - uint32_t ret = (am_hal_stimer_counter_get() - g_last_count) / CYC_PER_TICK; - + update_tick_counter(); k_spin_unlock(&g_lock, key); - return ret; + + return g_tick_elapsed; } uint32_t sys_clock_cycle_get_32(void) @@ -115,7 +179,6 @@ uint32_t sys_clock_cycle_get_32(void) static int stimer_init(void) { uint32_t oldCfg; - k_spinlock_key_t key = k_spin_lock(&g_lock); oldCfg = am_hal_stimer_config(AM_HAL_STIMER_CFG_FREEZE); @@ -126,9 +189,7 @@ static int stimer_init(void) am_hal_stimer_config((oldCfg & ~(AM_HAL_STIMER_CFG_FREEZE | STIMER_STCFG_CLKSEL_Msk)) | AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_A_ENABLE); #endif - g_last_count = am_hal_stimer_counter_get(); - - k_spin_unlock(&g_lock, key); + g_last_time_stamp = am_hal_stimer_counter_get(); NVIC_ClearPendingIRQ(TIMER_IRQ); IRQ_CONNECT(TIMER_IRQ, 0, stimer_isr, 0, 0); diff --git a/drivers/timer/mcux_lptmr_timer.c b/drivers/timer/mcux_lptmr_timer.c index e91c11112ff9cb..930058f4ea40a8 100644 --- a/drivers/timer/mcux_lptmr_timer.c +++ b/drivers/timer/mcux_lptmr_timer.c @@ -4,7 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#if DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_lptmr) #define DT_DRV_COMPAT nxp_kinetis_lptmr +#else +#define DT_DRV_COMPAT nxp_lptmr +#endif #include #include diff --git a/drivers/usb/device/Kconfig b/drivers/usb/device/Kconfig index ad2432998c4377..f110d7df2f1d38 100644 --- a/drivers/usb/device/Kconfig +++ b/drivers/usb/device/Kconfig @@ -229,6 +229,17 @@ config USB_NATIVE_POSIX help Native Posix USB Device Controller Driver. +DT_ZEPHYR_UDC0 := $(dt_nodelabel_path,zephyr_udc0) +DT_ZEPHYR_UDC0_HS_SPEED := $(dt_node_str_prop_equals,$(DT_ZEPHYR_UDC0),maximum-speed,high-speed) + +config USB_NATIVE_POSIX_HS + bool "High speed support" + select USB_DC_HAS_HS_SUPPORT + depends on USB_NATIVE_POSIX + default y if "$(DT_ZEPHYR_UDC0_HS_SPEED)" + help + Enable high speed support in the Native Posix USB device controller driver. + module = USB_DRIVER module-str = usb driver source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/usb/device/usb_dc_it82xx2.c b/drivers/usb/device/usb_dc_it82xx2.c index e453144473c0bc..3cf17e7f08a831 100644 --- a/drivers/usb/device/usb_dc_it82xx2.c +++ b/drivers/usb/device/usb_dc_it82xx2.c @@ -82,7 +82,6 @@ enum it82xx2_transaction_types { /* ENDPOINT[3..0]_CONTROL_REG */ #define ENDPOINT_EN BIT(0) -#define ENDPOINT_RDY BIT(1) #define EP_SEND_STALL BIT(3) enum it82xx2_ep_status { @@ -195,8 +194,7 @@ static struct usb_it82xx2_regs *it82xx2_get_usb_regs(void) static void it82xx2_enable_sof_int(bool enable) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); usb_regs->dc_interrupt_status = DC_SOF_RECEIVED; if (enable) { @@ -257,12 +255,13 @@ static void it8xxx2_usb_dc_wuc_init(const struct device *dev) IRQ_CONNECT(IT8XXX2_WU90_IRQ, 0, it82xx2_wu90_isr, 0, 0); } -static int it82xx2_usb_fifo_ctrl(uint8_t ep) +static int it82xx2_usb_fifo_ctrl(const uint8_t ep, const bool clear) { - struct usb_it82xx2_regs *const usb_regs = (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); volatile uint8_t *ep_fifo_ctrl = usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl; uint8_t ep_idx = USB_EP_GET_IDX(ep); uint8_t fifon_ctrl = (ep_fifo_res[ep_idx % FIFO_NUM] - 1) * 2; + unsigned int key; int ret = 0; if (ep_idx == 0) { @@ -270,6 +269,13 @@ static int it82xx2_usb_fifo_ctrl(uint8_t ep) return -EINVAL; } + key = irq_lock(); + if (clear) { + ep_fifo_ctrl[fifon_ctrl] = 0x0; + ep_fifo_ctrl[fifon_ctrl + 1] = 0x0; + goto out; + } + if (USB_EP_DIR_IS_IN(ep) && udata0.ep_data[ep_idx].ep_status == EP_CONFIG_IN) { if (ep_idx < 8) { ep_fifo_ctrl[fifon_ctrl] = BIT(ep_idx); @@ -290,14 +296,15 @@ static int it82xx2_usb_fifo_ctrl(uint8_t ep) ret = -EINVAL; } +out: + irq_unlock(key); return ret; } static volatile void *it82xx2_get_ext_ctrl(int ep_idx, enum it82xx2_ep_ctrl ctrl) { uint8_t idx; - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); union epn0n1_extend_ctrl_reg *epn0n1_ext_ctrl = usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl; struct epn_ext_ctrl_regs *ext_ctrl = @@ -314,12 +321,14 @@ static volatile void *it82xx2_get_ext_ctrl(int ep_idx, enum it82xx2_ep_ctrl ctrl static int it82xx2_usb_extend_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enable) { - struct usb_it82xx2_regs *const usb_regs = (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); + struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct epn_ext_ctrl_regs *ext_ctrl = usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl; union epn_extend_ctrl1_reg *epn_ext_ctrl1 = NULL; union epn0n1_extend_ctrl_reg *epn0n1_ext_ctrl = NULL; uint8_t ep_idx = USB_EP_GET_IDX(ep); + uint8_t ep_fifo = (ep_idx > 0) ? (ep_fifo_res[ep_idx % FIFO_NUM]) : 0; if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) { return -EINVAL; @@ -408,10 +417,14 @@ static int it82xx2_usb_extend_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, boo } break; case EP_READY_ENABLE: + unsigned int key; int idx = ((ep_idx - 4) % 3) + 1; + key = irq_lock(); (enable) ? (ext_ctrl[idx].epn_ext_ctrl2 |= BIT((ep_idx - 4) / 3)) : (ext_ctrl[idx].epn_ext_ctrl2 &= ~BIT((ep_idx - 4) / 3)); + ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = enable; + irq_unlock(key); break; default: LOG_ERR("Unknown control type 0x%x", ctrl); @@ -423,8 +436,7 @@ static int it82xx2_usb_extend_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, boo static int it82xx2_usb_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enable) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; uint8_t ep_idx = USB_EP_GET_IDX(ep); @@ -448,7 +460,11 @@ static int it82xx2_usb_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enabl ep_regs[ep_idx].ep_ctrl.fields.enable_bit = enable; break; case EP_READY_ENABLE: + unsigned int key; + + key = irq_lock(); ep_regs[ep_idx].ep_ctrl.fields.ready_bit = enable; + irq_unlock(key); break; case EP_DATA_SEQ_1: ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit = enable; @@ -485,8 +501,7 @@ static int it82xx2_usb_set_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool e static int it82xx2_usb_dc_ip_init(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); /* Reset Device Controller */ usb_regs->host_device_control = RESET_CORE; @@ -524,8 +539,7 @@ static int it82xx2_usb_dc_attach_init(void) /* Check the condition that SETUP_TOKEN following OUT_TOKEN and return it */ static bool it82xx2_check_setup_following_out(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; @@ -536,8 +550,7 @@ static bool it82xx2_check_setup_following_out(void) static inline void it82xx2_handler_setup(uint8_t fifo_idx, uint8_t ep_ctrl) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; uint8_t ep_idx = fifo_idx; @@ -578,34 +591,19 @@ static inline void it82xx2_handler_setup(uint8_t fifo_idx, uint8_t ep_ctrl) /* Set ready bit to no-data control in */ if (udata0.no_data_ctrl) { - ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); udata0.no_data_ctrl = false; } } -static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl) +static inline void it82xx2_handler_in(const uint8_t ep_idx, const uint8_t ep_ctrl) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; - volatile struct epn_ext_ctrl_regs *epn_ext_ctrl = - usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl; - uint8_t ep_idx; - if (fifo_idx != 0) { - if (!udata0.fifo_ready[fifo_idx - 1]) { - return; - } - - ep_idx = (epn_ext_ctrl[fifo_idx].epn_ext_ctrl2 & COMPLETED_TRANS) >> 4; - if (ep_idx == 0 || udata0.ep_data[ep_idx].ep_status != EP_CONFIG_IN) { - return; - } - udata0.fifo_ready[fifo_idx - 1] = false; - } else { - ep_idx = 0; + if (ep_idx == 0) { if (ep_ctrl & EP_SEND_STALL) { - ep_regs[fifo_idx].ep_ctrl.fields.send_stall_bit = 0; + ep_regs[ep_idx].ep_ctrl.fields.send_stall_bit = 0; udata0.st_state = STALL_SEND; LOG_DBG("Clear Stall Bit"); return; @@ -644,36 +642,25 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl) udata0.ep_data[ep_idx].cb_in(ep_idx | USB_EP_DIR_IN, USB_DC_EP_DATA_IN); } - if (fifo_idx != 0) { - k_sem_give(&udata0.fifo_sem[fifo_idx - 1]); + if (ep_idx != 0) { + uint8_t ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM]; + + /* clear fifo ctrl registers when IN transaction is completed */ + it82xx2_usb_fifo_ctrl(ep_idx, true); + k_sem_give(&udata0.fifo_sem[ep_fifo - 1]); } else { if (udata0.st_state == DIN_ST && udata0.ep_data[ep_idx].remaining == 0) { - ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); } } } -static inline void it82xx2_handler_out(uint8_t fifo_idx) +static inline void it82xx2_handler_out(const uint8_t ep_idx) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; - volatile struct epn_ext_ctrl_regs *epn_ext_ctrl = - usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl; - uint8_t ep_idx; - - if (fifo_idx != 0) { - if (!udata0.fifo_ready[fifo_idx - 1]) { - return; - } - ep_idx = (epn_ext_ctrl[fifo_idx].epn_ext_ctrl2 & COMPLETED_TRANS) >> 4; - if (ep_idx == 0 || udata0.ep_data[ep_idx].ep_status != EP_CONFIG_OUT) { - return; - } - udata0.fifo_ready[fifo_idx - 1] = false; - } else { - ep_idx = 0; + if (ep_idx == 0) { /* ep0 wrong enter check */ if (udata0.st_state >= STATUS_ST) { return; @@ -695,45 +682,150 @@ static inline void it82xx2_handler_out(uint8_t fifo_idx) udata0.ep_data[ep_idx].cb_out(ep_idx, USB_DC_EP_DATA_OUT); } - if (fifo_idx == 0) { + if (ep_idx == 0) { /* SETUP_TOKEN follow OUT_TOKEN */ if (it82xx2_check_setup_following_out()) { udata0.last_token = udata0.now_token; udata0.now_token = SETUP_TOKEN; udata0.st_state = SETUP_ST; - ep_regs[fifo_idx].ep_ctrl.fields.outdata_sequence_bit = 1; + ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit = 1; udata0.ep_data[ep_idx].cb_out(ep_idx | USB_EP_DIR_OUT, USB_DC_EP_SETUP); if (udata0.no_data_ctrl) { - ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); udata0.no_data_ctrl = false; } } } } +static bool get_extend_enable_bit(const uint8_t ep_idx) +{ + union epn_extend_ctrl1_reg *epn_ext_ctrl1 = NULL; + bool enable; + + epn_ext_ctrl1 = (union epn_extend_ctrl1_reg *)it82xx2_get_ext_ctrl(ep_idx, EP_ENABLE); + if (((ep_idx - 4) / 3 == 0)) { + enable = (epn_ext_ctrl1->fields.epn0_enable_bit != 0); + } else if (((ep_idx - 4) / 3 == 1)) { + enable = (epn_ext_ctrl1->fields.epn3_enable_bit != 0); + } else if (((ep_idx - 4) / 3 == 2)) { + enable = (epn_ext_ctrl1->fields.epn6_enable_bit != 0); + } else { + enable = (epn_ext_ctrl1->fields.epn9_enable_bit != 0); + } + + return enable; +} + +static bool get_extend_ready_bit(const uint8_t ep_idx) +{ + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); + struct epn_ext_ctrl_regs *ext_ctrl = + usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl; + int idx = ((ep_idx - 4) % 3) + 1; + + return ((ext_ctrl[idx].epn_ext_ctrl2 & BIT((ep_idx - 4) / 3)) != 0); +} + +static uint16_t get_fifo_ctrl(const uint8_t fifo_idx) +{ + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); + volatile uint8_t *ep_fifo_ctrl = usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl; + uint8_t fifon_ctrl = (fifo_idx - 1) * 2; + + if (fifo_idx == 0) { + LOG_ERR("Invalid fifo_idx 0x%x", fifo_idx); + return 0; + } + + return (ep_fifo_ctrl[fifon_ctrl + 1] << 8 | ep_fifo_ctrl[fifon_ctrl]); +} + +static bool it82xx2_usb_fake_token(const uint8_t ep_idx, uint8_t *token_type) +{ + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); + struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; + bool is_fake = false; + bool enable_bit, ready_bit; + uint8_t ep_fifo = (ep_idx > 0) ? (ep_fifo_res[ep_idx % FIFO_NUM]) : 0; + + if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) { + enable_bit = get_extend_enable_bit(ep_idx); + ready_bit = get_extend_ready_bit(ep_idx); + } else { + enable_bit = (ep_regs[ep_idx].ep_ctrl.fields.enable_bit != 0); + ready_bit = (ep_regs[ep_idx].ep_ctrl.fields.ready_bit != 0); + } + + /* The enable bit is set and the ready bit is cleared if the + * transaction is completed. + */ + if (!enable_bit || ready_bit) { + return true; + } + + *token_type = ep_regs[ep_fifo].ep_transtype_sts & DC_ALL_TRANS; + + if (ep_idx == 0) { + return false; + } + + switch (*token_type) { + case DC_IN_TRANS: + if (get_fifo_ctrl(ep_fifo) != BIT(ep_idx) || + udata0.ep_data[ep_idx].ep_status != EP_CONFIG_IN) { + is_fake = true; + } + break; + case DC_OUTDATA_TRANS: + if (!udata0.fifo_ready[ep_fifo - 1] || + udata0.ep_data[ep_idx].ep_status != EP_CONFIG_OUT) { + is_fake = true; + } else { + udata0.fifo_ready[ep_fifo - 1] = false; + } + break; + case DC_SETUP_TRANS: + __fallthrough; + default: + is_fake = true; + break; + } + + return is_fake; +} + static void it82xx2_usb_dc_trans_done(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; + struct epn_ext_ctrl_regs *epn_ext_ctrl = + usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl; for (uint8_t fifo_idx = 0; fifo_idx < 4; fifo_idx++) { uint8_t ep_ctrl = ep_regs[fifo_idx].ep_ctrl.value; + uint8_t ep_idx, token_type; - /* check ready bit ,will be 0 when trans done */ - if ((ep_ctrl & ENDPOINT_EN) && !(ep_ctrl & ENDPOINT_RDY)) { - switch (ep_regs[fifo_idx].ep_transtype_sts & DC_ALL_TRANS) { + if (fifo_idx == 0) { + ep_idx = 0; + } else { + ep_idx = (epn_ext_ctrl[fifo_idx].epn_ext_ctrl2 & COMPLETED_TRANS) >> 4; + if (ep_idx == 0) { + continue; + } + } + + if (!it82xx2_usb_fake_token(ep_idx, &token_type)) { + switch (token_type) { case DC_SETUP_TRANS: - if (fifo_idx == 0) { - it82xx2_handler_setup(fifo_idx, ep_ctrl); - } + it82xx2_handler_setup(fifo_idx, ep_ctrl); break; case DC_IN_TRANS: - it82xx2_handler_in(fifo_idx, ep_ctrl); + it82xx2_handler_in(ep_idx, ep_ctrl); break; case DC_OUTDATA_TRANS: - it82xx2_handler_out(fifo_idx); + it82xx2_handler_out(ep_idx); break; default: break; @@ -744,8 +836,7 @@ static void it82xx2_usb_dc_trans_done(void) static void it82xx2_usb_dc_isr(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); uint8_t status = usb_regs->dc_interrupt_status & usb_regs->dc_interrupt_mask; /* mask non enable int */ @@ -782,8 +873,7 @@ static void suspended_check_handler(struct k_work *item) struct usb_it82xx2_data *udata = CONTAINER_OF(dwork, struct usb_it82xx2_data, check_suspended_work); - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); if (usb_regs->dc_interrupt_status & DC_SOF_RECEIVED) { usb_regs->dc_interrupt_status = DC_SOF_RECEIVED; @@ -818,8 +908,7 @@ static void suspended_check_handler(struct k_work *item) int usb_dc_attach(void) { int ret; - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); if (udata0.attached) { LOG_DBG("Already Attached"); @@ -867,8 +956,7 @@ int usb_dc_attach(void) int usb_dc_detach(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); if (!udata0.attached) { LOG_DBG("Already Detached"); @@ -887,8 +975,7 @@ int usb_dc_detach(void) int usb_dc_reset(void) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; @@ -1002,7 +1089,7 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg) udata0.ep_data[ep_idx].ep_status = EP_CONFIG_IN; } else { udata0.ep_data[ep_idx].ep_status = EP_CONFIG_OUT; - it82xx2_usb_fifo_ctrl(cfg->ep_addr); + it82xx2_usb_fifo_ctrl(cfg->ep_addr, false); } switch (cfg->ep_type) { @@ -1093,8 +1180,7 @@ int usb_dc_ep_disable(uint8_t ep) int usb_dc_ep_set_stall(const uint8_t ep) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; uint8_t ep_idx = USB_EP_GET_IDX(ep); @@ -1109,7 +1195,7 @@ int usb_dc_ep_set_stall(const uint8_t ep) if (ep_idx == 0) { uint32_t idx = 0; - ep_regs[ep_idx].ep_ctrl.fields.ready_bit = 1; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); /* polling if stall send for 3ms */ while (idx < 198 && !(ep_regs[ep_idx].ep_status & DC_STALL_SENT)) { @@ -1166,8 +1252,7 @@ int usb_dc_ep_halt(uint8_t ep) int usb_dc_ep_flush(uint8_t ep) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; uint8_t ep_idx = USB_EP_GET_IDX(ep); @@ -1189,11 +1274,9 @@ int usb_dc_ep_flush(uint8_t ep) int usb_dc_ep_write(uint8_t ep, const uint8_t *buf, uint32_t data_len, uint32_t *ret_bytes) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); - struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; - + unsigned int key; uint8_t ep_idx = USB_EP_GET_IDX(ep); uint8_t ep_fifo = (ep_idx > 0) ? (ep_fifo_res[ep_idx % FIFO_NUM]) : 0; @@ -1213,7 +1296,8 @@ int usb_dc_ep_write(uint8_t ep, const uint8_t *buf, } } else { k_sem_take(&udata0.fifo_sem[ep_fifo - 1], K_FOREVER); - it82xx2_usb_fifo_ctrl(ep); + key = irq_lock(); + it82xx2_usb_fifo_ctrl(ep, false); } if (data_len > udata0.ep_data[ep_idx].mps) { @@ -1238,14 +1322,9 @@ int usb_dc_ep_write(uint8_t ep, const uint8_t *buf, LOG_DBG("Write %d Packets to TX FIFO(%d)", data_len, ep_idx); } - if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) { - it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true); - } - - ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1; - - if (ep_fifo > EP0) { - udata0.fifo_ready[ep_fifo - 1] = true; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); + if (ep_idx != 0) { + irq_unlock(key); } LOG_DBG("Set EP%d Ready(%d)", ep_idx, __LINE__); @@ -1257,8 +1336,7 @@ int usb_dc_ep_write(uint8_t ep, const uint8_t *buf, int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len, uint32_t *read_bytes) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; @@ -1274,20 +1352,25 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len, LOG_WRN("fifo_%d error status: 0x%02x", ep_fifo, ep_regs[ep_fifo].ep_status); } - if (max_data_len == 0) { - - *read_bytes = 0; + rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb + + (((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8); - if (ep_idx > 0) { - ep_regs[ep_idx].ep_ctrl.fields.ready_bit = 1; + if (!buf && !max_data_len) { + /* + * When both buffer and max data to read are zero return + * the available data length in buffer. + */ + if (read_bytes) { + *read_bytes = rx_fifo_len; } + if (ep_idx > 0 && !rx_fifo_len) { + udata0.fifo_ready[ep_fifo - 1] = true; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); + } return 0; } - rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb + - (((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8); - if (ep_idx == 0) { /* Prevent wrong read_bytes cause memory error * if EP0 is in OUT status stage @@ -1331,11 +1414,8 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len, } if (ep_fifo > EP0) { - ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1; - if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) { - it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true); - } udata0.fifo_ready[ep_fifo - 1] = true; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); } else if (udata0.now_token == SETUP_TOKEN) { if (!(buf[0] & USB_EP_DIR_MASK)) { /* request type: host-to-device transfer direction */ @@ -1343,7 +1423,7 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len, if (buf[6] != 0 || buf[7] != 0) { /* set status IN after data OUT */ ep_regs[0].ep_ctrl.fields.outdata_sequence_bit = 1; - ep_regs[0].ep_ctrl.fields.ready_bit = 1; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); } else { /* no_data_ctrl status */ udata0.no_data_ctrl = true; @@ -1358,8 +1438,7 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len, int usb_dc_ep_read_wait(uint8_t ep, uint8_t *buf, uint32_t max_data_len, uint32_t *read_bytes) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs; @@ -1400,10 +1479,6 @@ int usb_dc_ep_read_wait(uint8_t ep, uint8_t *buf, uint32_t max_data_len, int usb_dc_ep_read_continue(uint8_t ep) { - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); - struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs; - uint8_t ep_idx = USB_EP_GET_IDX(ep); uint8_t ep_fifo = (ep_idx > 0) ? (ep_fifo_res[ep_idx % FIFO_NUM]) : 0; @@ -1417,11 +1492,8 @@ int usb_dc_ep_read_continue(uint8_t ep) return -EINVAL; } - if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) { - it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true); - } - ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1; udata0.fifo_ready[ep_fifo - 1] = true; + it82xx2_usb_set_ep_ctrl(ep_idx, EP_READY_ENABLE, true); LOG_DBG("EP(%d) Read Continue", ep_idx); return 0; } @@ -1447,8 +1519,7 @@ int usb_dc_ep_mps(const uint8_t ep) int usb_dc_wakeup_request(void) { int ret; - struct usb_it82xx2_regs *const usb_regs = - (struct usb_it82xx2_regs *)it82xx2_get_usb_regs(); + struct usb_it82xx2_regs *const usb_regs = it82xx2_get_usb_regs(); if (udata0.suspended) { diff --git a/drivers/usb/device/usb_dc_native_posix.c b/drivers/usb/device/usb_dc_native_posix.c index c74dad9b35debc..d806d3513ef67c 100644 --- a/drivers/usb/device/usb_dc_native_posix.c +++ b/drivers/usb/device/usb_dc_native_posix.c @@ -26,7 +26,11 @@ LOG_MODULE_REGISTER(native_posix); #define USBIP_IN_EP_NUM 8 #define USBIP_OUT_EP_NUM 8 +#ifdef CONFIG_USB_NATIVE_POSIX_HS +#define USBIP_MAX_PACKET_SIZE 512 +#else /* CONFIG_USB_NATIVE_POSIX_HS */ #define USBIP_MAX_PACKET_SIZE 64 +#endif /* !CONFIG_USB_NATIVE_POSIX_HS */ K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE); static struct k_thread thread; diff --git a/drivers/usb/device/usb_dc_native_posix_adapt.c b/drivers/usb/device/usb_dc_native_posix_adapt.c index f62b6242491bf4..14ede80fec0cf8 100644 --- a/drivers/usb/device/usb_dc_native_posix_adapt.c +++ b/drivers/usb/device/usb_dc_native_posix_adapt.c @@ -127,7 +127,11 @@ static void fill_device(struct devlist_device *dev, const uint8_t *desc) dev->busnum = htonl(1); dev->devnum = htonl(2); - dev->speed = htonl(2); + if (IS_ENABLED(CONFIG_USB_NATIVE_POSIX_HS)) { + dev->speed = htonl(3); + } else { + dev->speed = htonl(2); + } dev->idVendor = htons(dev_dsc->idVendor); dev->idProduct = htons(dev_dsc->idProduct); diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 98ded9e4b5de24..e97001ca9c352b 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -469,7 +469,10 @@ static int dwc2_handle_evt_setup(const struct device *dev) /* Allocate and feed buffer for data OUT stage */ LOG_DBG("s:%p|feed for -out-", buf); - err = dwc2_ctrl_feed_dout(dev, udc_data_stage_length(buf)); + /* Allocate at least 8 bytes in case the host decides to send + * SETUP DATA instead of OUT DATA packet. + */ + err = dwc2_ctrl_feed_dout(dev, MAX(udc_data_stage_length(buf), 8)); if (err == -ENOMEM) { err = udc_submit_ep_event(dev, buf, err); } @@ -1176,7 +1179,8 @@ static int dwc2_unset_dedicated_fifo(const struct device *dev, return 0; } -static void dwc2_wait_for_bit(mem_addr_t addr, uint32_t bit) +static void dwc2_wait_for_bit(const struct device *dev, + mem_addr_t addr, uint32_t bit) { k_timepoint_t timeout = sys_timepoint_calc(K_MSEC(100)); @@ -1187,6 +1191,13 @@ static void dwc2_wait_for_bit(mem_addr_t addr, uint32_t bit) * Busy looping is most likely fine unless profiling shows otherwise. */ while (!(sys_read32(addr) & bit)) { + if (dwc2_quirk_is_phy_clk_off(dev)) { + /* No point in waiting, because the bit can only be set + * when the PHY is actively clocked. + */ + return; + } + if (sys_timepoint_expired(timeout)) { LOG_ERR("Timeout waiting for bit 0x%08X at 0x%08X", bit, (uint32_t)addr); @@ -1241,7 +1252,7 @@ static void udc_dwc2_ep_disable(const struct device *dev, dctl &= ~USB_DWC2_DCTL_SGOUTNAK; } - dwc2_wait_for_bit(gintsts_reg, USB_DWC2_GINTSTS_GOUTNAKEFF); + dwc2_wait_for_bit(dev, gintsts_reg, USB_DWC2_GINTSTS_GOUTNAKEFF); /* The application cannot disable control OUT endpoint 0. */ if (ep_idx != 0) { @@ -1257,7 +1268,7 @@ static void udc_dwc2_ep_disable(const struct device *dev, sys_write32(dxepctl, dxepctl_reg); if (ep_idx != 0) { - dwc2_wait_for_bit(doepint_reg, USB_DWC2_DOEPINT_EPDISBLD); + dwc2_wait_for_bit(dev, doepint_reg, USB_DWC2_DOEPINT_EPDISBLD); } /* Clear Endpoint Disabled interrupt */ @@ -1277,12 +1288,12 @@ static void udc_dwc2_ep_disable(const struct device *dev, } sys_write32(dxepctl, dxepctl_reg); - dwc2_wait_for_bit(diepint_reg, USB_DWC2_DIEPINT_INEPNAKEFF); + dwc2_wait_for_bit(dev, diepint_reg, USB_DWC2_DIEPINT_INEPNAKEFF); dxepctl |= USB_DWC2_DEPCTL_EPENA | USB_DWC2_DEPCTL_EPDIS; sys_write32(dxepctl, dxepctl_reg); - dwc2_wait_for_bit(diepint_reg, USB_DWC2_DIEPINT_EPDISBLD); + dwc2_wait_for_bit(dev, diepint_reg, USB_DWC2_DIEPINT_EPDISBLD); /* Clear Endpoint Disabled interrupt */ sys_write32(USB_DWC2_DIEPINT_EPDISBLD, diepint_reg); @@ -1331,6 +1342,15 @@ static int udc_dwc2_ep_deactivate(const struct device *dev, sys_write32(dxepctl, dxepctl_reg); dwc2_set_epint(dev, cfg, false); + if (cfg->addr == USB_CONTROL_EP_OUT) { + struct net_buf *buf = udc_buf_get_all(dev, cfg->addr); + + /* Release the buffer allocated in dwc2_ctrl_feed_dout() */ + if (buf) { + net_buf_unref(buf); + } + } + return 0; } diff --git a/drivers/usb/udc/udc_dwc2.h b/drivers/usb/udc/udc_dwc2.h index b54cb82fd2a712..07cd71bcb9c858 100644 --- a/drivers/usb/udc/udc_dwc2.h +++ b/drivers/usb/udc/udc_dwc2.h @@ -28,6 +28,8 @@ struct dwc2_vendor_quirks { int (*irq_clear)(const struct device *dev); /* Called on driver pre-init */ int (*caps)(const struct device *dev); + /* Called while waiting for bits that require PHY to be clocked */ + int (*is_phy_clk_off)(const struct device *dev); }; /* Driver configuration per instance */ @@ -69,5 +71,6 @@ DWC2_QUIRK_FUNC_DEFINE(disable) DWC2_QUIRK_FUNC_DEFINE(shutdown) DWC2_QUIRK_FUNC_DEFINE(irq_clear) DWC2_QUIRK_FUNC_DEFINE(caps) +DWC2_QUIRK_FUNC_DEFINE(is_phy_clk_off) #endif /* ZEPHYR_DRIVERS_USB_UDC_DWC2_H */ diff --git a/drivers/usb/udc/udc_dwc2_vendor_quirks.h b/drivers/usb/udc/udc_dwc2_vendor_quirks.h index 2311dd803086af..57ff4c4de04414 100644 --- a/drivers/usb/udc/udc_dwc2_vendor_quirks.h +++ b/drivers/usb/udc/udc_dwc2_vendor_quirks.h @@ -244,6 +244,11 @@ static inline int usbhs_init_caps(const struct device *dev) return 0; } +static inline int usbhs_is_phy_clk_off(const struct device *dev) +{ + return !k_event_test(&usbhs_events, USBHS_VBUS_READY); +} + #define QUIRK_NRF_USBHS_DEFINE(n) \ struct dwc2_vendor_quirks dwc2_vendor_quirks_##n = { \ .init = usbhs_enable_nrfs_service, \ @@ -252,6 +257,7 @@ static inline int usbhs_init_caps(const struct device *dev) .shutdown = usbhs_disable_nrfs_service, \ .irq_clear = usbhs_irq_clear, \ .caps = usbhs_init_caps, \ + .is_phy_clk_off = usbhs_is_phy_clk_off, \ }; DT_INST_FOREACH_STATUS_OKAY(QUIRK_NRF_USBHS_DEFINE) diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index e86893b1b18f89..157902a1216404 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -353,6 +353,16 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) } } +#if DT_INST_NODE_HAS_PROP(0, disconnect_gpios) +void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) +{ + struct gpio_dt_spec usb_disconnect = GPIO_DT_SPEC_INST_GET(0, disconnect_gpios); + + gpio_pin_configure_dt(&usb_disconnect, + state ? GPIO_OUTPUT_ACTIVE : GPIO_OUTPUT_INACTIVE); +} +#endif + static void udc_stm32_irq(const struct device *dev) { const struct udc_stm32_data *priv = udc_get_private(dev); diff --git a/drivers/video/CMakeLists.txt b/drivers/video/CMakeLists.txt index 19ad0e2bc797ee..2e52d1f66ea889 100644 --- a/drivers/video/CMakeLists.txt +++ b/drivers/video/CMakeLists.txt @@ -12,3 +12,4 @@ zephyr_library_sources_ifdef(CONFIG_VIDEO_OV7725 ov7725.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_OV2640 ov2640.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_STM32_DCMI video_stm32_dcmi.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_OV5640 ov5640.c) +zephyr_library_sources_ifdef(CONFIG_VIDEO_OV7670 ov7670.c) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 787311622e0cc9..d6a6bd3ccce669 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -47,4 +47,6 @@ source "drivers/video/Kconfig.stm32_dcmi" source "drivers/video/Kconfig.ov5640" +source "drivers/video/Kconfig.ov7670" + endif # VIDEO diff --git a/drivers/video/Kconfig.ov7670 b/drivers/video/Kconfig.ov7670 new file mode 100644 index 00000000000000..9a2a1d70f3d90c --- /dev/null +++ b/drivers/video/Kconfig.ov7670 @@ -0,0 +1,10 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config VIDEO_OV7670 + bool "OV7670 CMOS digital image sensor" + select I2C + depends on DT_HAS_OVTI_OV7670_ENABLED + default y + help + Enable driver for OV7670 CMOS digital image sensor device. diff --git a/drivers/video/ov7670.c b/drivers/video/ov7670.c new file mode 100644 index 00000000000000..96cb3f860db1f1 --- /dev/null +++ b/drivers/video/ov7670.c @@ -0,0 +1,488 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ovti_ov7670 + +#include +#include +#include + +#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#include +LOG_MODULE_REGISTER(ov7670); + +/* Initialization register structure */ +struct ov7670_reg { + uint8_t reg; + uint8_t cmd; +}; + +struct ov7670_config { + struct i2c_dt_spec bus; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + struct gpio_dt_spec reset; +#endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios) + struct gpio_dt_spec pwdn; +#endif +}; + +struct ov7670_data { + struct video_format fmt; +}; + +/* OV7670 registers */ +#define OV7670_PID 0x0A +#define OV7670_COM7 0x12 +#define OV7670_MVFP 0x1E +#define OV7670_COM10 0x15 +#define OV7670_COM12 0x3C +#define OV7670_BRIGHT 0x55 +#define OV7670_CLKRC 0x11 +#define OV7670_SCALING_PCLK_DIV 0x73 +#define OV7670_COM14 0x3E +#define OV7670_DBLV 0x6B +#define OV7670_SCALING_XSC 0x70 +#define OV7670_SCALING_YSC 0x71 +#define OV7670_COM2 0x09 +#define OV7670_SCALING_PCLK_DELAY 0xA2 +#define OV7670_BD50MAX 0xA5 +#define OV7670_BD60MAX 0xAB +#define OV7670_HAECC7 0xAA +#define OV7670_COM3 0x0C +#define OV7670_COM4 0x0D +#define OV7670_COM6 0x0F +#define OV7670_COM11 0x3B +#define OV7670_EDGE 0x3F +#define OV7670_DNSTH 0x4C +#define OV7670_DM_LNL 0x92 +#define OV7670_DM_LNH 0x93 +#define OV7670_COM15 0x40 +#define OV7670_TSLB 0x3A +#define OV7670_COM13 0x3D +#define OV7670_MANU 0x67 +#define OV7670_MANV 0x68 +#define OV7670_HSTART 0x17 +#define OV7670_HSTOP 0x18 +#define OV7670_VSTRT 0x19 +#define OV7670_VSTOP 0x1A +#define OV7670_HREF 0x32 +#define OV7670_VREF 0x03 +#define OV7670_SCALING_DCWCTR 0x72 +#define OV7670_GAIN 0x00 +#define OV7670_AECHH 0x07 +#define OV7670_AECH 0x10 +#define OV7670_COM8 0x13 +#define OV7670_COM9 0x14 +#define OV7670_AEW 0x24 +#define OV7670_AEB 0x25 +#define OV7670_VPT 0x26 +#define OV7670_AWBC1 0x43 +#define OV7670_AWBC2 0x44 +#define OV7670_AWBC3 0x45 +#define OV7670_AWBC4 0x46 +#define OV7670_AWBC5 0x47 +#define OV7670_AWBC6 0x48 +#define OV7670_MTX1 0x4F +#define OV7670_MTX2 0x50 +#define OV7670_MTX3 0x51 +#define OV7670_MTX4 0x52 +#define OV7670_MTX5 0x53 +#define OV7670_MTX6 0x54 +#define OV7670_LCC1 0x62 +#define OV7670_LCC2 0x63 +#define OV7670_LCC3 0x64 +#define OV7670_LCC4 0x65 +#define OV7670_LCC5 0x66 +#define OV7670_LCC6 0x94 +#define OV7670_LCC7 0x95 +#define OV7670_SLOP 0x7A +#define OV7670_GAM1 0x7B +#define OV7670_GAM2 0x7C +#define OV7670_GAM3 0x7D +#define OV7670_GAM4 0x7E +#define OV7670_GAM5 0x7F +#define OV7670_GAM6 0x80 +#define OV7670_GAM7 0x81 +#define OV7670_GAM8 0x82 +#define OV7670_GAM9 0x83 +#define OV7670_GAM10 0x84 +#define OV7670_GAM11 0x85 +#define OV7670_GAM12 0x86 +#define OV7670_GAM13 0x87 +#define OV7670_GAM14 0x88 +#define OV7670_GAM15 0x89 +#define OV7670_HAECC1 0x9F +#define OV7670_HAECC2 0xA0 +#define OV7670_HSYEN 0x31 +#define OV7670_HAECC3 0xA6 +#define OV7670_HAECC4 0xA7 +#define OV7670_HAECC5 0xA8 +#define OV7670_HAECC6 0xA9 + +/* OV7670 definitions */ +#define OV7670_PROD_ID 0x76 + +#define OV7670_VIDEO_FORMAT_CAP(width, height, format) \ + { \ + .pixelformat = (format), .width_min = (width), .width_max = (width), \ + .height_min = (height), .height_max = (height), .width_step = 0, .height_step = 0 \ + } + +static const struct video_format_cap fmts[] = { + OV7670_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_RGB565), /* QCIF */ + OV7670_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), /* QVGA */ + OV7670_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_RGB565), /* CIF */ + OV7670_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), /* VGA */ + OV7670_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_YUYV), /* QCIF */ + OV7670_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_YUYV), /* QVGA */ + OV7670_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_YUYV), /* CIF */ + OV7670_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_YUYV), /* VGA */ + {0}}; + +/* This initialization table is based on the MCUX SDK driver for the OV7670 */ +static const struct ov7670_reg ov7670_init_regtbl[] = { + {OV7670_MVFP, 0x20}, /* MVFP: Mirror/VFlip,Normal image */ + + /* configure the output timing */ + /* PCLK does not toggle during horizontal blank, one PCLK, one pixel */ + {OV7670_COM10, 0x20}, /* COM10 */ + {OV7670_COM12, 0x00}, /* COM12,No HREF when VSYNC is low */ + /* Brightness Control, with signal -128 to +128, 0x00 is middle value */ + {OV7670_BRIGHT, 0x2f}, + + /* Internal clock pre-scalar,F(internal clock) = F(input clock)/(Bit[5:0]+1) */ + {OV7670_CLKRC, 0x81}, /* Clock Div, Input/(n+1), bit6 set to 1 to disable divider */ + + /* SCALING_PCLK_DIV, */ + {OV7670_SCALING_PCLK_DIV, 0x00}, /* 0: Enable clock divider,010: Divided by 4 */ + /* Common Control 14,Bit[4]: DCW and scaling PCLK enable,Bit[3]: Manual scaling */ + {OV7670_COM14, 0x00}, + + /* DBLV,Bit[7:6]: PLL control */ + /* 0:Bypass PLL.,40: Input clock x4 , 80: Input clock x6 ,C0: Input clock x8 */ + {OV7670_DBLV, 0x40}, + + /* test pattern, useful in some case */ + {OV7670_SCALING_XSC, 0x0}, + {OV7670_SCALING_YSC, 0}, + + /* Output Drive Capability */ + {OV7670_COM2, 0x00}, /* Common Control 2, Output Drive Capability: 1x */ + {OV7670_SCALING_PCLK_DELAY, 0x02}, + {OV7670_BD50MAX, 0x05}, + {OV7670_BD60MAX, 0x07}, + {OV7670_HAECC7, 0x94}, + + {OV7670_COM3, 0x00}, + {OV7670_COM4, 0x00}, + {OV7670_COM6, 0x4b}, + {OV7670_COM11, 0x9F}, /* Night mode */ + {OV7670_EDGE, 0x04}, /* Edge Enhancement Adjustment */ + {OV7670_DNSTH, 0x00}, /* De-noise Strength */ + + {OV7670_DM_LNL, 0x00}, + {OV7670_DM_LNH, 0x00}, + + /* reserved */ + {0x16, 0x02}, + {0x21, 0x02}, + {0x22, 0x91}, + {0x29, 0x07}, + {0x35, 0x0b}, + {0x33, 0x0b}, + {0x37, 0x1d}, + {0x38, 0x71}, + {0x39, 0x2a}, + {0x0e, 0x61}, + {0x56, 0x40}, + {0x57, 0x80}, + {0x69, 0x00}, + {0x74, 0x19}, + + /* display , need retain */ + {OV7670_COM15, 0xD0}, /* Common Control 15 */ + {OV7670_TSLB, 0x0C}, /* Line Buffer Test Option */ + {OV7670_COM13, 0x80}, /* Common Control 13 */ + {OV7670_MANU, 0x11}, /* Manual U Value */ + {OV7670_MANV, 0xFF}, /* Manual V Value */ + /* config the output window data, this can be configed later */ + {OV7670_HSTART, 0x16}, /* HSTART */ + {OV7670_HSTOP, 0x04}, /* HSTOP */ + {OV7670_VSTRT, 0x02}, /* VSTRT */ + {OV7670_VSTOP, 0x7a}, /* VSTOP */ + {OV7670_HREF, 0x80}, /* HREF */ + {OV7670_VREF, 0x0a}, /* VREF */ + + /* DCW Control, */ + {OV7670_SCALING_DCWCTR, 0x11}, + + /* AGC/AEC - Automatic Gain Control/Automatic exposure Control */ + {OV7670_GAIN, 0x00}, /* AGC */ + {OV7670_AECHH, 0x3F}, /* Exposure Value */ + {OV7670_AECH, 0xFF}, + {OV7670_COM8, 0x66}, + {OV7670_COM9, 0x21}, /* limit the max gain */ + {OV7670_AEW, 0x75}, + {OV7670_AEB, 0x63}, + {OV7670_VPT, 0xA5}, + /* Automatic white balance control */ + {OV7670_AWBC1, 0x14}, + {OV7670_AWBC2, 0xf0}, + {OV7670_AWBC3, 0x34}, + {OV7670_AWBC4, 0x58}, + {OV7670_AWBC5, 0x28}, + {OV7670_AWBC6, 0x3a}, + /* Matrix Coefficient */ + {OV7670_MTX1, 0x80}, + {OV7670_MTX2, 0x80}, + {OV7670_MTX3, 0x00}, + {OV7670_MTX4, 0x22}, + {OV7670_MTX5, 0x5e}, + {OV7670_MTX6, 0x80}, + /* AWB Control */ + {0x59, 0x88}, + {0x5a, 0x88}, + {0x5b, 0x44}, + {0x5c, 0x67}, + {0x5d, 0x49}, + {0x5e, 0x0e}, + {0x6c, 0x0a}, + {0x6d, 0x55}, + {0x6e, 0x11}, + {0x6f, 0x9f}, + /* Lens Correction Option */ + {OV7670_LCC1, 0x00}, + {OV7670_LCC2, 0x00}, + {OV7670_LCC3, 0x04}, + {OV7670_LCC4, 0x20}, + {OV7670_LCC5, 0x05}, + {OV7670_LCC6, 0x04}, /* effective only when LCC5[2] is high */ + {OV7670_LCC7, 0x08}, /* effective only when LCC5[2] is high */ + /* Gamma Curve, needn't config */ + {OV7670_SLOP, 0x20}, + {OV7670_GAM1, 0x1c}, + {OV7670_GAM2, 0x28}, + {OV7670_GAM3, 0x3c}, + {OV7670_GAM4, 0x55}, + {OV7670_GAM5, 0x68}, + {OV7670_GAM6, 0x76}, + {OV7670_GAM7, 0x80}, + {OV7670_GAM8, 0x88}, + {OV7670_GAM9, 0x8f}, + {OV7670_GAM10, 0x96}, + {OV7670_GAM11, 0xa3}, + {OV7670_GAM12, 0xaf}, + {OV7670_GAM13, 0xc4}, + {OV7670_GAM14, 0xd7}, + {OV7670_GAM15, 0xe8}, + /* Histogram-based AEC/AGC Control */ + {OV7670_HAECC1, 0x78}, + {OV7670_HAECC2, 0x68}, + {OV7670_HSYEN, 0xff}, + {0xa1, 0x03}, + {OV7670_HAECC3, 0xdf}, + {OV7670_HAECC4, 0xdf}, + {OV7670_HAECC5, 0xf0}, + {OV7670_HAECC6, 0x90}, + /* Automatic black Level Compensation */ + {0xb0, 0x84}, + {0xb1, 0x0c}, + {0xb2, 0x0e}, + {0xb3, 0x82}, + {0xb8, 0x0a}, +}; + +static int ov7670_get_caps(const struct device *dev, enum video_endpoint_id ep, + struct video_caps *caps) +{ + caps->format_caps = fmts; + return 0; +} + +static int ov7670_set_fmt(const struct device *dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + const struct ov7670_config *config = dev->config; + struct ov7670_data *data = dev->data; + uint8_t com7 = 0U; + uint8_t i = 0U; + + if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565 && fmt->pixelformat != VIDEO_PIX_FMT_YUYV) { + LOG_ERR("Only RGB565 and YUYV supported!"); + return -ENOTSUP; + } + + if (!memcmp(&data->fmt, fmt, sizeof(data->fmt))) { + /* nothing to do */ + return 0; + } + + memcpy(&data->fmt, fmt, sizeof(data->fmt)); + + if (fmt->pixelformat == VIDEO_PIX_FMT_RGB565) { + com7 |= 0x4; + } + + /* Set output resolution */ + while (fmts[i].pixelformat) { + if (fmts[i].width_min == fmt->width && fmts[i].height_min == fmt->height && + fmts[i].pixelformat == fmt->pixelformat) { + /* Set output format */ + switch (fmts[i].width_min) { + case 176: /* QCIF */ + com7 |= BIT(3); + break; + case 320: /* QVGA */ + com7 |= BIT(4); + break; + case 352: /* CIF */ + com7 |= BIT(5); + break; + default: /* VGA */ + break; + } + /* Program COM7 to set format */ + return i2c_reg_write_byte_dt(&config->bus, OV7670_COM7, com7); + } + i++; + } + LOG_ERR("Unsupported format"); + return -ENOTSUP; +} + +static int ov7670_get_fmt(const struct device *dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + struct ov7670_data *data = dev->data; + + if (fmt == NULL) { + return -EINVAL; + } + memcpy(fmt, &data->fmt, sizeof(data->fmt)); + return 0; +} + +static int ov7670_init(const struct device *dev) +{ + const struct ov7670_config *config = dev->config; + int ret, i; + uint8_t pid; + struct video_format fmt; + const struct ov7670_reg *reg; + + if (!i2c_is_ready_dt(&config->bus)) { + /* I2C device is not ready, return */ + return -ENODEV; + } + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios) + /* Power up camera module */ + if (config->pwdn.port != NULL) { + if (!gpio_is_ready_dt(&config->pwdn)) { + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->pwdn, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Could not clear power down pin: %d", ret); + return ret; + } + } +#endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + /* Reset camera module */ + if (config->reset.port != NULL) { + if (!gpio_is_ready_dt(&config->reset)) { + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Could not set reset pin: %d", ret); + return ret; + } + /* Reset is active low, has 1ms settling time*/ + gpio_pin_set_dt(&config->reset, 0); + k_msleep(1); + gpio_pin_set_dt(&config->reset, 1); + k_msleep(1); + } +#endif + + /* + * Read product ID from camera. This camera implements the SCCB, + * spec- which *should* be I2C compatible, but in practice does + * not seem to respond when I2C repeated start commands are used. + * To work around this, use a write then a read to interface with + * registers. + */ + uint8_t cmd = OV7670_PID; + + ret = i2c_write_dt(&config->bus, &cmd, sizeof(cmd)); + if (ret < 0) { + LOG_ERR("Could not request product ID: %d", ret); + return ret; + } + ret = i2c_read_dt(&config->bus, &pid, sizeof(pid)); + if (ret < 0) { + LOG_ERR("Could not read product ID: %d", ret); + return ret; + } + + if (pid != OV7670_PROD_ID) { + LOG_ERR("Incorrect product ID: 0x%02X", pid); + return -ENODEV; + } + + /* Set default camera format (QVGA, YUYV) */ + fmt.pixelformat = VIDEO_PIX_FMT_YUYV; + fmt.width = 640; + fmt.height = 480; + fmt.pitch = fmt.width * 2; + ret = ov7670_set_fmt(dev, VIDEO_EP_OUT, &fmt); + if (ret < 0) { + return ret; + } + + /* Write initialization values to OV7670 */ + for (i = 0; i < ARRAY_SIZE(ov7670_init_regtbl); i++) { + reg = &ov7670_init_regtbl[i]; + ret = i2c_reg_write_byte_dt(&config->bus, reg->reg, reg->cmd); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +static const struct video_driver_api ov7670_api = { + .set_format = ov7670_set_fmt, + .get_format = ov7670_get_fmt, + .get_caps = ov7670_get_caps, +}; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define OV7670_RESET_GPIO(inst) .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}), +#else +#define OV7670_RESET_GPIO(inst) +#endif + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios) +#define OV7670_PWDN_GPIO(inst) .pwdn = GPIO_DT_SPEC_INST_GET_OR(inst, pwdn_gpios, {}), +#else +#define OV7670_PWDN_GPIO(inst) +#endif + +#define OV7670_INIT(inst) \ + const struct ov7670_config ov7670_config_##inst = {.bus = I2C_DT_SPEC_INST_GET(inst), \ + OV7670_RESET_GPIO(inst) \ + OV7670_PWDN_GPIO(inst)}; \ + struct ov7670_data ov7670_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \ + POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); + +DT_INST_FOREACH_STATUS_OKAY(OV7670_INIT) diff --git a/drivers/virtualization/virt_ivshmem.c b/drivers/virtualization/virt_ivshmem.c index f620ab473f9e06..bce1dd4c42885b 100644 --- a/drivers/virtualization/virt_ivshmem.c +++ b/drivers/virtualization/virt_ivshmem.c @@ -219,9 +219,9 @@ static bool ivshmem_configure(const struct device *dev) LOG_ERR("Invalid state table size %zu", state_table_size); return false; } - z_phys_map((uint8_t **)&data->state_table_shmem, - shmem_phys_addr, state_table_size, - K_MEM_CACHE_WB | K_MEM_PERM_USER); + k_mem_map_phys_bare((uint8_t **)&data->state_table_shmem, + shmem_phys_addr, state_table_size, + K_MEM_CACHE_WB | K_MEM_PERM_USER); /* R/W section (optional) */ cap_pos = vendor_cap + IVSHMEM_CFG_RW_SECTION_SZ / 4; @@ -229,9 +229,10 @@ static bool ivshmem_configure(const struct device *dev) size_t rw_section_offset = state_table_size; LOG_INF("RW section size 0x%zX", data->rw_section_size); if (data->rw_section_size > 0) { - z_phys_map((uint8_t **)&data->rw_section_shmem, - shmem_phys_addr + rw_section_offset, data->rw_section_size, - K_MEM_CACHE_WB | K_MEM_PERM_RW | K_MEM_PERM_USER); + k_mem_map_phys_bare((uint8_t **)&data->rw_section_shmem, + shmem_phys_addr + rw_section_offset, + data->rw_section_size, + K_MEM_CACHE_WB | K_MEM_PERM_RW | K_MEM_PERM_USER); } /* Output sections */ @@ -249,8 +250,8 @@ static bool ivshmem_configure(const struct device *dev) if (i == regs->id) { flags |= K_MEM_PERM_RW; } - z_phys_map((uint8_t **)&data->output_section_shmem[i], - phys_addr, data->output_section_size, flags); + k_mem_map_phys_bare((uint8_t **)&data->output_section_shmem[i], + phys_addr, data->output_section_size, flags); } data->size = output_section_offset + @@ -273,9 +274,9 @@ static bool ivshmem_configure(const struct device *dev) data->size = mbar_shmem.size; - z_phys_map((uint8_t **)&data->shmem, - shmem_phys_addr, data->size, - K_MEM_CACHE_WB | K_MEM_PERM_RW | K_MEM_PERM_USER); + k_mem_map_phys_bare((uint8_t **)&data->shmem, + shmem_phys_addr, data->size, + K_MEM_CACHE_WB | K_MEM_PERM_RW | K_MEM_PERM_USER); } if (msi_x_bar_present) { diff --git a/drivers/watchdog/wdt_andes_atcwdt200.c b/drivers/watchdog/wdt_andes_atcwdt200.c index 5fca002680502c..899f2cfac51b38 100644 --- a/drivers/watchdog/wdt_andes_atcwdt200.c +++ b/drivers/watchdog/wdt_andes_atcwdt200.c @@ -332,14 +332,14 @@ static int wdt_atcwdt200_init(const struct device *dev) ret = syscon_write_reg(syscon_dev, SMU_RESET_REGLO, ((uint32_t)((unsigned long) - Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY)))); + K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY)))); if (ret < 0) { return -EINVAL; } ret = syscon_write_reg(syscon_dev, SMU_RESET_REGHI, ((uint32_t)((uint64_t)((unsigned long) - Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY)) >> 32))); + K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY)) >> 32))); if (ret < 0) { return -EINVAL; } diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc index a3eac53862d54c..319253378d3181 100644 --- a/drivers/wifi/infineon/Kconfig.airoc +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -116,11 +116,11 @@ choice CYW4373_MODULE config CYW4373_STERLING_LWB5PLUS bool "STERLING-LWB5plus" help - Laird Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board + Ezurio Sterling LWB5+ 802.11ac / Bluetooth 5.0 M.2 Carrier Board (E-Type Key w/ SDIO/UART) Detailed information about Type Sterling LWB5+ module you can find on - https://www.lairdconnect.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module + https://www.ezurio.com/wireless-modules/wifi-modules-bluetooth/sterling-lwb5-plus-wifi-5-bluetooth-5-module endchoice choice CYW43439_MODULE diff --git a/drivers/wifi/simplelink/Kconfig.simplelink b/drivers/wifi/simplelink/Kconfig.simplelink index f2c5ccacbab310..c325a50f2cd4e2 100644 --- a/drivers/wifi/simplelink/Kconfig.simplelink +++ b/drivers/wifi/simplelink/Kconfig.simplelink @@ -9,6 +9,7 @@ menuconfig WIFI_SIMPLELINK select WIFI_OFFLOAD select NET_L2_WIFI_MGMT select FDTABLE + select POSIX_SEMAPHORES if WIFI_SIMPLELINK diff --git a/dts/arm/adi/max32/max32655-pinctrl.dtsi b/dts/arm/adi/max32/max32655-pinctrl.dtsi new file mode 100644 index 00000000000000..c336e402afcc76 --- /dev/null +++ b/dts/arm/adi/max32/max32655-pinctrl.dtsi @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2023-2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + pinctrl: pin-controller@40008000 { + + /omit-if-no-ref/ uart0a_rx_p0_0: uart0a_rx_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0a_tx_p0_1: uart0a_tx_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0a_ioa_p0_2: tmr0a_ioa_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0b_cts_p0_2: uart0b_cts_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ ext_clk_p0_3: ext_clk_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0b_rts_p0_3: uart0b_rts_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss0_p0_4: spi0_ss0_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioan_p0_4: tmr0b_ioan_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_mosi_p0_5: spi0_mosi_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iobn_p0_5: tmr0b_iobn_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_miso_p0_6: spi0_miso_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p0_6: owm_io_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sck_p0_7: spi0_sck_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pe_p0_7: owm_pe_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sdio2_p0_8: spi0_sdio2_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioa_p0_8: tmr0b_ioa_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sdio3_p0_9: spi0_sdio3_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iob_p0_9: tmr0b_iob_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_scl_p0_10: i2c0_scl_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss2_p0_10: spi0_ss2_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_sda_p0_11: i2c0_sda_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss1_p0_11: spi0_ss1_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1a_rx_p0_12: uart1a_rx_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_ioan_p0_12: tmr1b_ioan_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1a_tx_p0_13: uart1a_tx_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_iobn_p0_13: tmr1b_iobn_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_ioa_p0_14: tmr1a_ioa_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1b_cts_p0_14: uart1b_cts_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_iob_p0_15: tmr1a_iob_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1b_rts_p0_15: uart1b_rts_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_scl_p0_16: i2c1_scl_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ pt2_p0_16: pt2_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_sda_p0_17: i2c1_sda_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ pt3_p0_17: pt3_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ pt0_p0_18: pt0_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p0_18: owm_io_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ pt1_p0_19: pt1_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pe_p0_19: owm_pe_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss0_p0_20: spi1_ss0_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_ioa_p0_20: tmr1b_ioa_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_mosi_p0_21: spi1_mosi_p0_21 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_iob_p0_21: tmr1b_iob_p0_21 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_miso_p0_22: spi1_miso_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_ioan_p0_22: tmr1b_ioan_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sck_p0_23: spi1_sck_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_iobn_p0_23: tmr1b_iobn_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sdio2_p0_24: spi1_sdio2_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2b_ioa_p0_24: tmr2b_ioa_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sdio3_p0_25: spi1_sdio3_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2b_iob_p0_25: tmr2b_iob_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2a_ioa_p0_26: tmr2a_ioa_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss1_p0_26: spi1_ss1_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2a_iob_p0_27: tmr2a_iob_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss2_p0_27: spi1_ss2_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ swdio_p0_28: swdio_p0_28 { + pinmux = ; + }; + + /omit-if-no-ref/ swclk_p0_29: swclk_p0_29 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c2_scl_p0_30: i2c2_scl_p0_30 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2b_cts_p0_30: uart2b_cts_p0_30 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c2_sda_p0_31: i2c2_sda_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2b_rts_p0_31: uart2b_rts_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2a_rx_p1_0: uart2a_rx_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tck_p1_0: rv_tck_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2a_tx_p1_1: uart2a_tx_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tms_p1_1: rv_tms_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sck_p1_2: i2s_sck_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdi_p1_2: rv_tdi_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_ws_p1_3: i2s_ws_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdo_p1_3: rv_tdo_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sdi_p1_4: i2s_sdi_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_ioa_p1_4: tmr3b_ioa_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sdo_p1_5: i2s_sdo_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_iob_p1_5: tmr3b_iob_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_ioa_p1_6: tmr3a_ioa_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctrl2_p1_6: ble_ant_ctrl2_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_iob_p1_7: tmr3a_iob_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctrl3_p1_7: ble_ant_ctrl3_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctr_p1_8: ble_ant_ctr_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ rxev0l0_p1_8: rxev0l0_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctr_p1_9: ble_ant_ctr_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ txev0l1_p1_9: txev0l1_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ ain0_p2_0: ain0_p2_0 { + pinmux = ; + }; + + /omit-if-no-ref/ ain1_p2_1: ain1_p2_1 { + pinmux = ; + }; + + /omit-if-no-ref/ ain2_p2_2: ain2_p2_2 { + pinmux = ; + }; + + /omit-if-no-ref/ ain3_p2_3: ain3_p2_3 { + pinmux = ; + }; + + /omit-if-no-ref/ ain4_p2_4: ain4_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0b_ioa_p2_4: lptmr0b_ioa_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ ain5_p2_5: ain5_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1b_ioa_p2_5: lptmr1b_ioa_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ ain6_p2_6: ain6_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0_clk_p2_6: lptmr0_clk_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_rx_p2_6: lpuartb_rx_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ ain7_p2_7: ain7_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1_clk_p2_7: lptmr1_clk_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_tx_p2_7: lpuartb_tx_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ pdown_p3_0: pdown_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ wakeup_p3_0: wakeup_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ sqwout_p3_1: sqwout_p3_1 { + pinmux = ; + }; + + /omit-if-no-ref/ wakeup_p3_1: wakeup_p3_1 { + pinmux = ; + }; + + }; + }; +}; diff --git a/dts/arm/adi/max32/max32655.dtsi b/dts/arm/adi/max32/max32655.dtsi new file mode 100644 index 00000000000000..feacd93f09d870 --- /dev/null +++ b/dts/arm/adi/max32/max32655.dtsi @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023-2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&pinctrl { + reg = <0x40008000 0x2400>; + + gpio2: gpio@40080400 { + reg = <0x40080400 0x200>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <26 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 0>; + status = "disabled"; + }; + + gpio3: gpio@40080600 { + reg = <0x40080600 0x200>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <54 0>; + status = "disabled"; + }; +}; + +/* MAX32655 extra peripherals. */ +/ { + soc { + sram1: memory@20008000 { + compatible = "mmio-sram"; + reg = <0x20008000 DT_SIZE_K(32)>; + }; + + sram2: memory@20010000 { + compatible = "mmio-sram"; + reg = <0x20010000 DT_SIZE_K(48)>; + }; + + sram3: memory@2001c000 { + compatible = "mmio-sram"; + reg = <0x2001c000 DT_SIZE_K(16)>; + }; + + uart3: serial@40081400 { + compatible = "adi,max32-uart"; + reg = <0x40081400 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 4>; + clock-source = ; + interrupts = <88 0>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32680-pinctrl.dtsi b/dts/arm/adi/max32/max32680-pinctrl.dtsi new file mode 100644 index 00000000000000..525666cb14c9d1 --- /dev/null +++ b/dts/arm/adi/max32/max32680-pinctrl.dtsi @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + pinctrl: pin-controller@40008000 { + + /omit-if-no-ref/ uart0a_rx_p0_0: uart0a_rx_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0a_tx_p0_1: uart0a_tx_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0a_ioa_p0_2: tmr0a_ioa_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0b_cts_p0_2: uart0b_cts_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ ext_clk_p0_3: ext_clk_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_ss0_p0_4: spi0a_ss0_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioan_p0_4: tmr0b_ioan_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_mosi_p0_5: spi0a_mosi_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iobn_p0_5: tmr0b_iobn_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_miso_p0_6: spi0a_miso_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p0_6: owm_io_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_sck_p0_7: spi0a_sck_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pe_p0_7: owm_pe_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_sdio2_p0_8: spi0a_sdio2_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioa_p0_8: tmr0b_ioa_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0a_sdio3_p0_9: spi0a_sdio3_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iob_p0_9: tmr0b_iob_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0a_scl_p0_10: i2c0a_scl_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0b_ss2_p0_10: spi0b_ss2_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0a_sda_p0_11: i2c0a_sda_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0b_ss1_p0_11: spi0b_ss1_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1a_rx_p0_12: uart1a_rx_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_ioa_p0_12: tmr1b_ioa_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1a_tx_p0_13: uart1a_tx_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_iobn_p0_13: tmr1b_iobn_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_ioa_p0_14: tmr1a_ioa_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1b_cts_p0_14: uart1b_cts_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_iob_p0_15: tmr1a_iob_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1b_rts_p0_15: uart1b_rts_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1a_scl_p0_16: i2c1a_scl_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ pt2_p0_16: pt2_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1a_sda_p0_17: i2c1a_sda_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ pt3_p0_17: pt3_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1a_sdio2_p0_24: spi1a_sdio2_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2b_ioa_p0_24: tmr2b_ioa_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_rdy_p0_24: adc0_rdy_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1a_sdio3_p0_25: spi1a_sdio3_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2b_iob_p0_25: tmr2b_iob_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ adc1_rdy_p0_25: adc1_rdy_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2a_ioa_p0_26: tmr2a_ioa_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1b_ss1_p0_26: spi1b_ss1_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2a_iob_p0_27: tmr2a_iob_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1b_ss2_p0_27: spi1b_ss2_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ swdio_p0_28: swdio_p0_28 { + pinmux = ; + }; + + /omit-if-no-ref/ swclk_p0_29: swclk_p0_29 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2a_rx_p1_0: uart2a_rx_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tck_p1_0: rv_tck_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2a_tx_p1_1: uart2a_tx_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tms_p1_1: rv_tms_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s0a_sck_p1_2: i2s0a_sck_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdi_p1_2: rv_tdi_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s0a_lrclk_p1_3: i2s0a_lrclk_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdo_p1_3: rv_tdo_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s0a_sdi_p1_4: i2s0a_sdi_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_ioa_p1_4: tmr3b_ioa_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s0a_sdo_p1_5: i2s0a_sdo_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_iob_p1_5: tmr3b_iob_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_ioa_p1_6: tmr3a_ioa_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctrl2_p1_6: ble_ant_ctrl2_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_iob_p1_7: tmr3a_iob_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ ble_ant_ctrl3_p1_7: ble_ant_ctrl3_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ ain12_p2_4: ain12_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0b_ioa_p2_4: lptmr0b_ioa_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ ain13_p2_5: ain13_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1b_ioa_p2_5: lptmr1b_ioa_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0_clk_p2_6: lptmr0_clk_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_r_p2_6: lpuartb_r_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ x_p2_6: x_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1_clk_p2_7: lptmr1_clk_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_tx_p2_7: lpuartb_tx_p2_7 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32680.dtsi b/dts/arm/adi/max32/max32680.dtsi new file mode 100644 index 00000000000000..47c883b50b2bd1 --- /dev/null +++ b/dts/arm/adi/max32/max32680.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&pinctrl { + reg = <0x40008000 0x2400>; + + gpio2: gpio@40080400 { + reg = <0x40080400 0x200>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <26 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 0>; + status = "disabled"; + }; + + gpio3: gpio@40080600 { + reg = <0x40080600 0x200>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <54 0>; + status = "disabled"; + }; +}; + +/ { + soc { + sram1: memory@20008000 { + compatible = "mmio-sram"; + reg = <0x20008000 DT_SIZE_K(32)>; + }; + + sram2: memory@20010000 { + compatible = "mmio-sram"; + reg = <0x20010000 DT_SIZE_K(48)>; + }; + + sram3: memory@2001c000 { + compatible = "mmio-sram"; + reg = <0x2001c000 DT_SIZE_K(16)>; + }; + + uart3: serial@40081400 { + compatible = "adi,max32-uart"; + reg = <0x40081400 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 4>; + clock-source = ; + interrupts = <88 0>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32690.dtsi b/dts/arm/adi/max32/max32690.dtsi index 2bfef0e4be3cd5..a0dac1573a70c6 100644 --- a/dts/arm/adi/max32/max32690.dtsi +++ b/dts/arm/adi/max32/max32690.dtsi @@ -111,6 +111,56 @@ }; }; + spi0: spi@40046000 { + compatible = "adi,max32-spi"; + reg = <0x40046000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 6>; + interrupts = <16 0>; + status = "disabled"; + }; + + spi1: spi@40047000 { + compatible = "adi,max32-spi"; + reg = <0x40047000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 7>; + interrupts = <17 0>; + status = "disabled"; + }; + + spi2: spi@40048000 { + compatible = "adi,max32-spi"; + reg = <0x40048000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 8>; + interrupts = <18 0>; + status = "disabled"; + }; + + spi3: spi@400be000 { + compatible = "adi,max32-spi"; + reg = <0x400be000 0x400>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 16>; + interrupts = <56 0>; + status = "disabled"; + }; + + spi4: spi@400be400 { + compatible = "adi,max32-spi"; + reg = <0x400be400 0x400>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 17>; + interrupts = <105 0>; + status = "disabled"; + }; + uart3: serial@40081400 { compatible = "adi,max32-uart"; reg = <0x40081400 0x400>; diff --git a/dts/arm/adi/max32/max32xxx.dtsi b/dts/arm/adi/max32/max32xxx.dtsi index 64db7032960299..9db02fc4498340 100644 --- a/dts/arm/adi/max32/max32xxx.dtsi +++ b/dts/arm/adi/max32/max32xxx.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -101,6 +102,39 @@ status = "okay"; }; + i2c0: i2c0@4001d000 { + compatible = "adi,max32-i2c"; + reg = <0x4001d000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 13>; + interrupts = <13 0>; + status = "disabled"; + }; + + i2c1: i2c1@4001e000 { + compatible = "adi,max32-i2c"; + reg = <0x4001e000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 28>; + interrupts = <36 0>; + status = "disabled"; + }; + + i2c2: i2c2@4001f000 { + compatible = "adi,max32-i2c"; + reg = <0x4001f000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 24>; + interrupts = <62 0>; + status = "disabled"; + }; + pinctrl: pin-controller@40008000 { compatible = "adi,max32-pinctrl"; #address-cells = <1>; diff --git a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi index 07aa609e9423d5..ae1028ab4a1f31 100644 --- a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi @@ -160,6 +160,60 @@ ambiq,pwrcfg = <&pwrcfg 0x8 0x100>; }; + spi0: spi@50004000 { + reg = <0x50004000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <6 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x2>; + }; + + spi1: spi@50005000 { + reg = <0x50005000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <7 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x4>; + }; + + spi2: spi@50006000 { + reg = <0x50006000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <8 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x8>; + }; + + spi3: spi@50007000 { + reg = <0x50007000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <9 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x10>; + }; + + spi4: spi@50008000 { + reg = <0x50008000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <10 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x20>; + }; + + spi5: spi@50009000 { + reg = <0x50009000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <11 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x40>; + }; + i2c0: i2c@50004000 { reg = <0x50004000 0x1000>; #address-cells = <1>; @@ -233,7 +287,7 @@ status = "disabled"; ambiq,pwrcfg = <&pwrcfg 0x8 0x8000>; - bt-hci@0 { + bt_hci_apollo: bt-hci@0 { compatible = "ambiq,bt-hci-spi"; reg = <0>; }; diff --git a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi index 9fcfbd2b5e018f..afaf69692dd5af 100644 --- a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi @@ -160,6 +160,60 @@ ambiq,pwrcfg = <&pwrcfg 0x8 0x100>; }; + spi0: spi@50004000 { + reg = <0x50004000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <6 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x2>; + }; + + spi1: spi@50005000 { + reg = <0x50005000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <7 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x4>; + }; + + spi2: spi@50006000 { + reg = <0x50006000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <8 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x8>; + }; + + spi3: spi@50007000 { + reg = <0x50007000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <9 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x10>; + }; + + spi4: spi@50008000 { + reg = <0x50008000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <10 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x20>; + }; + + spi5: spi@50009000 { + reg = <0x50009000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <11 0>; + status = "disabled"; + ambiq,pwrcfg = <&pwrcfg 0x8 0x40>; + }; + i2c0: i2c@50004000 { reg = <0x50004000 0x1000>; #address-cells = <1>; @@ -253,7 +307,7 @@ status = "disabled"; ambiq,pwrcfg = <&pwrcfg 0x8 0x8000>; - bt-hci@0 { + bt_hci_apollo: bt-hci@0 { compatible = "ambiq,bt-hci-spi"; reg = <0>; }; diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 7f4d7145877fbf..9656eadc98445b 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -174,7 +174,7 @@ status = "disabled"; ambiq,pwrcfg = <&pwrcfg 0x4 0x20>; - bt-hci@0 { + bt_hci_apollo: bt-hci@0 { compatible = "ambiq,bt-hci-spi"; reg = <0>; irq-gpios = <&gpio32_63 21 GPIO_ACTIVE_HIGH>; diff --git a/dts/arm/infineon/cat1a/legacy/psoc6-pinctrl.dtsi b/dts/arm/infineon/cat1a/legacy/psoc6-pinctrl.dtsi index 526f74eea036c6..2f06ed2269fcb6 100644 --- a/dts/arm/infineon/cat1a/legacy/psoc6-pinctrl.dtsi +++ b/dts/arm/infineon/cat1a/legacy/psoc6-pinctrl.dtsi @@ -4,140 +4,718 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "pinctrl_cypress_psoc6.h" +#include +#include / { soc { - pinctrl@40310000 { - /* instance, signal, port, pin, hsiom [, flag1, ... ] */ - DT_CYPRESS_HSIOM(spi0, mosi, 0, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi0, miso, 0, 3, act_8, input-enable); - DT_CYPRESS_HSIOM(spi0, clk, 0, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi0, sel0, 0, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi0, sel1, 0, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi0, sel2, 0, 1, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, mosi, 10, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, miso, 10, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi1, clk, 10, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, sel0, 10, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, sel1, 10, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, sel2, 10, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi1, sel3, 10, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, mosi, 9, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, miso, 9, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi2, clk, 9, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, sel0, 9, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, sel1, 9, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, sel2, 9, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi2, sel3, 9, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, mosi, 6, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, miso, 6, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi3, clk, 6, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, sel0, 6, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, sel1, 7, 7, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, sel2, 8, 7, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi3, sel3, 5, 7, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, mosi, 7, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, miso, 7, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi4, clk, 7, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel0, 7, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel1, 7, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel2, 7, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel3, 7, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, mosi, 8, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, miso, 8, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi4, clk, 8, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel0, 8, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel1, 8, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel2, 8, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi4, sel3, 8, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, mosi, 5, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, miso, 5, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi5, clk, 5, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel0, 5, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel1, 5, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel2, 5, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel3, 5, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, mosi, 11, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, miso, 11, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi5, clk, 11, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel0, 11, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel1, 11, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel2, 11, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi5, sel3, 11, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, mosi, 6, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, miso, 6, 5, act_8, input-enable); - DT_CYPRESS_HSIOM(spi6, clk, 6, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel0, 6, 7, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, mosi, 12, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, miso, 12, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi6, clk, 12, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel0, 12, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel1, 12, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel2, 12, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel3, 12, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, mosi, 13, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, miso, 13, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi6, clk, 13, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel0, 13, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel1, 13, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel2, 13, 5, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi6, sel3, 13, 6, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi7, mosi, 1, 0, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi7, miso, 1, 1, act_8, input-enable); - DT_CYPRESS_HSIOM(spi7, clk, 1, 2, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi7, sel0, 1, 3, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi7, sel1, 1, 4, act_8, drive-push-pull); - DT_CYPRESS_HSIOM(spi7, sel2, 1, 5, act_8, drive-push-pull); - - DT_CYPRESS_HSIOM(uart0, rx, 0, 2, act_6, input-enable); - DT_CYPRESS_HSIOM(uart0, tx, 0, 3, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart0, rts, 0, 4, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart0, cts, 0, 5, act_6, input-enable); - DT_CYPRESS_HSIOM(uart1, rx, 10, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart1, tx, 10, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart1, rts, 10, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart1, cts, 10, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart2, rx, 9, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart2, tx, 9, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart2, rts, 9, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart2, cts, 9, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart3, rx, 6, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart3, tx, 6, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart3, rts, 6, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart3, cts, 6, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart4, rx, 7, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart4, tx, 7, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart4, rts, 7, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart4, cts, 7, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart4, rx, 8, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart4, tx, 8, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart4, rts, 8, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart4, cts, 8, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart5, rx, 5, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart5, tx, 5, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart5, rts, 5, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart5, cts, 5, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart5, rx, 11, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart5, tx, 11, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart5, rts, 11, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart5, cts, 11, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, rx, 6, 4, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, tx, 6, 5, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, rts, 6, 6, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, cts, 6, 7, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, rx, 12, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, tx, 12, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, rts, 12, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, cts, 12, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, rx, 13, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart6, tx, 13, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, rts, 13, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart6, cts, 13, 3, act_6, input-enable); - DT_CYPRESS_HSIOM(uart7, rx, 1, 0, act_6, input-enable); - DT_CYPRESS_HSIOM(uart7, tx, 1, 1, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart7, rts, 1, 2, act_6, drive-push-pull); - DT_CYPRESS_HSIOM(uart7, cts, 1, 3, act_6, input-enable); + + pinctrl: pinctrl@40310000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_2_scb0_i2c_scl: p0_2_scb0_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p1_0_scb7_i2c_scl: p1_0_scb7_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p5_0_scb5_i2c_scl: p5_0_scb5_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb3_i2c_scl: p6_0_scb3_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb8_i2c_scl: p6_0_scb8_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb6_i2c_scl: p6_4_scb6_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb8_i2c_scl: p6_4_scb8_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p7_0_scb4_i2c_scl: p7_0_scb4_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p8_0_scb4_i2c_scl: p8_0_scb4_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p9_0_scb2_i2c_scl: p9_0_scb2_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p10_0_scb1_i2c_scl: p10_0_scb1_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p11_0_scb5_i2c_scl: p11_0_scb5_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p12_0_scb6_i2c_scl: p12_0_scb6_i2c_scl { + pinmux = ; + }; + /omit-if-no-ref/ p13_0_scb6_i2c_scl: p13_0_scb6_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_3_scb0_i2c_sda: p0_3_scb0_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p1_1_scb7_i2c_sda: p1_1_scb7_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p5_1_scb5_i2c_sda: p5_1_scb5_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb3_i2c_sda: p6_1_scb3_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb8_i2c_sda: p6_1_scb8_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb6_i2c_sda: p6_5_scb6_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb8_i2c_sda: p6_5_scb8_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p7_1_scb4_i2c_sda: p7_1_scb4_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p8_1_scb4_i2c_sda: p8_1_scb4_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p9_1_scb2_i2c_sda: p9_1_scb2_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p10_1_scb1_i2c_sda: p10_1_scb1_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p11_1_scb5_i2c_sda: p11_1_scb5_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p12_1_scb6_i2c_sda: p12_1_scb6_i2c_sda { + pinmux = ; + }; + /omit-if-no-ref/ p13_1_scb6_i2c_sda: p13_1_scb6_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_4_scb0_spi_m_clk: p0_4_scb0_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p5_2_scb5_spi_m_clk: p5_2_scb5_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_2_scb3_spi_m_clk: p6_2_scb3_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_2_scb8_spi_m_clk: p6_2_scb8_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_6_scb6_spi_m_clk: p6_6_scb6_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_6_scb8_spi_m_clk: p6_6_scb8_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p7_2_scb4_spi_m_clk: p7_2_scb4_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p8_2_scb4_spi_m_clk: p8_2_scb4_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p9_2_scb2_spi_m_clk: p9_2_scb2_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p10_2_scb1_spi_m_clk: p10_2_scb1_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p11_2_scb5_spi_m_clk: p11_2_scb5_spi_m_clk { + pinmux = ; + }; + /omit-if-no-ref/ p12_2_scb6_spi_m_clk: p12_2_scb6_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_3_scb0_spi_m_miso: p0_3_scb0_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p1_1_scb7_spi_m_miso: p1_1_scb7_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p5_1_scb5_spi_m_miso: p5_1_scb5_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb3_spi_m_miso: p6_1_scb3_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb8_spi_m_miso: p6_1_scb8_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb6_spi_m_miso: p6_5_scb6_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb8_spi_m_miso: p6_5_scb8_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p7_1_scb4_spi_m_miso: p7_1_scb4_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p8_1_scb4_spi_m_miso: p8_1_scb4_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p9_1_scb2_spi_m_miso: p9_1_scb2_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p10_1_scb1_spi_m_miso: p10_1_scb1_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p11_1_scb5_spi_m_miso: p11_1_scb5_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p12_1_scb6_spi_m_miso: p12_1_scb6_spi_m_miso { + pinmux = ; + }; + /omit-if-no-ref/ p13_1_scb6_spi_m_miso: p13_1_scb6_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_2_scb0_spi_m_mosi: p0_2_scb0_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p1_0_scb7_spi_m_mosi: p1_0_scb7_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p5_0_scb5_spi_m_mosi: p5_0_scb5_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb3_spi_m_mosi: p6_0_scb3_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb8_spi_m_mosi: p6_0_scb8_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb6_spi_m_mosi: p6_4_scb6_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb8_spi_m_mosi: p6_4_scb8_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p7_0_scb4_spi_m_mosi: p7_0_scb4_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p8_0_scb4_spi_m_mosi: p8_0_scb4_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p9_0_scb2_spi_m_mosi: p9_0_scb2_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p10_0_scb1_spi_m_mosi: p10_0_scb1_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p11_0_scb5_spi_m_mosi: p11_0_scb5_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p12_0_scb6_spi_m_mosi: p12_0_scb6_spi_m_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p13_0_scb6_spi_m_mosi: p13_0_scb6_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_5_scb0_spi_m_select0: p0_5_scb0_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p5_3_scb5_spi_m_select0: p5_3_scb5_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_3_scb3_spi_m_select0: p6_3_scb3_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_3_scb8_spi_m_select0: p6_3_scb8_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_7_scb6_spi_m_select0: p6_7_scb6_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_7_scb8_spi_m_select0: p6_7_scb8_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p7_3_scb4_spi_m_select0: p7_3_scb4_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p8_3_scb4_spi_m_select0: p8_3_scb4_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p9_3_scb2_spi_m_select0: p9_3_scb2_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p10_3_scb1_spi_m_select0: p10_3_scb1_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p11_3_scb5_spi_m_select0: p11_3_scb5_spi_m_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p12_3_scb6_spi_m_select0: p12_3_scb6_spi_m_select0 { + pinmux = ; + }; + + /* scb_spi_m_select1 */ + /omit-if-no-ref/ p0_0_scb0_spi_m_select1: p0_0_scb0_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p1_4_scb7_spi_m_select1: p1_4_scb7_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p5_4_scb5_spi_m_select1: p5_4_scb5_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p7_4_scb4_spi_m_select1: p7_4_scb4_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p7_7_scb3_spi_m_select1: p7_7_scb3_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p8_4_scb4_spi_m_select1: p8_4_scb4_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p10_4_scb1_spi_m_select1: p10_4_scb1_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p11_4_scb5_spi_m_select1: p11_4_scb5_spi_m_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p12_4_scb6_spi_m_select1: p12_4_scb6_spi_m_select1 { + pinmux = ; + }; + + /* scb_spi_m_select2 */ + /omit-if-no-ref/ p0_1_scb0_spi_m_select2: p0_1_scb0_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p1_5_scb7_spi_m_select2: p1_5_scb7_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p5_5_scb5_spi_m_select2: p5_5_scb5_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p7_5_scb4_spi_m_select2: p7_5_scb4_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p8_5_scb4_spi_m_select2: p8_5_scb4_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p8_7_scb3_spi_m_select2: p8_7_scb3_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p10_5_scb1_spi_m_select2: p10_5_scb1_spi_m_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p11_5_scb5_spi_m_select2: p11_5_scb5_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p5_6_scb5_spi_m_select3: p5_6_scb5_spi_m_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p5_7_scb3_spi_m_select3: p5_7_scb3_spi_m_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p7_6_scb4_spi_m_select3: p7_6_scb4_spi_m_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p8_6_scb4_spi_m_select3: p8_6_scb4_spi_m_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p10_6_scb1_spi_m_select3: p10_6_scb1_spi_m_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p11_6_scb5_spi_m_select3: p11_6_scb5_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_4_scb0_spi_s_clk: p0_4_scb0_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p5_2_scb5_spi_s_clk: p5_2_scb5_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_2_scb3_spi_s_clk: p6_2_scb3_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_2_scb8_spi_s_clk: p6_2_scb8_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_6_scb6_spi_s_clk: p6_6_scb6_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p6_6_scb8_spi_s_clk: p6_6_scb8_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p7_2_scb4_spi_s_clk: p7_2_scb4_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p8_2_scb4_spi_s_clk: p8_2_scb4_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p9_2_scb2_spi_s_clk: p9_2_scb2_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p10_2_scb1_spi_s_clk: p10_2_scb1_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p11_2_scb5_spi_s_clk: p11_2_scb5_spi_s_clk { + pinmux = ; + }; + /omit-if-no-ref/ p12_2_scb6_spi_s_clk: p12_2_scb6_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_3_scb0_spi_s_miso: p0_3_scb0_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p1_1_scb7_spi_s_miso: p1_1_scb7_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p5_1_scb5_spi_s_miso: p5_1_scb5_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb3_spi_s_miso: p6_1_scb3_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb8_spi_s_miso: p6_1_scb8_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb6_spi_s_miso: p6_5_scb6_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb8_spi_s_miso: p6_5_scb8_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p7_1_scb4_spi_s_miso: p7_1_scb4_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p8_1_scb4_spi_s_miso: p8_1_scb4_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p9_1_scb2_spi_s_miso: p9_1_scb2_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p10_1_scb1_spi_s_miso: p10_1_scb1_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p11_1_scb5_spi_s_miso: p11_1_scb5_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p12_1_scb6_spi_s_miso: p12_1_scb6_spi_s_miso { + pinmux = ; + }; + /omit-if-no-ref/ p13_1_scb6_spi_s_miso: p13_1_scb6_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_2_scb0_spi_s_mosi: p0_2_scb0_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p1_0_scb7_spi_s_mosi: p1_0_scb7_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p5_0_scb5_spi_s_mosi: p5_0_scb5_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb3_spi_s_mosi: p6_0_scb3_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb8_spi_s_mosi: p6_0_scb8_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb6_spi_s_mosi: p6_4_scb6_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb8_spi_s_mosi: p6_4_scb8_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p7_0_scb4_spi_s_mosi: p7_0_scb4_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p8_0_scb4_spi_s_mosi: p8_0_scb4_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p9_0_scb2_spi_s_mosi: p9_0_scb2_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p10_0_scb1_spi_s_mosi: p10_0_scb1_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p11_0_scb5_spi_s_mosi: p11_0_scb5_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p12_0_scb6_spi_s_mosi: p12_0_scb6_spi_s_mosi { + pinmux = ; + }; + /omit-if-no-ref/ p13_0_scb6_spi_s_mosi: p13_0_scb6_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_5_scb0_spi_s_select0: p0_5_scb0_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p5_3_scb5_spi_s_select0: p5_3_scb5_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_3_scb3_spi_s_select0: p6_3_scb3_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_3_scb8_spi_s_select0: p6_3_scb8_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_7_scb6_spi_s_select0: p6_7_scb6_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p6_7_scb8_spi_s_select0: p6_7_scb8_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p7_3_scb4_spi_s_select0: p7_3_scb4_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p8_3_scb4_spi_s_select0: p8_3_scb4_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p9_3_scb2_spi_s_select0: p9_3_scb2_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p10_3_scb1_spi_s_select0: p10_3_scb1_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p11_3_scb5_spi_s_select0: p11_3_scb5_spi_s_select0 { + pinmux = ; + }; + /omit-if-no-ref/ p12_3_scb6_spi_s_select0: p12_3_scb6_spi_s_select0 { + pinmux = ; + }; + + /* scb_spi_s_select1 */ + /omit-if-no-ref/ p0_0_scb0_spi_s_select1: p0_0_scb0_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p1_4_scb7_spi_s_select1: p1_4_scb7_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p5_4_scb5_spi_s_select1: p5_4_scb5_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p7_4_scb4_spi_s_select1: p7_4_scb4_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p7_7_scb3_spi_s_select1: p7_7_scb3_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p8_4_scb4_spi_s_select1: p8_4_scb4_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p10_4_scb1_spi_s_select1: p10_4_scb1_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p11_4_scb5_spi_s_select1: p11_4_scb5_spi_s_select1 { + pinmux = ; + }; + /omit-if-no-ref/ p12_4_scb6_spi_s_select1: p12_4_scb6_spi_s_select1 { + pinmux = ; + }; + + /* scb_spi_s_select2 */ + /omit-if-no-ref/ p0_1_scb0_spi_s_select2: p0_1_scb0_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p1_5_scb7_spi_s_select2: p1_5_scb7_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p5_5_scb5_spi_s_select2: p5_5_scb5_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p7_5_scb4_spi_s_select2: p7_5_scb4_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p8_5_scb4_spi_s_select2: p8_5_scb4_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p8_7_scb3_spi_s_select2: p8_7_scb3_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p10_5_scb1_spi_s_select2: p10_5_scb1_spi_s_select2 { + pinmux = ; + }; + /omit-if-no-ref/ p11_5_scb5_spi_s_select2: p11_5_scb5_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p5_6_scb5_spi_s_select3: p5_6_scb5_spi_s_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p5_7_scb3_spi_s_select3: p5_7_scb3_spi_s_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p7_6_scb4_spi_s_select3: p7_6_scb4_spi_s_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p8_6_scb4_spi_s_select3: p8_6_scb4_spi_s_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p10_6_scb1_spi_s_select3: p10_6_scb1_spi_s_select3 { + pinmux = ; + }; + /omit-if-no-ref/ p11_6_scb5_spi_s_select3: p11_6_scb5_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_5_scb0_uart_cts: p0_5_scb0_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p5_3_scb5_uart_cts: p5_3_scb5_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p6_3_scb3_uart_cts: p6_3_scb3_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p6_7_scb6_uart_cts: p6_7_scb6_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p7_3_scb4_uart_cts: p7_3_scb4_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p8_3_scb4_uart_cts: p8_3_scb4_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p9_3_scb2_uart_cts: p9_3_scb2_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p10_3_scb1_uart_cts: p10_3_scb1_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p11_3_scb5_uart_cts: p11_3_scb5_uart_cts { + pinmux = ; + }; + /omit-if-no-ref/ p12_3_scb6_uart_cts: p12_3_scb6_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_4_scb0_uart_rts: p0_4_scb0_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p5_2_scb5_uart_rts: p5_2_scb5_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p6_2_scb3_uart_rts: p6_2_scb3_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p6_6_scb6_uart_rts: p6_6_scb6_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p7_2_scb4_uart_rts: p7_2_scb4_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p8_2_scb4_uart_rts: p8_2_scb4_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p9_2_scb2_uart_rts: p9_2_scb2_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p10_2_scb1_uart_rts: p10_2_scb1_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p11_2_scb5_uart_rts: p11_2_scb5_uart_rts { + pinmux = ; + }; + /omit-if-no-ref/ p12_2_scb6_uart_rts: p12_2_scb6_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_2_scb0_uart_rx: p0_2_scb0_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p1_0_scb7_uart_rx: p1_0_scb7_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p5_0_scb5_uart_rx: p5_0_scb5_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p6_0_scb3_uart_rx: p6_0_scb3_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p6_4_scb6_uart_rx: p6_4_scb6_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p7_0_scb4_uart_rx: p7_0_scb4_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p8_0_scb4_uart_rx: p8_0_scb4_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p9_0_scb2_uart_rx: p9_0_scb2_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p10_0_scb1_uart_rx: p10_0_scb1_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p11_0_scb5_uart_rx: p11_0_scb5_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p12_0_scb6_uart_rx: p12_0_scb6_uart_rx { + pinmux = ; + }; + /omit-if-no-ref/ p13_0_scb6_uart_rx: p13_0_scb6_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_3_scb0_uart_tx: p0_3_scb0_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p1_1_scb7_uart_tx: p1_1_scb7_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p5_1_scb5_uart_tx: p5_1_scb5_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p6_1_scb3_uart_tx: p6_1_scb3_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p6_5_scb6_uart_tx: p6_5_scb6_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p7_1_scb4_uart_tx: p7_1_scb4_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p8_1_scb4_uart_tx: p8_1_scb4_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p9_1_scb2_uart_tx: p9_1_scb2_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p10_1_scb1_uart_tx: p10_1_scb1_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p11_1_scb5_uart_tx: p11_1_scb5_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p12_1_scb6_uart_tx: p12_1_scb6_uart_tx { + pinmux = ; + }; + /omit-if-no-ref/ p13_1_scb6_uart_tx: p13_1_scb6_uart_tx { + pinmux = ; + }; }; }; }; diff --git a/dts/arm/infineon/cat1a/legacy/psoc6.dtsi b/dts/arm/infineon/cat1a/legacy/psoc6.dtsi index a6ab61e9949dde..ad9fef2e0fdef1 100644 --- a/dts/arm/infineon/cat1a/legacy/psoc6.dtsi +++ b/dts/arm/infineon/cat1a/legacy/psoc6.dtsi @@ -67,7 +67,7 @@ soc { pinctrl@40310000 { - compatible = "cypress,psoc6-pinctrl"; + compatible = "infineon,cat1-pinctrl"; #address-cells = <1>; #size-cells = <1>; ranges = <0x40310000 0x40310000 0x2024>; diff --git a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi index 7f64c6bc8c3151..c0a59722e2f8bf 100644 --- a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi +++ b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi @@ -21,13 +21,13 @@ sram0: memory@20000000 { compatible = "mmio-sram"; - reg = <0x20000000 0x3DC00>; + reg = <0x20000000 DT_SIZE_K(244)>; }; - sram_bootstrap: memory@2003DC00 { + sram_bootstrap: memory@2003D000 { compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "BOOTSTRAP_RAM"; - reg = <0x2003DC00 0x2400>; + reg = <0x2003D000 DT_SIZE_K(12)>; }; soc { @@ -289,6 +289,12 @@ <34 6>; /* CH15 */ status = "disabled"; }; + bluetooth: btss@42000000 { + compatible = "infineon,cyw208xx-hci"; + reg = <0x42000000 0x6186A0>; + interrupts = <16 6>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/nordic/nrf51822.dtsi b/dts/arm/nordic/nrf51822.dtsi index b64de1d4985c86..11cc9eff2f9e81 100644 --- a/dts/arm/nordic/nrf51822.dtsi +++ b/dts/arm/nordic/nrf51822.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -73,6 +74,11 @@ reg = <0x40001000 0x1000>; interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index c5a184d5e288c4..b375ef1706975f 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -86,6 +87,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 1ca4a9ea378a37..0c95fe96e70df6 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -90,6 +91,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 63b85676587735..2176bfa93c7448 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -102,6 +103,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index f93e449b0b2cc9..d6bd6e65f66cfb 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -10,6 +10,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -98,6 +99,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index 13ee05226b76f2..bdb76a05d5b596 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -90,6 +91,11 @@ interrupts = <1 NRF_DEFAULT_IRQ_PRIORITY>; status = "okay"; ble-2mbps-supported; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index f22cb36bc14a48..40c3f1efcad4b5 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -97,6 +98,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 4cfb7abc511efc..120a5a87b1355f 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -5,6 +5,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -92,6 +93,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; uart0: uart@40002000 { diff --git a/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi b/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi index 9dc8f70a7d0cee..f5cda20e9613fe 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi @@ -11,4 +11,9 @@ ipc0: ipc0 { mbox-names = "tx", "rx"; role = "host"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; diff --git a/dts/arm/nordic/nrf5340_cpunet.dtsi b/dts/arm/nordic/nrf5340_cpunet.dtsi index 8a95b3e99850a8..4e05f4a1df02ea 100644 --- a/dts/arm/nordic/nrf5340_cpunet.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet.dtsi @@ -9,6 +9,7 @@ / { chosen { + zephyr,bt-hci = &bt_hci_controller; zephyr,entropy = &rng; zephyr,flash-controller = &flash_controller; }; @@ -100,6 +101,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "okay"; + }; }; rng: random@41009000 { diff --git a/dts/arm/nordic/nrf54h20_cpurad.dtsi b/dts/arm/nordic/nrf54h20_cpurad.dtsi index e4a7469dac5530..b426d660f3dc08 100644 --- a/dts/arm/nordic/nrf54h20_cpurad.dtsi +++ b/dts/arm/nordic/nrf54h20_cpurad.dtsi @@ -50,7 +50,7 @@ wdt011: &cpurad_wdt011 {}; }; &grtc { - owned-channels = <7 8 9 10 11 12 13 14>; + owned-channels = <7 8 9 10 11 12 13 14 15>; child-owned-channels = <8 9 10 11 12>; nonsecure-channels = <8 9 10 11 12>; interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>, diff --git a/dts/arm/nordic/nrf54l15_cpuapp.dtsi b/dts/arm/nordic/nrf54l15_cpuapp.dtsi index 6a4f5fcae239e9..551d344f8426aa 100644 --- a/dts/arm/nordic/nrf54l15_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54l15_cpuapp.dtsi @@ -17,6 +17,10 @@ cpuflpr_vevif: &cpuflpr_vevif_remote {}; /delete-node/ &cpuflpr_clic; / { + chosen { + zephyr,bt-hci = &bt_hci_controller; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&cpuapp_nvic>; @@ -29,14 +33,22 @@ cpuflpr_vevif: &cpuflpr_vevif_remote {}; }; }; +&bt_hci_controller { + status = "okay"; +}; + &cpuapp_ppb { compatible = "simple-bus"; ranges; }; &grtc { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>, +#else interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>, - <229 NRF_DEFAULT_IRQ_PRIORITY>; /* reserved for Zero Latency IRQs */ +#endif + <229 NRF_DEFAULT_IRQ_PRIORITY>; /* reserved for Zero Latency IRQs */ }; &gpiote20 { diff --git a/dts/arm/nuvoton/m2l31x.dtsi b/dts/arm/nuvoton/m2l31x.dtsi index 2b4b57c987687c..b3cbd6c997b5d4 100644 --- a/dts/arm/nuvoton/m2l31x.dtsi +++ b/dts/arm/nuvoton/m2l31x.dtsi @@ -386,6 +386,14 @@ bosch,mram-cfg = <0x0 12 10 3 3 3 3 3>; status = "disabled"; }; + + wwdt: watchdog@40096000 { + compatible = "nuvoton,numaker-wwdt"; + reg = <0x40096000 0x10>; + interrupts = <9 0>; + clocks = <&pcc NUMAKER_WWDT_MODULE NUMAKER_CLK_CLKSEL1_WWDTSEL_LIRC 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/nxp/nxp_k22fn512.dtsi b/dts/arm/nxp/nxp_k22fn512.dtsi new file mode 100644 index 00000000000000..76244b94d597b9 --- /dev/null +++ b/dts/arm/nxp/nxp_k22fn512.dtsi @@ -0,0 +1,11 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&flash0 { + reg = <0 DT_SIZE_K(512)>; +}; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index d47fd6cca52878..6aff4315889ad5 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -290,6 +290,7 @@ clock-frequency = <128000>; prescaler = <1>; clk-source = <1>; + resolution = <16>; }; wdog: watchdog@40052000 { diff --git a/dts/arm/nxp/nxp_ke1xz.dtsi b/dts/arm/nxp/nxp_ke1xz.dtsi index 5f6b08f5dc0784..d3b55949e454f6 100644 --- a/dts/arm/nxp/nxp_ke1xz.dtsi +++ b/dts/arm/nxp/nxp_ke1xz.dtsi @@ -167,17 +167,18 @@ clocks = <&pcc 0x134 KINETIS_PCC_SRC_NONE_OR_EXT>; }; - gpios0: gpios0 { + gpios0: gpios0@400ff000 { compatible = "nxp,gpio-cluster"; interrupts = <7 2>; - + reg = <0x400ff000 0x200>; + ranges = <0x0 0x400ff000 0x200>; #address-cells = <1>; #size-cells = <1>; gpioa: gpio@400ff000 { compatible = "nxp,kinetis-gpio"; status = "disabled"; - reg = <0x400ff000 0x40>; + reg = <0x0 0x40>; gpio-controller; #gpio-cells = <2>; nxp,kinetis-port = <&porta>; @@ -186,24 +187,25 @@ gpioe: gpio@400ff100 { compatible = "nxp,kinetis-gpio"; status = "disabled"; - reg = <0x400ff100 0x40>; + reg = <0x100 0x40>; gpio-controller; #gpio-cells = <2>; nxp,kinetis-port = <&porte>; }; }; - gpios1: gpios1 { + gpios1: gpios1@400ff040 { compatible = "nxp,gpio-cluster"; interrupts = <26 2>; - + reg = <0x400ff040 0x200>; + ranges = <0x40 0x400ff040 0x200>; #address-cells = <1>; #size-cells = <1>; gpiob: gpio@400ff040 { compatible = "nxp,kinetis-gpio"; status = "disabled"; - reg = <0x400ff040 0x40>; + reg = <0x40 0x40>; gpio-controller; #gpio-cells = <2>; nxp,kinetis-port = <&portb>; @@ -212,7 +214,7 @@ gpioc: gpio@400ff080 { compatible = "nxp,kinetis-gpio"; status = "disabled"; - reg = <0x400ff080 0x40>; + reg = <0x80 0x40>; gpio-controller; #gpio-cells = <2>; nxp,kinetis-port = <&portc>; @@ -221,7 +223,7 @@ gpiod: gpio@400ff0c0 { compatible = "nxp,kinetis-gpio"; status = "disabled"; - reg = <0x400ff0c0 0x40>; + reg = <0xc0 0x40>; gpio-controller; #gpio-cells = <2>; nxp,kinetis-port = <&portd>; diff --git a/dts/arm/nxp/nxp_lpc51u68.dtsi b/dts/arm/nxp/nxp_lpc51u68.dtsi index 3c69de8dd4ac65..ff4b43073b6216 100644 --- a/dts/arm/nxp/nxp_lpc51u68.dtsi +++ b/dts/arm/nxp/nxp_lpc51u68.dtsi @@ -40,7 +40,7 @@ sramx:memory@4000000 { compatible = "mmio-sram"; - reg = <0x40000000 DT_SIZE_K(32)>; + reg = <0x04000000 DT_SIZE_K(32)>; }; flash0: flash@0 { diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index ba6e8c1c5c990f..054ad3700d8c1b 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -874,6 +874,36 @@ status = "disabled"; #io-channel-cells = <2>; }; + + flexcan0: can@d4000 { + compatible = "nxp,flexcan"; + reg = <0xd4000 0x4000>; + interrupts = <62 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN0_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan1: can@d8000 { + compatible = "nxp,flexcan"; + reg = <0xd8000 0x4000>; + interrupts = <63 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN1_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + lptmr0: lptmr@4a000 { + compatible = "nxp,lptmr"; + reg = <0x4a000 0x1000>; + interrupts = <143 0>; + clock-frequency = <16000>; + prescaler = <1>; + clk-source = <1>; + resolution = <32>; + }; }; &systick { diff --git a/dts/arm/nxp/nxp_rt1160.dtsi b/dts/arm/nxp/nxp_rt1160.dtsi new file mode 100644 index 00000000000000..1794204a80f307 --- /dev/null +++ b/dts/arm/nxp/nxp_rt1160.dtsi @@ -0,0 +1,11 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Configure ARM PLL to 600MHz */ +&arm_pll { + clock-mult = <100>; + clock-div = <4>; +}; diff --git a/dts/arm/nxp/nxp_rt1170.dtsi b/dts/arm/nxp/nxp_rt1170.dtsi new file mode 100644 index 00000000000000..555225b94fd93d --- /dev/null +++ b/dts/arm/nxp/nxp_rt1170.dtsi @@ -0,0 +1,11 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Configure ARM PLL to 996MHz */ +&arm_pll { + clock-mult = <83>; + clock-div = <2>; +}; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index fc0a1690800107..c9c126f5173ed0 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -164,11 +164,55 @@ clocks = <&ccm IMX_CCM_GPT_CLK 0x45 0>; }; + qtmr1: qtmr@4015c000 { + compatible = "nxp,qtmr-pwm"; + reg = <0x4015c000 0x4000>; + interrupts = <171 0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_QTMR1_CLK 0x0 0>; + }; + + qtmr2: qtmr@40160000 { + compatible = "nxp,qtmr-pwm"; + reg = <0x40160000 0x4000>; + interrupts = <172 0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_QTMR2_CLK 0x0 0>; + }; + + qtmr3: qtmr@40164000 { + compatible = "nxp,qtmr-pwm"; + reg = <0x40164000 0x4000>; + interrupts = <173 0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_QTMR3_CLK 0x0 0>; + }; + + qtmr4: qtmr@40168000 { + compatible = "nxp,qtmr-pwm"; + reg = <0x40168000 0x4000>; + interrupts = <174 0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_QTMR4_CLK 0x0 0>; + }; + ccm: ccm@40cc0000 { compatible = "nxp,imx-ccm-rev2"; reg = <0x40cc0000 0x4000>; #clock-cells = <3>; + + /* + * ARM PLL is an integer PLL, with an input clock + * of 24MHz. The PLL features a loop divider and + * post divider. The output frequency is calculated + * as Fout = 24MHz * (clock-mult / clock-div) + */ + arm_pll: arm-pll { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + }; + }; gpio1: gpio@4012c000 { @@ -732,22 +776,30 @@ }; }; - /* - * enet1g peripheral to use with kinetis-ethernet (eth_mcux) driver - * just like the enet peripheral (i.e. only 10/100Mbit for now) - */ enet1g: ethernet@40420000 { - compatible = "nxp,kinetis-ethernet"; + compatible = "nxp,enet1g"; reg = <0x40420000 0x628>; - interrupts = <141 0>; - interrupt-names = "COMMON"; + clocks = <&ccm IMX_CCM_ENET1G_CLK 0 0>; status = "disabled"; - phy-addr = <1>; - ptp1g: ptp { - compatible = "nxp,kinetis-ptp"; + enet1g_mac: ethernet { + compatible = "nxp,enet-mac"; + interrupts = <141 0>; + interrupt-names = "COMMON"; + nxp,mdio = <&enet1g_mdio>; + nxp,ptp-clock = <&enet1g_ptp_clock>; status = "disabled"; + }; + enet1g_mdio: mdio { + compatible = "nxp,enet-mdio"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + enet1g_ptp_clock: ptp_clock { + compatible = "nxp,enet-ptp-clock"; interrupts = <142 0>; - interrupt-names = "IEEE1588_TMR"; + status = "disabled"; + clocks = <&ccm IMX_CCM_ENET_PLL 0 0>; }; }; diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index 60c3dc9d2d5427..229d8b299db292 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -16,6 +16,7 @@ / { chosen { zephyr,entropy = &trng; + zephyr,bt-hci = &hci; }; cpus { @@ -484,6 +485,32 @@ interrupts = <90 2>, <82 2>; interrupt-names = "hci_int", "wakeup_int"; }; + + enet: enet@138000 { + compatible = "nxp,enet"; + reg = <0x138000 0x700>; + clocks = <&clkctl1 MCUX_ENET_CLK>; + enet_mac: ethernet { + compatible = "nxp,enet-mac"; + interrupts = <115 0>; + interrupt-names = "COMMON"; + nxp,mdio = <&enet_mdio>; + nxp,ptp-clock = <&enet_ptp_clock>; + status = "disabled"; + }; + enet_mdio: mdio { + compatible = "nxp,enet-mdio"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + enet_ptp_clock: ptp-clock { + compatible = "nxp,enet-ptp-clock"; + interrupts = <116 0>; + status = "disabled"; + clocks = <&clkctl1 MCUX_ENET_PLL>; + }; + }; }; &flexspi { diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 0289b24f42ea69..fa6b2b1e43de0b 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -828,6 +828,20 @@ }; }; + flexio0: flexio@40324000 { + compatible = "nxp,flexio"; + reg = <0x40324000 0x4000>; + interrupts = <139 0>; + clocks = <&clock NXP_S32_FLEXIO0_CLK>; + status = "disabled"; + + flexio0_pwm { + compatible = "nxp,flexio-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + lcu0: lcu@40098000 { compatible = "nxp,s32-lcu"; reg = <0x40098000 0x4000>; diff --git a/dts/arm/renesas/smartbond/da1469x.dtsi b/dts/arm/renesas/smartbond/da1469x.dtsi index 1da9cc6cae0b52..05f250935f32f7 100644 --- a/dts/arm/renesas/smartbond/da1469x.dtsi +++ b/dts/arm/renesas/smartbond/da1469x.dtsi @@ -386,7 +386,7 @@ status = "disabled"; dma-channels = <8>; block-count = <1>; - #dma-cells = <0>; + #dma-cells = <2>; }; memc: qspic2@34000000 { @@ -394,6 +394,11 @@ reg = <0x34000000 0x48>; status = "disabled"; }; + + bt_hci_da1469x: bt_hci_da1469x { + compatible = "renesas,bt-hci-da1469x"; + status = "disabled"; + }; }; }; diff --git a/dts/arm/silabs/efr32bg2x.dtsi b/dts/arm/silabs/efr32bg2x.dtsi index 70df9708d116ac..9cd0618cd41c9a 100644 --- a/dts/arm/silabs/efr32bg2x.dtsi +++ b/dts/arm/silabs/efr32bg2x.dtsi @@ -224,6 +224,11 @@ #io-channel-cells = <1>; }; }; + + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci"; + status = "disabled"; + }; }; / { diff --git a/dts/arm/silabs/efr32mg.dtsi b/dts/arm/silabs/efr32mg.dtsi index cfbbde48af9b16..a7926f6710f6bf 100644 --- a/dts/arm/silabs/efr32mg.dtsi +++ b/dts/arm/silabs/efr32mg.dtsi @@ -234,6 +234,11 @@ }; }; + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci"; + status = "disabled"; + }; + pinctrl: pin-controller { /* Pin controller is a "virtual" device since SiLabs SoCs do pin * control in a distributed way (GPIO registers and PSEL diff --git a/dts/arm/silabs/efr32mg24.dtsi b/dts/arm/silabs/efr32mg24.dtsi index 860cedddeda5f0..b92100c85a5673 100644 --- a/dts/arm/silabs/efr32mg24.dtsi +++ b/dts/arm/silabs/efr32mg24.dtsi @@ -213,6 +213,12 @@ #io-channel-cells = <1>; }; }; + + + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci"; + status = "disabled"; + }; }; / { diff --git a/dts/arm/silabs/efr32xg13p.dtsi b/dts/arm/silabs/efr32xg13p.dtsi index 96d9c6493d18dc..3444eb6e391f43 100644 --- a/dts/arm/silabs/efr32xg13p.dtsi +++ b/dts/arm/silabs/efr32xg13p.dtsi @@ -181,6 +181,11 @@ }; }; + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci"; + status = "disabled"; + }; + pinctrl: pin-controller { /* Pin controller is a "virtual" device since SiLabs SoCs do pin * control in a distributed way (GPIO registers and PSEL diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index 89c6944e6a42f0..ca4e3d47d8a91a 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -192,6 +192,18 @@ alarms-count = <2>; alrm-exti-line = <19>; status = "disabled"; + + /* In STM32G0, the backup registers are defined as part of the TAMP + * peripheral. This peripheral is not implemented in Zephyr yet, however, + * the reference manual states that tamp_pclk is connected to rtc_pclk. + * It makes sense to have BBRAM instantiated as a child of RTC, so that + * the driver can verify that its parent device (RTC) is ready. + */ + bbram: backup_regs { + compatible = "st,stm32-bbram"; + st,backup-regs = <5>; + status = "disabled"; + }; }; iwdg: watchdog@40003000 { diff --git a/dts/arm/st/h5/stm32h533.dtsi b/dts/arm/st/h5/stm32h533.dtsi new file mode 100644 index 00000000000000..bd781b87cd9cde --- /dev/null +++ b/dts/arm/st/h5/stm32h533.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/ { + soc { + compatible = "st,stm32h533", "st,stm32h5", "simple-bus"; + + gpiof: gpio@42021400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x42021400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB2 0x00000080>; + }; + }; +}; diff --git a/dts/arm/st/h5/stm32h533Xe.dtsi b/dts/arm/st/h5/stm32h533Xe.dtsi new file mode 100644 index 00000000000000..7b3b530f6a7ef2 --- /dev/null +++ b/dts/arm/st/h5/stm32h533Xe.dtsi @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/ { + sram1: memory@20000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(128)>; + zephyr,memory-region = "SRAM1"; + }; + + sram2: memory@20040000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20040000 DT_SIZE_K(80)>; + zephyr,memory-region = "SRAM2"; + }; + + sram3: memory@20050000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20050000 DT_SIZE_K(64)>; + zephyr,memory-region = "SRAM3"; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(512)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index b8e7a23554bdd3..bab82009a1f592 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -56,6 +56,14 @@ }; }; + backup_sram: memory@40036400 { + compatible = "zephyr,memory-region", "st,stm32-backup-sram"; + reg = <0x40036400 DT_SIZE_K(4)>; + clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x10000000>; + zephyr,memory-region = "BACKUP_SRAM"; + status = "disabled"; + }; + lptim3: timers@44004800 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK_BUS_APB3 0x1000>; @@ -368,6 +376,69 @@ }; }; + timers15: timers@40014000 { + compatible = "st,stm32-timers"; + reg = <0x40014000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00010000>; + resets = <&rctl STM32_RESET(APB2, 16U)>; + interrupts = <71 0>; + interrupt-names = "global"; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers16: timers@40014400 { + compatible = "st,stm32-timers"; + reg = <0x40014400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00020000>; + resets = <&rctl STM32_RESET(APB2, 17U)>; + interrupts = <72 0>; + interrupt-names = "global"; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers17: timers@40014800 { + compatible = "st,stm32-timers"; + reg = <0x40014800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00040000>; + resets = <&rctl STM32_RESET(APB2, 18U)>; + interrupts = <73 0>; + interrupt-names = "global"; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + aes: aes@420c0000 { compatible = "st,stm32-aes"; reg = <0x420c0000 0x400>; diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index 662ecef5da94db..05e596974982cc 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -177,6 +177,15 @@ status = "disabled"; }; }; + + digi_die_temp: digi_dietemp@58006800 { + compatible = "st,stm32-digi-temp"; + reg = <0x58006800 0x400>; + interrupts = <147 0>; + interrupt-names = "digi_temp"; + clocks = <&rcc STM32_CLOCK_BUS_APB4 0x04000000>; + status = "disabled"; + }; }; /* D1 domain, AXI SRAM (128KB with shared ITCM 192KB as `TCM_AXI_SHARED` is `000`) */ diff --git a/dts/arm/st/h7/stm32h7a3.dtsi b/dts/arm/st/h7/stm32h7a3.dtsi index 68f7d82969f545..a9a570e07abafb 100644 --- a/dts/arm/st/h7/stm32h7a3.dtsi +++ b/dts/arm/st/h7/stm32h7a3.dtsi @@ -97,6 +97,15 @@ health-test-magic = <0x17590abc>; health-test-config = <0x72ac>; }; + + digi_die_temp: digi_dietemp@58006800 { + compatible = "st,stm32-digi-temp"; + reg = <0x58006800 0x400>; + interrupts = <147 0>; + interrupt-names = "digi_temp"; + clocks = <&rcc STM32_CLOCK_BUS_APB4 0x04000000>; + status = "disabled"; + }; }; /* System data RAM accessible over AXI bus: AXI SRAM1 in CD domain */ diff --git a/dts/arm/st/h7rs/stm32h7r3.dtsi b/dts/arm/st/h7rs/stm32h7r3.dtsi new file mode 100644 index 00000000000000..57a2c057b92d8d --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7r3.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + + compatible = "st,stm32h7r3", "st,stm32h7rs", "simple-bus"; + + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7r3X8.dtsi b/dts/arm/st/h7rs/stm32h7r3X8.dtsi new file mode 100644 index 00000000000000..5bdb944644816e --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7r3X8.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7r7.dtsi b/dts/arm/st/h7rs/stm32h7r7.dtsi new file mode 100644 index 00000000000000..bdc347798c8cad --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7r7.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * STM32H7R7 line contains the same peripherals as STM32H7R3. + */ +/ { + soc { + compatible = "st,stm32h7r7", "st,stm32h7rs", "simple-bus"; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7r7X8.dtsi b/dts/arm/st/h7rs/stm32h7r7X8.dtsi new file mode 100644 index 00000000000000..3755e88f26bbff --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7r7X8.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi new file mode 100644 index 00000000000000..d0f5712eb263b0 --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -0,0 +1,704 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * STM32H7RS line contains has many common peripherals with STM32H7. + */ + +/ { + chosen { + zephyr,flash-controller = &flash; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + /* System data RAM accessible over AXI bus: AXI SRAM1 in CD domain */ + sram0: memory@24000000 { + compatible = "mmio-sram"; + reg = <0x24000000 DT_SIZE_K(128)>; + }; + + /* System data RAM accessible over AHB bus: SRAM1 in D2 domain */ + sram1: memory@30000000 { + reg = <0x30000000 DT_SIZE_K(16)>; + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "SRAM1"; + }; + + /* System data RAM accessible over AHB bus: SRAM2 in D2 domain */ + sram2: memory@30004000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x30004000 DT_SIZE_K(16)>; + zephyr,memory-region = "SRAM2"; + }; + + dtcm: memory@20000000 { + compatible = "zephyr,memory-region", "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(128)>; + zephyr,memory-region = "DTCM"; + }; + + itcm: memory@0 { + compatible = "zephyr,memory-region", "arm,itcm"; + reg = <0x00000000 DT_SIZE_K(64)>; + zephyr,memory-region = "ITCM"; + }; + + ext_memory: memory@70000000 { + compatible = "zephyr,memory-region"; + reg = <0x70000000 DT_SIZE_M(256)>; + zephyr,memory-region = "EXTMEM"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_EXTMEM) )>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "st,stm32-hse-clock"; + status = "disabled"; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "st,stm32h7-hsi-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_hsi48: clk-hsi48 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_csi: clk-csi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_lse: clk-lse { + #clock-cells = <0>; + compatible = "st,stm32-lse-clock"; + clock-frequency = <32768>; + driving-capability = <0>; + status = "disabled"; + }; + + clk_lsi: clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + pll: pll@0 { + #clock-cells = <0>; + compatible = "st,stm32h7rs-pll-clock"; + reg = <0>; + status = "disabled"; + }; + + pll2: pll@1 { + #clock-cells = <0>; + compatible = "st,stm32h7rs-pll-clock"; + reg = <1>; + status = "disabled"; + }; + + pll3: pll@2 { + #clock-cells = <0>; + compatible = "st,stm32h7rs-pll-clock"; + reg = <2>; + status = "disabled"; + }; + + perck: perck { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + status = "disabled"; + }; + }; + + soc { + flash: flash-controller@52002000 { + compatible = "st,stm32-flash-controller", "st,stm32h7-flash-controller"; + reg = <0x52002000 0x400>; + interrupts = <8 0>; + + #address-cells = <1>; + #size-cells = <1>; + }; + + rcc: rcc@58024400 { + compatible = "st,stm32h7rs-rcc"; + #clock-cells = <2>; + reg = <0x58024400 0x400>; + + rctl: reset-controller { + compatible = "st,stm32-rcc-rctl"; + #reset-cells = <1>; + }; + }; + + exti: interrupt-controller@58000000 { + compatible = "st,stm32h7rs-exti", "st,stm32-exti"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + reg = <0x58000000 0x400>; + /* SBS for interrupt */ + num-lines = <16>; + interrupts = <16 0>, <17 0>, <18 0>, <19 0>, + <20 0>, <21 0>, <22 0>, <23 0>, + <24 0>, <25 0>, <26 0>, <27 0>, + <28 0>, <29 0>, <30 0>, <31 0>; + interrupt-names = "line0", "line1", "line2", "line3", + "line4", "line5", "line6", "line7", + "line8", "line9", "line10", "line11", + "line12", "line13", "line14", "line15"; + line-ranges = <0 1>, <1 1>, <2 1>, <3 1>, + <4 1>, <5 1>, <6 1>, <7 1>, + <8 1>, <9 1>, <10 1>, <11 1>, + <12 1>, <13 1>, <14 1>, <15 1>; + }; + + pinctrl: pin-controller@58020000 { + compatible = "st,stm32-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x58020000 0x2400>; + + gpioa: gpio@58020000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58020000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000001>; + }; + + gpiob: gpio@58020400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58020400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000002>; + }; + + gpioc: gpio@58020800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58020800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000004>; + }; + + gpiod: gpio@58020C00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58020C00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000008>; + }; + + gpioe: gpio@58021000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58021000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000010>; + }; + + gpiof: gpio@58021400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58021400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000020>; + }; + + gpiog: gpio@58021800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58021800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000040>; + }; + + gpioh: gpio@58021c00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58021c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00000080>; + }; + + gpiom: gpio@58023000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58023000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00001000>; + }; + + gpion: gpio@58023400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58023400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00002000>; + }; + + gpioo: gpio@58023800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58023800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00004000>; + }; + + gpiop: gpio@58023c00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x58023c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_AHB4 0x00008000>; + }; + }; + + usart1: serial@42001000 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x42001000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00000010>; + resets = <&rctl STM32_RESET(APB2, 4U)>; + interrupts = <82 0>; + status = "disabled"; + }; + usart2: serial@40004400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00020000>; + resets = <&rctl STM32_RESET(APB1L, 17U)>; + interrupts = <83 0>; + status = "disabled"; + }; + usart3: serial@40004800 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00040000>; + resets = <&rctl STM32_RESET(APB1L, 18U)>; + interrupts = <84 0>; + status = "disabled"; + }; + uart4: serial@40004c00 { + compatible ="st,stm32-uart"; + reg = <0x40004c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00080000>; + resets = <&rctl STM32_RESET(APB1L, 19U)>; + interrupts = <85 0>; + status = "disabled"; + }; + uart5: serial@40005000 { + compatible = "st,stm32-uart"; + reg = <0x40005000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00100000>; + resets = <&rctl STM32_RESET(APB1L, 20U)>; + interrupts = <86 0>; + status = "disabled"; + }; + uart7: serial@40007800 { + compatible = "st,stm32-uart"; + reg = <0x40007800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x40000000>; + resets = <&rctl STM32_RESET(APB1L, 30U)>; + interrupts = <87 0>; + status = "disabled"; + }; + uart8: serial@40007c00 { + compatible = "st,stm32-uart"; + reg = <0x40007c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>; + resets = <&rctl STM32_RESET(APB1L, 31U)>; + interrupts = <88 0>; + status = "disabled"; + }; + + lpuart1: serial@58000c00 { + compatible = "st,stm32-lpuart", "st,stm32-uart"; + reg = <0x58000c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB4 0x00000008>; + resets = <&rctl STM32_RESET(APB4, 3U)>; + interrupts = <131 0>; + status = "disabled"; + }; + + i2c1: i2c@40005400 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>; + interrupts = <76 0>, <77 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + i2c2: i2c@40005800 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00400000>; + interrupts = <78 0>, <79 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + i2c3: i2c@40005c00 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00800000>; + interrupts = <80 0>, <81 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + spi1: spi@42003000 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42003000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_PLL1_Q SPI1_SEL(0)>; + interrupts = <58 0>; + status = "disabled"; + }; + + spi2: spi@40003800 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40003800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00004000>, + <&rcc STM32_SRC_PLL1_Q SPI23_SEL(0)>; + interrupts = <59 0>; + status = "disabled"; + }; + + spi3: spi@40003c00 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40003c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00008000>, + <&rcc STM32_SRC_PLL1_Q SPI23_SEL(0)>; + interrupts = <60 0>; + status = "disabled"; + }; + + spi4: spi@42003400 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42003400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00002000>; + interrupts = <61 0>; + status = "disabled"; + }; + + spi5: spi@42005000 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42005000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00100000>; + interrupts = <62 0>; + status = "disabled"; + }; + + i2s1: i2s@40013000 { + compatible = "st,stm32h7-i2s", "st,stm32-i2s"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40013000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_PLL1_Q SPI1_SEL(0)>; + interrupts = <35 3>; + status = "disabled"; + }; + + timers1: timers@42000000 { + compatible = "st,stm32-timers"; + reg = <0x42000000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00000001>; + resets = <&rctl STM32_RESET(APB2, 0U)>; + interrupts = <47 0>, <48 0>, <49 0>, <50 0>; + interrupt-names = "brk", "up", "trgcom", "cc"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timers2: timers@40000000 { + compatible = "st,stm32-timers"; + reg = <0x40000000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000001>; + resets = <&rctl STM32_RESET(APB1L, 0U)>; + interrupts = <51 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers3: timers@40000400 { + compatible = "st,stm32-timers"; + reg = <0x40000400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000002>; + resets = <&rctl STM32_RESET(APB1L, 1U)>; + interrupts = <52 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers4: timers@40000800 { + compatible = "st,stm32-timers"; + reg = <0x40000800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000004>; + resets = <&rctl STM32_RESET(APB1L, 2U)>; + interrupts = <53 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers5: timers@40000c00 { + compatible = "st,stm32-timers"; + reg = <0x40000c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000008>; + resets = <&rctl STM32_RESET(APB1L, 3U)>; + interrupts = <54 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers6: timers@40001000 { + compatible = "st,stm32-timers"; + reg = <0x40001000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000010>; + resets = <&rctl STM32_RESET(APB1L, 4U)>; + interrupts = <55 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers7: timers@40001400 { + compatible = "st,stm32-timers"; + reg = <0x40001400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000020>; + resets = <&rctl STM32_RESET(APB1L, 5U)>; + interrupts = <56 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers9: timers@42004c00 { + compatible = "st,stm32-timers"; + reg = <0x42004c00 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00080000>; + resets = <&rctl STM32_RESET(APB2, 19U)>; + interrupts = <57 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers15: timers@42004000 { + compatible = "st,stm32-timers"; + reg = <0x42004000 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00010000>; + resets = <&rctl STM32_RESET(APB2, 16U)>; + interrupts = <116 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers16: timers@42004400 { + compatible = "st,stm32-timers"; + reg = <0x42004400 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00020000>; + resets = <&rctl STM32_RESET(APB2, 17U)>; + interrupts = <117 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers17: timers@42004800 { + compatible = "st,stm32-timers"; + reg = <0x42004800 0x400>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00040000>; + resets = <&rctl STM32_RESET(APB2, 18U)>; + interrupts = <118 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + lptim1: timers@40002400 { + compatible = "st,stm32-lptim"; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000200>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40002400 0x400>; + interrupts = <119 1>; + interrupt-names = "wakeup"; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/st/h7rs/stm32h7s3.dtsi b/dts/arm/st/h7rs/stm32h7s3.dtsi new file mode 100644 index 00000000000000..f1d490266b7dd8 --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7s3.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * STM32H7S3 line contains the same peripherals as STM32H7R3. + */ +/ { + soc { + compatible = "st,stm32h7s3", "st,stm32h7rs", "simple-bus"; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7s3X8.dtsi b/dts/arm/st/h7rs/stm32h7s3X8.dtsi new file mode 100644 index 00000000000000..4eca0e58ab2c7e --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7s3X8.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7s7.dtsi b/dts/arm/st/h7rs/stm32h7s7.dtsi new file mode 100644 index 00000000000000..7566df2cfe9c84 --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7s7.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* + * STM32H7S7 line contains the same peripherals as STM32H7R7. + */ +/ { + soc { + compatible = "st,stm32h7s7", "st,stm32h7rs", "simple-bus"; + }; +}; diff --git a/dts/arm/st/h7rs/stm32h7s7X8.dtsi b/dts/arm/st/h7rs/stm32h7s7X8.dtsi new file mode 100644 index 00000000000000..2c31b66b586e38 --- /dev/null +++ b/dts/arm/st/h7rs/stm32h7s7X8.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index e6e87879b95a41..03e7734f759425 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include #include / { @@ -469,6 +470,39 @@ <&rcc STM32_SRC_MSI CLK48_SEL(3)>; status = "disabled"; }; + + pwr: power@40007000 { + compatible = "st,stm32-pwr"; + reg = <0x40007000 0x400>; /* PWR register bank */ + status = "disabled"; + + wkup-pins-nb = <5>; /* 5 system wake-up pins */ + wkup-pins-pol; + wkup-pins-pupd; + + #address-cells = <1>; + #size-cells = <0>; + + wkup-pin@1 { + reg = <0x1>; + }; + + wkup-pin@2 { + reg = <0x2>; + }; + + wkup-pin@3 { + reg = <0x3>; + }; + + wkup-pin@4 { + reg = <0x4>; + }; + + wkup-pin@5 { + reg = <0x5>; + }; + }; }; die_temp: dietemp { diff --git a/dts/arm/st/l4/stm32l4r5Xi.dtsi b/dts/arm/st/l4/stm32l4r5Xi.dtsi index 9154d8820f8be1..5da6f035e76936 100644 --- a/dts/arm/st/l4/stm32l4r5Xi.dtsi +++ b/dts/arm/st/l4/stm32l4r5Xi.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Pushpal Sidhu + * Copyright (c) 2024 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,3 +17,25 @@ }; }; }; + +&pwr { + wkup-pin@1 { + wkup-gpios = <&gpioa 0 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@2 { + wkup-gpios = <&gpioc 13 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@3 { + wkup-gpios = <&gpioe 6 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@4 { + wkup-gpios = <&gpioa 2 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@5 { + wkup-gpios = <&gpioc 5 STM32_PWR_WKUP_PIN_SRC_0>; + }; +}; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 642431a52ecaef..4a7f2a1fe43874 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -19,6 +19,7 @@ #include #include #include +#include #include / { @@ -841,6 +842,76 @@ }; }; + pwr: power@46020800 { + compatible = "st,stm32-pwr"; + reg = <0x46020800 0x400>; /* PWR register bank */ + status = "disabled"; + + wkup-pins-nb = <8>; /* 8 system wake-up pins */ + wkup-pin-srcs = <3>; /* 3 gpio sources associated with each wkup pin */ + wkup-pins-pol; + wkup-pins-pupd; + + #address-cells = <1>; + #size-cells = <0>; + + wkup-pin@1 { + reg = <0x1>; + wkup-gpios = <&gpioa 0 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpiob 2 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpioe 4 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@2 { + reg = <0x2>; + wkup-gpios = <&gpioa 4 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioc 13 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpioe 5 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@3 { + reg = <0x3>; + wkup-gpios = <&gpioe 6 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioa 1 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpiob 6 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@4 { + reg = <0x4>; + wkup-gpios = <&gpioa 2 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpiob 1 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpiob 7 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@5 { + reg = <0x5>; + wkup-gpios = <&gpioc 5 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioa 3 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpiob 8 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@6 { + reg = <0x6>; + wkup-gpios = <&gpiob 5 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioa 5 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpioe 7 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@7 { + reg = <0x7>; + wkup-gpios = <&gpiob 15 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioa 6 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpioe 8 STM32_PWR_WKUP_PIN_SRC_2>; + }; + + wkup-pin@8 { + reg = <0x8>; + wkup-gpios = <&gpiof 2 STM32_PWR_WKUP_PIN_SRC_0>, + <&gpioa 7 STM32_PWR_WKUP_PIN_SRC_1>, + <&gpiob 10 STM32_PWR_WKUP_PIN_SRC_2>; + }; + }; + }; swj_port: swj_port { diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index acd8d3c0fd89fe..fa0c3304fe287a 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -16,12 +16,14 @@ #include #include #include +#include #include / { chosen { zephyr,entropy = &rng; zephyr,flash-controller = &flash; + zephyr,bt-hci = &ble_rf; }; cpus { @@ -512,6 +514,29 @@ interrupts = <51 0>; status = "disabled"; }; + + pwr: power@58000400 { + compatible = "st,stm32-pwr"; + reg = <0x58000400 0x400>; /* PWR register bank */ + status = "disabled"; + + wkup-pins-nb = <5>; /* 5 system wake-up pins */ + wkup-pins-pol; + wkup-pins-pupd; + + #address-cells = <1>; + #size-cells = <0>; + + wkup-pin@1 { + reg = <0x1>; + wkup-gpios = <&gpioa 0 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@4 { + reg = <0x4>; + wkup-gpios = <&gpioa 2 STM32_PWR_WKUP_PIN_SRC_0>; + }; + }; }; die_temp: dietemp { diff --git a/dts/arm/st/wb/stm32wb55Xg.dtsi b/dts/arm/st/wb/stm32wb55Xg.dtsi index 91592e8778df38..c3a7d391e77522 100644 --- a/dts/arm/st/wb/stm32wb55Xg.dtsi +++ b/dts/arm/st/wb/stm32wb55Xg.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Linaro Limited + * Copyright (c) 2024 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,3 +20,20 @@ }; }; }; + +&pwr { + wkup-pin@2 { + reg = <0x2>; + wkup-gpios = <&gpioc 13 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@3 { + reg = <0x3>; + wkup-gpios = <&gpioc 12 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@5 { + reg = <0x5>; + wkup-gpios = <&gpioc 5 STM32_PWR_WKUP_PIN_SRC_0>; + }; +}; diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index 05efb0a9431e18..5b402ae9501c57 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -23,6 +23,7 @@ zephyr,entropy = &rng; zephyr,flash-controller = &flash; st,lptim-stdby-timer = &rtc; + zephyr,bt-hci = &bt_hci_wba; }; cpus { @@ -472,6 +473,11 @@ }; }; + bt_hci_wba: bt_hci_wba { + compatible = "st,hci-stm32wba"; + status = "okay"; + }; + swj_port: swj_port { compatible = "swj-connector"; pinctrl-0 = <&debug_jtms_swdio_pa13 &debug_jtck_swclk_pa14 diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index 9ef2a41969a678..fae199c6f6302b 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -15,6 +15,7 @@ #include #include #include +#include #include / { @@ -498,6 +499,34 @@ dma-requests= <38>; status = "disabled"; }; + + pwr: power@58000400 { + compatible = "st,stm32-pwr"; + reg = <0x58000400 0x400>; /* PWR register bank */ + status = "disabled"; + + wkup-pins-nb = <3>; /* 3 system wake-up pins */ + wkup-pins-pol; + wkup-pins-pupd; + + #address-cells = <1>; + #size-cells = <0>; + + wkup-pin@1 { + reg = <0x1>; + wkup-gpios = <&gpioa 0 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@2 { + reg = <0x2>; + wkup-gpios = <&gpioc 13 STM32_PWR_WKUP_PIN_SRC_0>; + }; + + wkup-pin@3 { + reg = <0x3>; + wkup-gpios = <&gpiob 3 STM32_PWR_WKUP_PIN_SRC_0>; + }; + }; }; die_temp: dietemp { diff --git a/dts/arm/ti/cc13xx_cc26xx.dtsi b/dts/arm/ti/cc13xx_cc26xx.dtsi index 5c67e9df3f4e97..3cdf6b5d578923 100644 --- a/dts/arm/ti/cc13xx_cc26xx.dtsi +++ b/dts/arm/ti/cc13xx_cc26xx.dtsi @@ -105,7 +105,7 @@ pwm0: pwm { compatible = "ti,cc13xx-cc26xx-timer-pwm"; - #pwm-cells = <1>; + #pwm-cells = <3>; status = "disabled"; }; }; @@ -119,7 +119,7 @@ pwm1: pwm { compatible = "ti,cc13xx-cc26xx-timer-pwm"; - #pwm-cells = <1>; + #pwm-cells = <3>; status = "disabled"; }; }; @@ -133,7 +133,7 @@ pwm2: pwm { compatible = "ti,cc13xx-cc26xx-timer-pwm"; - #pwm-cells = <1>; + #pwm-cells = <3>; status = "disabled"; }; }; @@ -147,7 +147,7 @@ pwm3: pwm { compatible = "ti,cc13xx-cc26xx-timer-pwm"; - #pwm-cells = <1>; + #pwm-cells = <3>; status = "disabled"; }; }; diff --git a/dts/bindings/adc/nordic,nrf-saadc.yaml b/dts/bindings/adc/nordic,nrf-saadc.yaml index f41cf2c048e870..ebb3a889692fc7 100644 --- a/dts/bindings/adc/nordic,nrf-saadc.yaml +++ b/dts/bindings/adc/nordic,nrf-saadc.yaml @@ -5,7 +5,7 @@ description: Nordic Semiconductor nRF family SAADC node compatible: "nordic,nrf-saadc" -include: adc-controller.yaml +include: ["adc-controller.yaml", "memory-region.yaml"] properties: reg: diff --git a/dts/bindings/arm/nordic,nrf-resetinfo.yaml b/dts/bindings/arm/nordic,nrf-resetinfo.yaml new file mode 100644 index 00000000000000..c8585e5897e505 --- /dev/null +++ b/dts/bindings/arm/nordic,nrf-resetinfo.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic RESETINFO (Reset Information) + +compatible: "nordic,nrf-resetinfo" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/base/pm.yaml b/dts/bindings/base/pm.yaml index 0776170d8f205c..50c016d07bd127 100644 --- a/dts/bindings/base/pm.yaml +++ b/dts/bindings/base/pm.yaml @@ -30,3 +30,8 @@ properties: description: | Automatically configure the device for runtime power management after the init function runs. + + zephyr,disabling-power-states: + type: phandles + description: | + List of power states that will disable this device power. diff --git a/dts/bindings/bluetooth/ambiq,bt-hci-spi.yaml b/dts/bindings/bluetooth/ambiq,bt-hci-spi.yaml index 42df66d2180941..cbaabb318c1b5c 100644 --- a/dts/bindings/bluetooth/ambiq,bt-hci-spi.yaml +++ b/dts/bindings/bluetooth/ambiq,bt-hci-spi.yaml @@ -7,6 +7,8 @@ description: | compatible: "ambiq,bt-hci-spi" +include: bt-hci.yaml + properties: reg: type: array @@ -30,3 +32,9 @@ properties: controller. The host needs to enable XO32MHz when receiving low to high edge interrupts and disable XO32MHz when receiving high to low edge interrupts. + + bt-hci-name: + default: "ambiq hci" + + bt-hci-bus: + default: "BT_HCI_BUS_SPI" diff --git a/dts/bindings/bluetooth/bt-hci.yaml b/dts/bindings/bluetooth/bt-hci.yaml new file mode 100644 index 00000000000000..e53b9022e9069f --- /dev/null +++ b/dts/bindings/bluetooth/bt-hci.yaml @@ -0,0 +1,28 @@ +# Common fields for Bluetooth HCI devices + +include: base.yaml + +properties: + bt-hci-name: + type: string + description: Name of the HCI transport + bt-hci-bus: + type: string + description: Bus of the transport + enum: + - "BT_HCI_BUS_VIRTUAL" + - "BT_HCI_BUS_USB" + - "BT_HCI_BUS_PCCARD" + - "BT_HCI_BUS_UART" + - "BT_HCI_BUS_RS232" + - "BT_HCI_BUS_PCI" + - "BT_HCI_BUS_SDIO" + - "BT_HCI_BUS_SPI" + - "BT_HCI_BUS_I2C" + - "BT_HCI_BUS_IPM" + bt-hci-quirks: + type: string-array + description: HCI device quirks + bt-hci-vs-ext: + type: boolean + description: Zephyr HCI vendor extensions are supported diff --git a/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml b/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml new file mode 100644 index 00000000000000..e095fcd9510a4c --- /dev/null +++ b/dts/bindings/bluetooth/espressif,esp32-bt-hci.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI for Espressif ESP32 + +compatible: "espressif,esp32-bt-hci" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "BT ESP32" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_AUTO_DLE"] diff --git a/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml b/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml index 0d38855c00edb5..80671e581350eb 100644 --- a/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml +++ b/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml @@ -8,8 +8,14 @@ description: | compatible: "infineon,cat1-bless-hci" -include: base.yaml +include: bt-hci.yaml properties: + bt-hci-name: + default: "PSoC 6 BLESS" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_RESET"] interrupts: required: true diff --git a/dts/bindings/bluetooth/infineon,cyw208xx-hci.yaml b/dts/bindings/bluetooth/infineon,cyw208xx-hci.yaml new file mode 100644 index 00000000000000..be3cb559be4b3b --- /dev/null +++ b/dts/bindings/bluetooth/infineon,cyw208xx-hci.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bluetooth module that uses Infineon CYW208XX HCI bluetooth interface + + NOTE: + cyw920829 requires fetch binary files of Bluetooth controller firmware. + To fetch Binary Blobs: west blobs fetch hal_infineon + +compatible: "infineon,cyw208xx-hci" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "CYW208XX" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" diff --git a/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml b/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml new file mode 100644 index 00000000000000..362c540507255d --- /dev/null +++ b/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml @@ -0,0 +1,50 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bluetooth module that uses NXP's Bluetooth Module (e.g. Murata 2EL) + +compatible: "nxp,bt-hci-uart" + +include: base.yaml + +properties: + sdio-reset-gpios: + type: phandle-array + required: true + + w-disable-gpios: + type: phandle-array + required: true + + hci-operation-speed: + type: int + description: | + HCI UART baudrate for feature operation. If not defined + bus/current-speed will be used as default. + + hw-flow-control: + type: boolean + description: Set to enable RTS/CTS flow control for HCI. + + fw-download-primary-speed: + type: int + description: | + HCI UART primary baudrate for FW download operation. + If not defined bus/current-speed will be used as default. + + fw-download-primary-flowcontrol: + type: boolean + description: | + Flow control setting for primary speed. + + fw-download-secondary-speed: + type: int + description: | + HCI UART secondary baudrate for FW download operation. + If not defined bus/current-speed will be used as default. + + fw-download-secondary-flowcontrol: + type: boolean + description: | + Flow control setting for secondary speed. diff --git a/dts/bindings/arm/nxp,hci-ble.yaml b/dts/bindings/bluetooth/nxp,hci-ble.yaml similarity index 62% rename from dts/bindings/arm/nxp,hci-ble.yaml rename to dts/bindings/bluetooth/nxp,hci-ble.yaml index 7620ec8eb6988b..f2c05c2fda1d9c 100644 --- a/dts/bindings/arm/nxp,hci-ble.yaml +++ b/dts/bindings/bluetooth/nxp,hci-ble.yaml @@ -5,8 +5,12 @@ description: NXP BLE HCI information compatible: "nxp,hci-ble" -include: base.yaml +include: bt-hci.yaml properties: interrupts: required: true + bt-hci-name: + default: "BT NXP" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" diff --git a/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml b/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml new file mode 100644 index 00000000000000..cd66b0119538b7 --- /dev/null +++ b/dts/bindings/bluetooth/renesas,bt-hci-da1469x.yaml @@ -0,0 +1,11 @@ +description: Bluetooth HCI for Renesas DA1469x + +compatible: "renesas,bt-hci-da1469x" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "BT DA1469x" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" diff --git a/dts/bindings/bluetooth/silabs,bt-hci.yaml b/dts/bindings/bluetooth/silabs,bt-hci.yaml new file mode 100644 index 00000000000000..9dc5b67947c581 --- /dev/null +++ b/dts/bindings/bluetooth/silabs,bt-hci.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI on Silabs boards + +compatible: "silabs,bt-hci" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "sl:bt" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_RESET"] diff --git a/dts/bindings/bluetooth/st,hci-spi-v1.yaml b/dts/bindings/bluetooth/st,hci-spi-v1.yaml index 3784c88ded047c..020a796af85f0c 100644 --- a/dts/bindings/bluetooth/st,hci-spi-v1.yaml +++ b/dts/bindings/bluetooth/st,hci-spi-v1.yaml @@ -6,3 +6,7 @@ description: STMicroelectronics SPI protocol V1 compatible with BlueNRG-MS devic compatible: "st,hci-spi-v1" include: zephyr,bt-hci-spi.yaml + +properties: + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_RESET"] diff --git a/dts/bindings/bluetooth/st,hci-spi-v2.yaml b/dts/bindings/bluetooth/st,hci-spi-v2.yaml index 36b25eae768946..97b62dc90bd82d 100644 --- a/dts/bindings/bluetooth/st,hci-spi-v2.yaml +++ b/dts/bindings/bluetooth/st,hci-spi-v2.yaml @@ -6,3 +6,7 @@ description: STMicroelectronics SPI protocol V2 compatible with BlueNRG-1 and su compatible: "st,hci-spi-v2" include: zephyr,bt-hci-spi.yaml + +properties: + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_RESET"] diff --git a/dts/bindings/bluetooth/st,hci-stm32wba.yaml b/dts/bindings/bluetooth/st,hci-stm32wba.yaml new file mode 100644 index 00000000000000..ea7c8dbbcc7358 --- /dev/null +++ b/dts/bindings/bluetooth/st,hci-stm32wba.yaml @@ -0,0 +1,11 @@ +description: Bluetooth HCI driver for ST STM32WBA + +compatible: "st,hci-stm32wba" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "BT IPM" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" diff --git a/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml b/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml index 51b46cbff17383..f1903de684000b 100644 --- a/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml +++ b/dts/bindings/bluetooth/st,stm32wb-ble-rf.yaml @@ -6,8 +6,12 @@ description: | compatible: "st,stm32wb-rf" -include: base.yaml +include: bt-hci.yaml properties: - clocks: - required: true + clocks: + required: true + bt-hci-name: + default: "BT IPM" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-3wire-uart.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-3wire-uart.yaml new file mode 100644 index 00000000000000..d2a5f62c2137d2 --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-3wire-uart.yaml @@ -0,0 +1,13 @@ +# UART Bluetooth HCI device + +description: Bluetooth HCI behind a 3-Wire UART device (H:5) + +compatible: "zephyr,bt-hci-3wire-uart" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "H:5" + bt-hci-bus: + default: "BT_HCI_BUS_UART" diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-ipc.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-ipc.yaml new file mode 100644 index 00000000000000..88780827ce47e2 --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-ipc.yaml @@ -0,0 +1,17 @@ +description: Bluetooth HCI using the IPC subsystem + +compatible: "zephyr,bt-hci-ipc" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "IPC" + bt-hci-bus: + default: "BT_HCI_BUS_IPM" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_AUTO_DLE"] + bt-hci-ipc-name: + type: string + default: "nrf_bt_hci" + description: IPC endpoint name diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml new file mode 100644 index 00000000000000..f53cf49e90e053 --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-ll-sw-split.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI provided by the native Zephyr Bluetooth Controller + +compatible: "zephyr,bt-hci-ll-sw-split" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "Controller" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_AUTO_DLE"] diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml index 50d0e311461b50..0447e69d5f19f0 100644 --- a/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml +++ b/dts/bindings/bluetooth/zephyr,bt-hci-spi.yaml @@ -7,7 +7,7 @@ description: | compatible: "zephyr,bt-hci-spi" -include: spi-device.yaml +include: [spi-device.yaml, bt-hci.yaml] properties: irq-gpios: @@ -35,3 +35,9 @@ properties: resulting in an ignored transaction that then needs to be performed a second time. The default of 20uS was chosen as the lowest delay that reliably eliminated double transactions between a nRF9160 host and a nRF52832 controller. + + bt-hci-name: + default: "SPI" + + bt-hci-bus: + default: "BT_HCI_BUS_SPI" diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-uart.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-uart.yaml new file mode 100644 index 00000000000000..d14f8e3035648e --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-uart.yaml @@ -0,0 +1,13 @@ +# UART Bluetooth HCI device + +description: Bluetooth HCI behind a UART device (H:4) + +compatible: "zephyr,bt-hci-uart" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "H:4" + bt-hci-bus: + default: "BT_HCI_BUS_UART" diff --git a/dts/bindings/bluetooth/zephyr,bt-hci-userchan.yaml b/dts/bindings/bluetooth/zephyr,bt-hci-userchan.yaml new file mode 100644 index 00000000000000..124a2983532750 --- /dev/null +++ b/dts/bindings/bluetooth/zephyr,bt-hci-userchan.yaml @@ -0,0 +1,11 @@ +description: Bluetooth HCI provided by a Linux HCI user channel socket + +compatible: "zephyr,bt-hci-userchan" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "HCI User Channel" + bt-hci-bus: + default: "BT_HCI_BUS_UART" diff --git a/dts/bindings/can/can-controller.yaml b/dts/bindings/can/can-controller.yaml index 55322b50a21e9d..e2825b6e6763b8 100644 --- a/dts/bindings/can/can-controller.yaml +++ b/dts/bindings/can/can-controller.yaml @@ -4,6 +4,14 @@ include: base.yaml properties: bus-speed: + type: int + deprecated: true + description: | + Deprecated. This property has been renamed to bitrate. + + Initial bitrate in bit/s. If this is unset, the initial bitrate is set to + CONFIG_CAN_DEFAULT_BITRATE. + bitrate: type: int description: | Initial bitrate in bit/s. If this is unset, the initial bitrate is set to diff --git a/dts/bindings/can/can-fd-controller.yaml b/dts/bindings/can/can-fd-controller.yaml index 9efc7823f94fd4..ea357b832240e3 100644 --- a/dts/bindings/can/can-fd-controller.yaml +++ b/dts/bindings/can/can-fd-controller.yaml @@ -4,6 +4,14 @@ include: can-controller.yaml properties: bus-speed-data: + type: int + deprecated: true + description: | + Deprecated. This property has been renamed to bitrate-data. + + Initial data phase bitrate in bit/s. If this is unset, the initial data phase bitrate is set + to CONFIG_CAN_DEFAULT_BITRATE_DATA. + bitrate-data: type: int description: | Initial data phase bitrate in bit/s. If this is unset, the initial data phase bitrate is set diff --git a/dts/bindings/can/zephyr,can-loopback.yaml b/dts/bindings/can/zephyr,can-loopback.yaml index 531c6d965bf8c0..af93433bf041b6 100644 --- a/dts/bindings/can/zephyr,can-loopback.yaml +++ b/dts/bindings/can/zephyr,can-loopback.yaml @@ -5,4 +5,4 @@ description: Zephyr emulated CAN loopback controller compatible: "zephyr,can-loopback" -include: can-controller.yaml +include: can-fd-controller.yaml diff --git a/dts/bindings/can/zephyr,native-linux-can.yaml b/dts/bindings/can/zephyr,native-linux-can.yaml index 4175617403b34f..b854984ece08a2 100644 --- a/dts/bindings/can/zephyr,native-linux-can.yaml +++ b/dts/bindings/can/zephyr,native-linux-can.yaml @@ -5,7 +5,7 @@ description: Zephyr CAN driver using Linux SocketCAN compatible: "zephyr,native-linux-can" -include: can-controller.yaml +include: can-fd-controller.yaml properties: host-interface: diff --git a/dts/bindings/clock/st,stm32f3-rcc.yaml b/dts/bindings/clock/st,stm32f3-rcc.yaml index ca0e57dc7193e8..64851cdaf59dab 100644 --- a/dts/bindings/clock/st,stm32f3-rcc.yaml +++ b/dts/bindings/clock/st,stm32f3-rcc.yaml @@ -31,6 +31,7 @@ properties: ADC 1 and 2 prescaler - 0: Disables the clock so the ADC can use AHB clock (synchronous mode) - Other values n: The ADC can use the PLL clock divided by n + On STM32F37x, only 2/4/6/8 are allowed. adc34-prescaler: type: int diff --git a/dts/bindings/clock/st,stm32h7rs-pll-clock.yaml b/dts/bindings/clock/st,stm32h7rs-pll-clock.yaml new file mode 100644 index 00000000000000..cb2980dd39c5a3 --- /dev/null +++ b/dts/bindings/clock/st,stm32h7rs-pll-clock.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + PLL node binding for STM32H7RS devices + + It can be used to describe 3 different PLLs: PLL1 (Main PLL), PLL2 and PLL3. + + These PLLs could take one of clk_hse, clk_hsi or clk_csi as input clock, with + an input frequency from 1 to 16 MHz. PLLM factor is used to set the input + clock in this acceptable range. + + Each PLL can have up to 5 output clocks and for each output clock, the + frequency can be computed with the following formulae: + + f(PLL_Px) = f(VCOx clock) / PLLPx -> pllx_p_ck ((pll1_p_ck : sys_ck)) + f(PLL_Qx) = f(VCOx clock) / PLLQx -> pllx_q_ck + f(PLL_Rx) = f(VCOx clock) / PLLRx -> pllx_r_ck + f(PLL_Sx) = f(VCOx clock) / PLLSx -> pllx_s_ck + f(PLL_Tx) = f(VCOx clock) / PLLTx -> pllx_t_ck (only for PLL2) + + with f(VCOx clock) = f(REFx_CK) × (PLLNx / PLLMx) + + +compatible: "st,stm32h7rs-pll-clock" + +include: st,stm32h7-pll-clock.yaml + +properties: + div-s: + type: int + description: | + PLL division factor for pllx_s_ck : valid for PLL1, 2, 3 + Valid range: 1 - 8 + + div-t: + type: int + description: | + PLL division factor for pllx_t_ck : valid for PLL2 + Valid range: 1 - 8 diff --git a/dts/bindings/clock/st,stm32h7rs-rcc.yaml b/dts/bindings/clock/st,stm32h7rs-rcc.yaml new file mode 100644 index 00000000000000..780c84564f447b --- /dev/null +++ b/dts/bindings/clock/st,stm32h7rs-rcc.yaml @@ -0,0 +1,135 @@ +# Copyright (c) 2024, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32 Reset and Clock controller node for STM32H7RS devices + This node is in charge of system clock ('SYSCLK') source selection and + System Clock Generation. + + Configuring STM32 Reset and Clock controller node: + + System clock source should be selected amongst the clock nodes available in "clocks" + node (typically 'clk_hse, clk_csi', 'pll', ...). + As part of this node configuration, SYSCLK frequency should also be defined, using + "clock-frequency" property. + Last, bus clocks (typically HCLK, PCLK1, PCLK2) should be configured using matching + prescaler properties. + Here is an example of correctly configured rcc node: + &rcc { + clocks = <&pll>; /* Set pll as SYSCLK source */ + clock-frequency = ; /* SYSCLK runs at 280MHz */ + dcpre = <1>; + hpre = <1>; + ppre1 = <1>; + ppre2 = <1>; + ppre4 = <1>; + ppre5 = <1>; + } + + Confere st,stm32-rcc binding for information about domain clocks configuration. + +compatible: "st,stm32h7rs-rcc" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 2 + + clock-frequency: + required: true + type: int + description: | + default frequency in Hz for clock output + + dcpre: + type: int + required: true + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 64 + - 128 + - 256 + - 512 + description: | + CPU clock prescaler. Sets a HCLK frequency (feeding Cortex-M Systick) + lower than SYSCLK frequency (actual core frequency). + Zephyr doesn't make a difference today between these two clocks. + Changing this prescaler is not allowed until it is made possible to + use them independently in Zephyr clock subsystem. + + hpre: + type: int + required: true + description: | + peripheral clock to the Bus Matrix APB (1/2/4/5) and AHB(1/2/3/4/5) peripheral + divider of the CPU clock by this prescaler (BMPRE register) + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 64 + - 128 + - 256 + - 512 + + ppre1: + type: int + required: true + description: | + APB1 peripheral prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + + ppre2: + type: int + required: true + description: | + APB2 peripheral prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + + ppre4: + type: int + required: true + description: | + APB4 peripheral prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + + ppre5: + type: int + required: true + description: | + APB5 peripheral prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + +clock-cells: + - bus + - bits diff --git a/dts/bindings/counter/nxp,lptmr.yaml b/dts/bindings/counter/nxp,lptmr.yaml index 13e38d76302f9b..d44fcb5ef5443a 100644 --- a/dts/bindings/counter/nxp,lptmr.yaml +++ b/dts/bindings/counter/nxp,lptmr.yaml @@ -29,3 +29,8 @@ properties: active-low: type: boolean description: Pulse counter input pin is active-low + + resolution: + type: int + required: true + description: Represents the width of the timer in bits. diff --git a/dts/bindings/display/ilitek,ili9xxx-common.yaml b/dts/bindings/display/ilitek,ili9xxx-common.yaml index 802250002d6048..6a657399140e61 100644 --- a/dts/bindings/display/ilitek,ili9xxx-common.yaml +++ b/dts/bindings/display/ilitek,ili9xxx-common.yaml @@ -28,6 +28,7 @@ properties: - 270 description: Display rotation (CW) in degrees. + If not defined, rotation is off by default. display-inversion: type: boolean diff --git a/dts/bindings/display/sitronix,st7789v.yaml b/dts/bindings/display/sitronix,st7789v.yaml index ec72e18d7f9777..9b503eb86bafa8 100644 --- a/dts/bindings/display/sitronix,st7789v.yaml +++ b/dts/bindings/display/sitronix,st7789v.yaml @@ -6,29 +6,9 @@ description: ST7789V 320x240 display controller compatible: "sitronix,st7789v" -include: [spi-device.yaml, display-controller.yaml] +include: [mipi-dbi-spi-device.yaml, display-controller.yaml] properties: - reset-gpios: - type: phandle-array - description: | - RESET pin. - - The RESET pin of ST7789V is active low. - If connected directly the MCU pin should be configured - as active low. - - cmd-data-gpios: - type: phandle-array - description: | - D/CX pin. If configured, 4-lines serial interface is used, otherwise - 3-lines serial interface is used and a D/CX bit (9-bit) is added to - the protocol. - - The D/CX pin of ST7789V is active low (transmission command byte). - If connected directly the MCU pin should be configured - as active low. - x-offset: type: int required: true @@ -115,3 +95,6 @@ properties: type: uint8-array required: true description: RGB Interface Control Parameter + + mipi-mode: + required: true diff --git a/dts/bindings/display/solomon,ssd16xx-common.yaml b/dts/bindings/display/solomon,ssd16xx-common.yaml index dd5b651e8feaf7..34911dbc18b57f 100644 --- a/dts/bindings/display/solomon,ssd16xx-common.yaml +++ b/dts/bindings/display/solomon,ssd16xx-common.yaml @@ -10,10 +10,6 @@ properties: type: uint8-array description: Booster soft start values - orientation-flipped: - type: boolean - description: Last column address is mapped to first segment - reset-gpios: type: phandle-array required: true @@ -49,6 +45,18 @@ properties: an external temperature sensor is connected to the controller. The value selects which sensor should be used. + rotation: + type: int + default: 0 + enum: + - 0 + - 90 + - 180 + - 270 + description: + Display rotation (CW) in degrees. + If not defined, rotation is off by default. + child-binding: description: | Child nodes describe refresh profiles. Each refresh profile diff --git a/dts/bindings/dma/raspberrypi,pico-dma.yaml b/dts/bindings/dma/raspberrypi,pico-dma.yaml index 35960fbca7fe9f..10263958b1372f 100644 --- a/dts/bindings/dma/raspberrypi,pico-dma.yaml +++ b/dts/bindings/dma/raspberrypi,pico-dma.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Raspberry Pi Pico GPIO + Raspberry Pi Pico DMA channel: Select channel for data transmitting @@ -30,7 +30,7 @@ properties: irq0-channels: type: uint8-array - default: [0, 2, 4, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] + default: [0, 2, 4, 6, 8, 10] description: Channels list that uses the irq0 "#dma-cells": diff --git a/dts/bindings/dma/renesas,smartbond-dma.yaml b/dts/bindings/dma/renesas,smartbond-dma.yaml index 0845df77463249..388efb236ebf0f 100644 --- a/dts/bindings/dma/renesas,smartbond-dma.yaml +++ b/dts/bindings/dma/renesas,smartbond-dma.yaml @@ -19,3 +19,14 @@ properties: type: int const: 1 description: Number of block counts supported + + "#dma-cells": + const: 2 + +# - #dma-cells : Must be <2>. +# channel: dma channel to be reserved +# config: peripheral's dma request line. Valid values are defined in dt-bindings/dma/dma_smartbond.h + +dma-cells: + - channel + - config diff --git a/dts/bindings/ethernet/ethernet-controller.yaml b/dts/bindings/ethernet/ethernet-controller.yaml index 8823459d3a9ebc..bb4fa794152bef 100644 --- a/dts/bindings/ethernet/ethernet-controller.yaml +++ b/dts/bindings/ethernet/ethernet-controller.yaml @@ -36,3 +36,4 @@ properties: - "mii" - "rmii" - "gmii" + - "rgmii" diff --git a/dts/bindings/ethernet/microchip,ksz8081.yaml b/dts/bindings/ethernet/microchip,ksz8081.yaml index 83a6be9f72d99b..7667fca85314bd 100644 --- a/dts/bindings/ethernet/microchip,ksz8081.yaml +++ b/dts/bindings/ethernet/microchip,ksz8081.yaml @@ -8,15 +8,13 @@ compatible: "microchip,ksz8081" include: ethernet-phy.yaml properties: - mc,reset-gpio: + reset-gpios: type: phandle-array - specifier-space: gpio description: GPIO connected to PHY reset signal pin. Reset is active low. - mc,interrupt-gpio: + int-gpios: type: phandle-array - specifier-space: gpio description: GPIO for interrupt signal indicating PHY state change. - mc,interface-type: + microchip,interface-type: type: string required: true description: Which type of phy connection the phy is set up for diff --git a/dts/bindings/ethernet/nxp,enet-mac.yaml b/dts/bindings/ethernet/nxp,enet-mac.yaml index cf8ca151e46c14..b6b7aaff10ad45 100644 --- a/dts/bindings/ethernet/nxp,enet-mac.yaml +++ b/dts/bindings/ethernet/nxp,enet-mac.yaml @@ -26,6 +26,17 @@ properties: nxp,unique-mac: type: boolean description: | - Use unique silicon ID to use UAA MAC. + Use part of the unique silicon ID to generate the MAC. This property will be overridden if the node has zephyr,random-mac-address or local-mac-address also. + This option is intended for cases where a very low likelihood + that the mac address is the same as another on the network + is sufficient, such as, testing, bringup, demos, etc. + The first 3 bytes will be the freescale OUI and the next + 3 bytes will come from the chip's unique ID. + + nxp,fused-mac: + type: boolean + description: | + Use the MAC address from fuse shadow register. + Not all platforms have a fusable MAC address. diff --git a/dts/bindings/ethernet/nxp,enet1g.yaml b/dts/bindings/ethernet/nxp,enet1g.yaml new file mode 100644 index 00000000000000..3f79a33f060a12 --- /dev/null +++ b/dts/bindings/ethernet/nxp,enet1g.yaml @@ -0,0 +1,15 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP ENET1G IP Module + +compatible: "nxp,enet1g" + +include: ["base.yaml"] + +properties: + reg: + required: true + + clocks: + required: true diff --git a/dts/bindings/ethernet/realtek,rtl8211f.yaml b/dts/bindings/ethernet/realtek,rtl8211f.yaml new file mode 100644 index 00000000000000..1f8cc22e71db30 --- /dev/null +++ b/dts/bindings/ethernet/realtek,rtl8211f.yaml @@ -0,0 +1,16 @@ +# Copyright 2023-2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Realtek RTL8211F Ethernet PHY device + +compatible: "realtek,rtl8211f" + +include: ethernet-phy.yaml + +properties: + reset-gpios: + type: phandle-array + description: GPIO connected to PHY reset signal pin. Reset is active low. + int-gpios: + type: phandle-array + description: GPIO for interrupt signal indicating PHY state change. diff --git a/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml b/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml index cdcb0b9d800899..0330240c79777e 100644 --- a/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml +++ b/dts/bindings/flash_controller/st,stm32-ospi-nor.yaml @@ -32,6 +32,9 @@ properties: reset-gpios: type: phandle-array description: RESETn pin + reset-gpios-duration: + type: int + description: The duration (in ms) for the flash memory reset pulse spi-bus-width: type: int required: true diff --git a/dts/bindings/gpio/nxp,cam-44pins-connector.yaml b/dts/bindings/gpio/nxp,cam-44pins-connector.yaml new file mode 100644 index 00000000000000..f929b71581fb0d --- /dev/null +++ b/dts/bindings/gpio/nxp,cam-44pins-connector.yaml @@ -0,0 +1,33 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on NXP 44-pin board-to-board camera connector. + The connector layout is depicted below: + + 42 GND GND 41 + 2 AF_GND AGND 1 + 4 AF_VCC STROBE 3 + 6 VCMSINK SDA 5 + 8 AVDD SCL 7 + 10 GPIO1 RESETB 9 + 12 GPIO0 PCLK 11 + 14 FREX VSYNC 13 + 16 MIPI_CSI_DP1/D9 HREF 15 + 18 MIPI_CSI_DN1/D8 PWDN 17 + 20 DGND MIPI_CSI_DP1/D9 19 + 22 MIPI_CSI_CLKP/D7 MIPI_CSI_DN1/D8 21 + 24 MIPI_CSI_CLKN/D6 MIPI_CSI_CLKP/D7 23 + 26 DGND MIPI_CSI_CLKN/D6 25 + 28 MIPI_CSI_DP0/D5 MIPI_CSI_DP0/D5 27 + 30 MIPI_CSI_DN0/D4 MIPI_CSI_DN0/D4 29 + 32 DGND D3 31 + 34 XCLK D2 33 + 36 DVDD D1 35 + 38 DOVDD D0 37 + 40 DGND DGND 39 + 44 AF_GND GND 43 + +compatible: "nxp,cam-44pins-connector" + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/gpio/nxp,i2c-tsc-fpc.yaml b/dts/bindings/gpio/nxp,i2c-tsc-fpc.yaml new file mode 100644 index 00000000000000..077f6701961a00 --- /dev/null +++ b/dts/bindings/gpio/nxp,i2c-tsc-fpc.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + + +compatible: "nxp,i2c-tsc-fpc" + +description: | + GPIO pins exposed on NXP LCD touch controller interface. These pins are + exposed on a 6 pin flexible printed cable connector. The pins have the + following assignments: + + Pin Number Usage + 1 VDD + 2 LCD touch reset + 3 LCD touch interrupt + 4 LCD touch controller I2C SCL + 5 LCD touch controller I2C SDA + 6 GND + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/gpio/nxp,parallel-lcd-connector.yaml b/dts/bindings/gpio/nxp,parallel-lcd-connector.yaml new file mode 100644 index 00000000000000..c1d8e8657e2ff4 --- /dev/null +++ b/dts/bindings/gpio/nxp,parallel-lcd-connector.yaml @@ -0,0 +1,33 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + + +compatible: "nxp,parallel-lcd-connector" + +description: | + GPIO pins exposed on NXP LCD interface. These pins are + exposed on a 40 pin flexible printed cable connector. The pins have the + following assignments: + + FPC Pin Function + 1 LED backlight cathode + 2 LED backlight anode + 3 GND + 4 VDD (3v3) + 5-7 GND + 8-12 LCD D11-D15 + 13-14 GND + 15-20 LCD D5-D10 + 21-23 GND + 24-28 LCD D0-D4 + 29 GND + 30 LCD CLK + 31 LCD DISP + 32 LCD HSYNC + 33 LCD VSYNC + 34 LCD DE + 35 NC + 36 GND + 37-40 NC + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/i2c/adi,max32-i2c.yaml b/dts/bindings/i2c/adi,max32-i2c.yaml new file mode 100644 index 00000000000000..2b1c81de0c70bb --- /dev/null +++ b/dts/bindings/i2c/adi,max32-i2c.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: ADI MAX32 I2C + +compatible: "adi,max32-i2c" + +include: [i2c-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + interrupts: + required: true diff --git a/dts/bindings/input/futaba,sbus.yaml b/dts/bindings/input/futaba,sbus.yaml new file mode 100644 index 00000000000000..574c7ef7ff8091 --- /dev/null +++ b/dts/bindings/input/futaba,sbus.yaml @@ -0,0 +1,70 @@ +# Copyright (c) 2024 NXP Semiconductors +# SPDX-License-Identifier: Apache-2.0 + +description: | + SBUS input driver using + This driver implements the SBUS protocol used on RC radio's + to send out analogue joystick and switches output. + SBUS is an single-wire inverted serial protocol to either you need to + to the rx-invert feature of your serial driver or use an external signal inverter. + The driver binds this to the Zephyr input system using INPUT_EV_CODES. + + The following examples defines a a binding of 2 joysticks and a button using 5 channels. + + &lpuart6 { + status = "okay"; + + sbus { + compatible = "futaba,sbus"; + right_stick_x { + channel = <1>; + type = ; + zephyr,code = ; + }; + right_stick_y { + channel = <2>; + type = ; + zephyr,code = ; + }; + left_stick_x { + channel = <3>; + type = ; + zephyr,code = ; + }; + left_stick_y { + channel = <4>; + type = ; + zephyr,code = ; + }; + kill_switch { + channel = <5>; + type = ; + zephyr,code = ; + }; + }; + }; + +compatible: "futaba,sbus" + +include: [base.yaml, uart-device.yaml] + +child-binding: + description: | + SBUS Channel to input-event-code binding + INPUT_EV_ABS & INPUT_EV_MSC gives raw input value + INPUT_EV_KEY emulates a key + properties: + channel: + type: int + required: true + description: | + SBUS input channel + Valid range: 1 - 16 + type: + type: int + required: true + description: Input event types see INPUT_EV_CODES + zephyr,code: + type: int + required: true + description: Code to emit. diff --git a/dts/bindings/interrupt-controller/st,stm32h7rs-exti.yaml b/dts/bindings/interrupt-controller/st,stm32h7rs-exti.yaml new file mode 100644 index 00000000000000..1e441fb47b80b0 --- /dev/null +++ b/dts/bindings/interrupt-controller/st,stm32h7rs-exti.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024, STMicroelectronics + +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32 controller + This compatible stands for the stm32H7RS interrupt-controller block + with two dedicated Rising and Falling interrupt pending registers + +compatible: "st,stm32h7rs-exti" + +include: st,stm32-exti.yaml diff --git a/dts/bindings/led/issi,is31fl3194.yaml b/dts/bindings/led/issi,is31fl3194.yaml new file mode 100644 index 00000000000000..4d07a36d7a4aa9 --- /dev/null +++ b/dts/bindings/led/issi,is31fl3194.yaml @@ -0,0 +1,74 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +description: | + IS31FL3194 3-channel LED driver with programmable pattern sequencing + + This driver supports single-channel and RGB LEDs. For single channel LEDs, + the led_set_brightness() API can be used to set the brightness of each LED. + For RGB LEDs, the led_set_color() API can be used to set the red, green and + blue components; the driver takes care of routing to the outputs described + by the color-mapping property. + + The LED_SHELL application can be used for testing. + + The following defines a single RGB LED in the is31fl3194 DT node: + + is31fl3194@53 { + compatible = "issi,is31fl3194"; + reg = <0x53>; + + led_0 { + label = "RGB LED"; + color-mapping = + , + , + ; + }; + }; + + The following example defines three single-channel LEDs in the is31fl3194 DT node: + + is31fl3194@53 { + compatible = "issi,is31fl3194"; + reg = <0x53>; + + led_0 { + label = "RED LED"; + color-mapping = ; + }; + + led_1 { + label = "GREEN LED"; + color-mapping = ; + }; + + led_2 { + label = "BLUE LED"; + color-mapping = ; + }; + }; + + +compatible: "issi,is31fl3194" + +include: ["i2c-device.yaml", "led-controller.yaml"] + +child-binding: + properties: + label: + required: true + + color-mapping: + required: true + + current-limit: + type: int + enum: + - 10 + - 20 + - 30 + - 40 + required: true + description: | + The current limit for the LED in mA. diff --git a/dts/bindings/mtd/atmel,at24.yaml b/dts/bindings/mtd/atmel,at24.yaml index da3369ec623c53..b9dda41cc802ab 100644 --- a/dts/bindings/mtd/atmel,at24.yaml +++ b/dts/bindings/mtd/atmel,at24.yaml @@ -2,7 +2,36 @@ # Copyright (c) 2018, Nordic Semiconductor # SPDX-License-Identifier: Apache-2.0 -description: Atmel AT24 (or compatible) I2C EEPROM +description: | + I2C EEPROMs compatible with Atmel's AT24 family + + There are multiple vendors manufacturing I2C EEPROMs compatible with the programming model of the + Atmel AT24. + + Examples of compatible EEPROM families: + - Microchip AT24xxx + - ST M24xxx + + Each of these can be represented by a set of common parameters (EEPROM size, page size, address + width, and timeout) available from the datasheet of the specific EEPROM. The compatible string for + these can list the specific EEPROM vendor and model along with the vendor EEPROM family as long as + the least-specific compatible entry is "atmel,at24". + + Example devicetree node describing a ST M24M01 EEPROM on the i2c0 bus: + + &i2c0 { + status = "okay"; + clock-frequency = ; + + eeprom@56 { + compatible = "st,m24m01", "st,m24xxx", "atmel,at24"; + reg = <0x56>; + size = ; + pagesize = <256>; + address-width = <16>; + timeout = <5>; + }; + }; compatible: "atmel,at24" diff --git a/dts/bindings/mtd/atmel,at25.yaml b/dts/bindings/mtd/atmel,at25.yaml index 9b1977e8dc1366..7c887dd1768e8f 100644 --- a/dts/bindings/mtd/atmel,at25.yaml +++ b/dts/bindings/mtd/atmel,at25.yaml @@ -1,7 +1,36 @@ # Copyright (c) 2019 Vestas Wind Systems A/S # SPDX-License-Identifier: Apache-2.0 -description: Atmel AT25 (or compatible) SPI EEPROM +description: | + SPI EEPROMs compatible with Atmel's AT25 family + + There are multiple vendors manufacturing SPI EEPROMs compatible with the programming model of the + Atmel AT25. + + Examples of compatible EEPROM families: + - Microchip AT25xxx + - ST M95xxx + + Each of these can be represented by a set of common parameters (EEPROM size, page size, address + width, and timeout) available from the datasheet of the specific EEPROM. The compatible string for + these can list the specific EEPROM vendor and model along with the vendor EEPROM family as long as + the least-specific compatible entry is "atmel,at25". + + Example devicetree node describing a ST M95256 EEPROM on the spi0 bus: + + &spi0 { + status = "okay"; + + eeprom@1 { + compatible = "st,m95256", "st,m95xxx", "atmel,at25"; + reg = <0x1>; + size = ; + pagesize = <64>; + address-width = <16>; + spi-max-frequency = ; + timeout = <5>; + }; + }; compatible: "atmel,at25" diff --git a/dts/bindings/pinctrl/cypress,psoc6-pinctrl.yaml b/dts/bindings/pinctrl/cypress,psoc6-pinctrl.yaml deleted file mode 100644 index 8914f873f81f24..00000000000000 --- a/dts/bindings/pinctrl/cypress,psoc6-pinctrl.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# Copyright (c) 2021, ATL Electronics -# SPDX-License-Identifier: Apache-2.0 - -description: | - Cypress PSoC-6 Pinctrl container node - - The Cypress PSoC-6 pins implements following pin configuration option: - - * bias-pull-up - * bias-pull-down - * drive-open-drain - * drive-open-source - * drive-push-pull (strong) - * input-enable (input-buffer) - - These options define devicetree flags that are converted to SoC flags at - CY_PSOC6_PIN_FLAGS(). - -compatible: "cypress,psoc6-pinctrl" - -include: base.yaml - -properties: - "#address-cells": - required: true - const: 1 - "#size-cells": - required: true - const: 1 - -child-binding: - description: cypress pins - - include: pincfg-node.yaml - - properties: - "cypress,pins": - type: phandle-array diff --git a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml index 01a1c758a9c553..40c688a0b8b47f 100644 --- a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml +++ b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml @@ -96,3 +96,16 @@ child-binding: enum: - "3v3" - "1v8" + + drive-strength: + type: string + description: | + We can configure this property to drive a high or low current selection. + If this property is not configured, it is the default setting. + According to the SPEC, the default drive current selection varies from + different pins. + Define the high level 0b: 8mA + low level 1b: 4mA or 2mA + enum: + - "high" + - "low" diff --git a/dts/bindings/power/st,stm32-pwr.yaml b/dts/bindings/power/st,stm32-pwr.yaml new file mode 100644 index 00000000000000..84b67104dac7db --- /dev/null +++ b/dts/bindings/power/st,stm32-pwr.yaml @@ -0,0 +1,67 @@ +# Copyright (c) 2023 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32 power controller + +compatible: "st,stm32-pwr" + +include: base.yaml + +properties: + reg: + required: true + + wkup-pins-nb: + type: int + description: | + Max nbr of system wake-up pins. + For example wkup-pins-nb = <8>; on the stm32u5 + + wkup-pin-srcs: + type: int + description: | + Number of wake-up GPIO sources to select from for each wake-up pin. + If not specified, that means there is only 1 GPIO source for each + wake-up pin. + + For example, each wake-up pin on STM32U5 is associated with + 4 wake-up sources, 3 of them correspond to GPIOs. + + wkup-pins-pol: + type: boolean + description: | + True if SoC has a wake-up pins polarity config register + + wkup-pins-pupd: + type: boolean + description: | + True if SoC has pull-up/down config register(s) for GPIO ports + that are associated with wake-up pins. + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +child-binding: + description: | + STM32 wake-up pin node. + + All nodes using this binding must be named "wkup-pin@[index]" + index starts from 1 + + properties: + reg: + type: array + required: true + description: Wake-up pin identifier, same as "index" in node name + + wkup-gpios: + type: phandle-array + description: | + Specifies the GPIOs, if any, that are associated with the wake-up pin. + + For example, for GPIO B2 associated with wakeup source 1 on wake-up + pin 1 on STM32U5 SoCs: + wkup-gpios = <&gpiob 2 STM32_PWR_WKUP_PIN_SRC_1>, <...>; diff --git a/dts/bindings/power/zephyr,power-state.yaml b/dts/bindings/power/zephyr,power-state.yaml index 5c645306b58a12..4fe22d1c5dba03 100644 --- a/dts/bindings/power/zephyr,power-state.yaml +++ b/dts/bindings/power/zephyr,power-state.yaml @@ -31,3 +31,9 @@ properties: type: int description: | Worst case latency in microseconds required to exit the idle state. + zephyr,pm-device-disabled: + type: boolean + description: | + Disable system managed device power management for this state. When set, + the power management subsystem will not suspend devices before entering + this state. diff --git a/dts/bindings/pwm/nxp,flexio-pwm.yaml b/dts/bindings/pwm/nxp,flexio-pwm.yaml new file mode 100644 index 00000000000000..44e33d5589c60d --- /dev/null +++ b/dts/bindings/pwm/nxp,flexio-pwm.yaml @@ -0,0 +1,47 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP Flexio PWM controller. + Each flexio timer can be used for generating one pwm pulse. + The two PWM modes supported by flexio are chosen based on the selected polarity - + Dual 8-bit counters PWM mode and Dual 8-bit counters PWM Low mode. + +compatible: "nxp,flexio-pwm" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags + +child-binding: + description: | + Flexio PWM channel configuration. + + properties: + pin-id: + type: int + required: true + description: | + pin-id should be populated with number 'n' specified in the + FXIO_D data pin of your board's schematic. + + prescaler: + type: int + description: | + The clock divider for internal counter prescaler. + - 1: Divide by 1 + - 16: Divide by 16 + - 256: Divide by 256 + enum: [1, 16, 256] diff --git a/dts/bindings/pwm/nxp,qtmr-pwm.yaml b/dts/bindings/pwm/nxp,qtmr-pwm.yaml new file mode 100644 index 00000000000000..587c32e3c4a7d5 --- /dev/null +++ b/dts/bindings/pwm/nxp,qtmr-pwm.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2024, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP QTMR PWM + +compatible: "nxp,qtmr-pwm" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + prescaler: + type: int + required: true + description: prescale factor from the qtmr clock. + enum: [1, 2, 4, 8, 16, 32, 64, 128] + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/ti,cc13xx-cc26xx-timer-pwm.yaml b/dts/bindings/pwm/ti,cc13xx-cc26xx-timer-pwm.yaml index c63fc7ac1d78fa..bc33465b1188e3 100644 --- a/dts/bindings/pwm/ti,cc13xx-cc26xx-timer-pwm.yaml +++ b/dts/bindings/pwm/ti,cc13xx-cc26xx-timer-pwm.yaml @@ -69,4 +69,6 @@ properties: required: true pwm-cells: -- period + - channel + - period + - flags diff --git a/dts/bindings/qspi/st,stm32-qspi.yaml b/dts/bindings/qspi/st,stm32-qspi.yaml index 04aa6e4d02083e..f656bd90586ef1 100644 --- a/dts/bindings/qspi/st,stm32-qspi.yaml +++ b/dts/bindings/qspi/st,stm32-qspi.yaml @@ -59,12 +59,22 @@ properties: For example dma-names = "tx_rx"; + dual-flash: + type: boolean + description: | + configuration to enable the dual flash mode of the QSPI peripheral + where two external quad SPI Flash memories (FLASH 1 and FLASH 2) are used + in order to send/receive 8 bits (or 16 bits in DDR mode) every cycle, + effectively doubling the throughput as well as the capacity. + When true, the Flash ID number is useless. + flash-id: type: int description: | - FLash ID number. This number, if defined, helps to select the right - QSPI GPIO banks (defined as 'quadspi_bk[12]' in pinctrl property) + Flash ID number. This number, if defined, helps to select the right + QSPI GPIO banks (defined as 'quadspi_bk[1/2]' in pinctrl property) to communicate with flash memory. + Valid only if the is not set. For example flash-id = <2>; diff --git a/dts/bindings/riscv/litex,soc-controller.yaml b/dts/bindings/riscv/litex,soc-controller.yaml new file mode 100644 index 00000000000000..3b78aae8df15db --- /dev/null +++ b/dts/bindings/riscv/litex,soc-controller.yaml @@ -0,0 +1,12 @@ +# Copyright 2024 Vogl Electronic GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: LiteX SoC Controller driver + +compatible: "litex,soc-controller" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/rtc/microcrystal,rv3028.yaml b/dts/bindings/rtc/microcrystal,rv3028.yaml new file mode 100644 index 00000000000000..6ca549c860e1c1 --- /dev/null +++ b/dts/bindings/rtc/microcrystal,rv3028.yaml @@ -0,0 +1,54 @@ +# Copyright (c) 2024 ANITRA system s.r.o. +# SPDX-License-Identifier: Apache-2.0 + +description: Micro Crystal RV3028 RTC + +compatible: "microcrystal,rv3028" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml + +properties: + clkout-frequency: + type: int + enum: + - 32768 + - 8192 + - 1024 + - 64 + - 32 + - 1 + description: | + Frequency of the CLKOUT signal in Hertz (Hz). If omitted, the CLKOUT pin is LOW. + + backup-switch-mode: + type: string + required: true + enum: + - disabled + - direct + - level + description: | + Automatic backup switchover function selection: + - disabled: The switchover function is disabled - only one power supply available (VDD) + - direct: Direct Switching Mode (DSM): when VDD < VBACKUP, switchover occurs from VDD to + VBACKUP without requiring VDD to drop below VTH:LSM (2.0 V) + - level: Level Switching Mode (LSM): when VDD < VTH:LSM (2.0 V) AND VBACKUP > VTH:LSM, + switchover occurs from VDD to VBACKUP + + trickle-resistor-ohms: + type: int + enum: + - 3000 + - 5000 + - 9000 + - 15000 + description: | + Enable the trickle charger with provided current-limiting resistance in ohms. The trickle + charger allows a battery or supercapacitor connected to VBACKUP to be charged. + + int-gpios: + type: phandle-array + description: | + GPIO connected to the RV3028 INT interrupt output. This signal is open-drain, active low. diff --git a/dts/bindings/sensor/sensirion,shtcx.yaml b/dts/bindings/sensor/sensirion,shtcx.yaml index e0d90c6a929a78..d4a2cfcc2d302a 100644 --- a/dts/bindings/sensor/sensirion,shtcx.yaml +++ b/dts/bindings/sensor/sensirion,shtcx.yaml @@ -1,24 +1,30 @@ # Copyright (c) 2021, Thomas Stranger # SPDX-License-Identifier: Apache-2.0 -description: Sensirion SHTCx humidity and temperature sensor +description: | + Sensirion SHTCx humidity and temperature sensor + + Additionally use "sensirion,shtc1" or "sensirion,shtc3" compatibles + such that a generic driver can consider chip specific behaviour. + + Example device tree node describing a Sensirion SHTC3 Sensor on the i2c0 bus: + + &i2c0 { + status = "okay"; + clock-frequency = ; + shtc3@70 { + compatible = "sensirion,shtc3", "sensirion,shtcx"; + reg = <0x70>; + measure-mode = "normal"; + clock-stretching; + }; + }; compatible: "sensirion,shtcx" include: [sensor-device.yaml, i2c-device.yaml] properties: - chip: - type: string - required: true - description: | - Specifies which chip exactly is used. This is necessary to get exact - timing information and supported command set. - SHTC3 has an additional sleep mode that is entered between measurements. - enum: - - "shtc1" - - "shtc3" - measure-mode: type: string required: true diff --git a/dts/bindings/sensor/st,stm32-digi-temp.yaml b/dts/bindings/sensor/st,stm32-digi-temp.yaml new file mode 100644 index 00000000000000..4faba85246dd2e --- /dev/null +++ b/dts/bindings/sensor/st,stm32-digi-temp.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024, Aurelien Jarno +# SPDX-License-Identifier: Apache-2.0 + +description: STM32 family Digital Temperature Sensor node + +compatible: "st,stm32-digi-temp" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true diff --git a/dts/bindings/serial/cypress,psoc6-uart.yaml b/dts/bindings/serial/cypress,psoc6-uart.yaml index 543975ab7c8c2d..6cf83bce617907 100644 --- a/dts/bindings/serial/cypress,psoc6-uart.yaml +++ b/dts/bindings/serial/cypress,psoc6-uart.yaml @@ -6,7 +6,7 @@ description: Cypress SCB[UART] compatible: "cypress,psoc6-uart" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/spi/adi,max32-spi.yaml b/dts/bindings/spi/adi,max32-spi.yaml new file mode 100644 index 00000000000000..12bc88b105a1e6 --- /dev/null +++ b/dts/bindings/spi/adi,max32-spi.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: ADI MAX32 SPI + +include: + - name: spi-controller.yaml + - name: pinctrl-device.yaml + +compatible: "adi,max32-spi" + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + type: phandles + required: true diff --git a/dts/bindings/spi/cypress,psoc6-spi.yaml b/dts/bindings/spi/cypress,psoc6-spi.yaml index 81a12f44ec5dbc..bebdc53d314b15 100644 --- a/dts/bindings/spi/cypress,psoc6-spi.yaml +++ b/dts/bindings/spi/cypress,psoc6-spi.yaml @@ -5,7 +5,7 @@ description: Cypress SBC[SPI] compatible: "cypress,psoc6-spi" -include: spi-controller.yaml +include: [spi-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/usb/zephyr,hid-device.yaml b/dts/bindings/usb/zephyr,hid-device.yaml index 03887acb0d887b..2d20b450986b69 100644 --- a/dts/bindings/usb/zephyr,hid-device.yaml +++ b/dts/bindings/usb/zephyr,hid-device.yaml @@ -36,11 +36,11 @@ properties: The size of the longest input report that the HID device can generate. This property is used to determine the buffer length used for transfers. - in-polling-rate: + in-polling-period-us: type: int required: true description: | - Input or output type reports polling rate in microseconds. For USB full + Input or output type reports polling period in microseconds. For USB full speed this could be clamped to 1ms or 255ms depending on the value. out-report-size: @@ -50,9 +50,9 @@ properties: When this property is present, a USB device will use out pipe for output reports, otherwise control pipe will be used for output reports. - out-polling-rate: + out-polling-period-us: type: int description: | - Output type reports polling rate in microseconds. For USB full + Output type reports polling period in microseconds. For USB full speed this could be clamped to 1ms or 255ms depending on the value. This option is only effective if the out-report-size property is defined. diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 4cc0cae7e82f7e..4580131de931ce 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -111,6 +111,7 @@ broadmobi Shanghai Broadmobi Communication Technology Co.,Ltd. bticino Bticino International buffalo Buffalo, Inc. bur B&R Industrial Automation GmbH +bytesatwork bytesatwork AG calaosystems CALAO Systems SAS calxeda Calxeda canaan Canaan, Inc. @@ -224,6 +225,7 @@ evervision Evervision Electronics Co. Ltd. exar Exar Corporation excito Excito ezchip EZchip Semiconductor +ezurio Ezurio facebook Facebook (deprecated, use meta) fairphone Fairphone B.V. fanke FANKE Technology Co., Ltd. @@ -243,6 +245,7 @@ friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd fsl Freescale Semiconductor ftdi Future Technology Devices International Ltd. fujitsu Fujitsu Ltd. +futaba Futaba Corporation gaisler Gaisler galaxycore Galaxycore, Inc. gardena GARDENA GmbH @@ -353,7 +356,6 @@ kvg Kverneland Group kyo Kyocera Corporation lacie LaCie laird Laird PLC -lairdconnect Laird Connectivity lamobo Ketai Huajie Technology Co., Ltd. lantiq Lantiq Semiconductor lattice Lattice Semiconductor @@ -366,6 +368,7 @@ lg LG Corporation lgphilips LG Display libretech Shenzhen Libre Technology Co., Ltd licheepi Lichee Pi +lilygo Lilygo Shenzhen Xinyuan Electronic Technology Co., Ltd linaro Linaro Limited linksprite LinkSprite Technologies, Inc. linksys Belkin International, Inc. (Linksys) diff --git a/dts/bindings/video/ovti,ov7670.yaml b/dts/bindings/video/ovti,ov7670.yaml new file mode 100644 index 00000000000000..4b8fa88f1170b8 --- /dev/null +++ b/dts/bindings/video/ovti,ov7670.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: OV7670 CMOS video sensor + +compatible: "ovti,ov7670" + +properties: + reset-gpios: + type: phandle-array + description: | + The RESETn pin is asserted to disable the sensor causing a hard + reset. The sensor receives this as an active-low signal. + pwdn-gpios: + type: phandle-array + description: | + The PWDN pin is asserted to power down the sensor. The sensor + receives this as an active high signal + +include: i2c-device.yaml diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index 231fbb3067edbd..a0f088be07fd86 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -189,6 +189,11 @@ interrupts = <21 NRF_DEFAULT_IRQ_PRIORITY>; }; + cpuapp_resetinfo: resetinfo@1e000 { + compatible = "nordic,nrf-resetinfo"; + reg = <0x1e000 0x1000>; + }; + cpuapp_ieee802154: ieee802154 { compatible = "nordic,nrf-ieee802154"; status = "disabled"; @@ -227,6 +232,11 @@ interrupts = <20 NRF_DEFAULT_IRQ_PRIORITY>; }; + cpurad_resetinfo: resetinfo@1e000 { + compatible = "nordic,nrf-resetinfo"; + reg = <0x1e000 0x1000>; + }; + dppic020: dppic@22000 { compatible = "nordic,nrf-dppic-local"; reg = <0x22000 0x1000>; @@ -651,6 +661,14 @@ status = "disabled"; }; + adc: adc@982000 { + compatible = "nordic,nrf-saadc"; + reg = <0x982000 0x1000>; + interrupts = <386 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + #io-channel-cells = <1>; + }; + comp: comparator@983000 { compatible = "nordic,nrf-comp"; reg = <0x983000 0x1000>; diff --git a/dts/common/nordic/nrf54l15.dtsi b/dts/common/nordic/nrf54l15.dtsi index 0b8eb1c549a879..8896b94f87488a 100644 --- a/dts/common/nordic/nrf54l15.dtsi +++ b/dts/common/nordic/nrf54l15.dtsi @@ -264,6 +264,11 @@ compatible = "nordic,nrf-ieee802154"; status = "disabled"; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; }; dppic20: dppic@c2000 { diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 43f171f57a1bea..71b703114c36b4 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -24,6 +24,7 @@ zephyr,canbus = &twai; zephyr,entropy = &trng0; zephyr,flash-controller = &flash; + zephyr,bt-hci = &esp32_bt_hci; }; cpus { @@ -68,6 +69,11 @@ status = "disabled"; }; + esp32_bt_hci: esp32_bt_hci { + compatible = "espressif,esp32-bt-hci"; + status = "disabled"; + }; + soc { #address-cells = <1>; #size-cells = <1>; diff --git a/dts/riscv/ite/it81xx2.dtsi b/dts/riscv/ite/it81xx2.dtsi index 252ddfe120bfdb..53dd3b0cdc9351 100644 --- a/dts/riscv/ite/it81xx2.dtsi +++ b/dts/riscv/ite/it81xx2.dtsi @@ -61,7 +61,8 @@ pinctrla: pinctrl@f01610 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01610 8>; /* GPCR */ + reg = <0x00f01610 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -80,7 +81,8 @@ pinctrlb: pinctrl@f01618 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01618 8>; /* GPCR */ + reg = <0x00f01618 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = <0xf016f5 0xf016f5 NO_FUNC NO_FUNC NO_FUNC NO_FUNC NO_FUNC 0xf01600>; func3-en-mask = <0x01 0x02 0 0 @@ -99,7 +101,8 @@ pinctrlc: pinctrl@f01620 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01620 8>; /* GPCR */ + reg = <0x00f01620 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0x10 @@ -118,7 +121,8 @@ pinctrld: pinctrl@f01628 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01628 8>; /* GPCR */ + reg = <0x00f01628 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -137,7 +141,8 @@ pinctrle: pinctrl@f01630 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01630 8>; /* GPCR */ + reg = <0x00f01630 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = <0xf02032 NO_FUNC NO_FUNC NO_FUNC NO_FUNC 0xf016f0 NO_FUNC 0xf02032>; func3-en-mask = <0x01 0 0 0 @@ -156,7 +161,8 @@ pinctrlf: pinctrl@f01638 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01638 8>; /* GPCR */ + reg = <0x00f01638 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0x02 0x02 @@ -175,7 +181,8 @@ pinctrlg: pinctrl@f01640 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01640 8>; /* GPCR */ + reg = <0x00f01640 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = <0xf016f0 0xf016f0 0xf016f0 NO_FUNC NO_FUNC NO_FUNC 0xf016f0 NO_FUNC>; func3-en-mask = <0x20 0x08 0x10 0 @@ -194,7 +201,8 @@ pinctrlh: pinctrl@f01648 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01648 8>; /* GPCR */ + reg = <0x00f01648 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0x20 0x20 0 @@ -217,7 +225,8 @@ pinctrli: pinctrl@f01650 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01650 8>; /* GPCR */ + reg = <0x00f01650 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -236,7 +245,8 @@ pinctrlj: pinctrl@f01658 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01658 8>; /* GPCR */ + reg = <0x00f01658 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = <0xf016f4 NO_FUNC 0xf016f4 0xf016f4 0xf016f0 0xf016f0 NO_FUNC NO_FUNC>; func3-en-mask = <0x01 0 0x01 0x02 @@ -255,7 +265,8 @@ pinctrlk: pinctrl@f01690 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01690 8>; /* GPCR */ + reg = <0x00f01690 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -274,7 +285,8 @@ pinctrll: pinctrl@f01698 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01698 8>; /* GPCR */ + reg = <0x00f01698 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -293,7 +305,8 @@ pinctrlm: pinctrl@f016a0 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a0 8>; /* GPCR */ + reg = <0x00f016a0 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 diff --git a/dts/riscv/ite/it82xx2.dtsi b/dts/riscv/ite/it82xx2.dtsi index a9ab8b206cf059..4e5bae980b6b71 100644 --- a/dts/riscv/ite/it82xx2.dtsi +++ b/dts/riscv/ite/it82xx2.dtsi @@ -447,7 +447,8 @@ pinctrla: pinctrl@f01660 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01660 8>; /* GPCR */ + reg = <0x00f01660 8 /* GPCR */ + 0x00f03e30 1>; /* PDSCA */ func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -466,7 +467,8 @@ pinctrlb: pinctrl@f01668 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01668 8>; /* GPCR */ + reg = <0x00f01668 8 /* GPCR */ + 0x00f03e31 1>; /* PDSCB */ func3-gcr = <0xf03e15 0xf03e15 0xf03e11 NO_FUNC NO_FUNC 0xf03e11 NO_FUNC NO_FUNC>; func3-en-mask = <0x01 0x02 0x20 0 @@ -489,7 +491,8 @@ pinctrlc: pinctrl@f01670 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01670 8>; /* GPCR */ + reg = <0x00f01670 8 /* GPCR */ + 0x00f03e32 1>; /* PDSCC */ func3-gcr = ; func3-en-mask = <0 0 0 0x10 @@ -508,7 +511,8 @@ pinctrld: pinctrl@f01678 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01678 8>; /* GPCR */ + reg = <0x00f01678 8 /* GPCR */ + 0x00f03e33 1>; /* PDSCD */ func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -527,7 +531,8 @@ pinctrle: pinctrl@f01680 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01680 8>; /* GPCR */ + reg = <0x00f01680 8 /* GPCR */ + 0x00f03e34 1>; /* PDSCE */ func3-gcr = ; func3-en-mask = <0 0x20 0x20 0 @@ -550,7 +555,8 @@ pinctrlf: pinctrl@f01688 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01688 8>; /* GPCR */ + reg = <0x00f01688 8 /* GPCR */ + 0x00f03e35 1>; /* PDSCF */ func3-gcr = <0xf03e15 0xf03e15 0xf03e10 0xf03e10 NO_FUNC NO_FUNC 0xf03e11 NO_FUNC>; func3-en-mask = <0x04 0x08 0x02 0x02 @@ -569,7 +575,8 @@ pinctrlg: pinctrl@f01690 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01690 8>; /* GPCR */ + reg = <0x00f01690 8 /* GPCR */ + 0x00f03e36 1>; /* PDSCG */ func3-gcr = <0xf03e10 0xf03e10 0xf03e10 NO_FUNC NO_FUNC NO_FUNC 0xf03e10 NO_FUNC>; func3-en-mask = <0x20 0x08 0x10 0 @@ -588,7 +595,8 @@ pinctrlh: pinctrl@f01698 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f01698 8>; /* GPCR */ + reg = <0x00f01698 8 /* GPCR */ + 0x00f03e37 1>; /* PDSCH */ func3-gcr = ; func3-en-mask = <0 0x20 0x20 0 @@ -607,7 +615,8 @@ pinctrli: pinctrl@f016a0 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a0 8>; /* GPCR */ + reg = <0x00f016a0 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -626,7 +635,8 @@ pinctrlj: pinctrl@f016a8 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016a8 8>; /* GPCR */ + reg = <0x00f016a8 8 /* GPCR */ + 0x00f03e39 1>; /* PDSCJ */ func3-gcr = <0xf03e14 NO_FUNC 0xf03e14 0xf03e14 0xf03e10 0xf03e10 NO_FUNC NO_FUNC>; func3-en-mask = <0x01 0 0x01 0x02 @@ -645,7 +655,8 @@ pinctrlk: pinctrl@f016b0 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016b0 8>; /* GPCR */ + reg = <0x00f016b0 8 /* GPCR */ + 0x00f03e3A 1>; /* PDSCK */ func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -664,7 +675,8 @@ pinctrll: pinctrl@f016b8 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016b8 8>; /* GPCR */ + reg = <0x00f016b8 8 /* GPCR */ + 0x00f03e3B 1>; /* PDSCL */ func3-gcr = ; func3-en-mask = <0 0 0 0 @@ -683,7 +695,8 @@ pinctrlm: pinctrl@f016c0 { compatible = "ite,it8xxx2-pinctrl-func"; - reg = <0x00f016c0 8>; /* GPCR */ + reg = <0x00f016c0 8 /* GPCR */ + NO_FUNC 1>; func3-gcr = ; func3-en-mask = <0 0 0 0 diff --git a/dts/riscv/openisa/rv32m1.dtsi b/dts/riscv/openisa/rv32m1.dtsi index afbc7c41c23a0e..cb234eba998275 100644 --- a/dts/riscv/openisa/rv32m1.dtsi +++ b/dts/riscv/openisa/rv32m1.dtsi @@ -524,5 +524,10 @@ write-block-size = <8>; }; }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/riscv32-litex-vexriscv.dtsi b/dts/riscv/riscv32-litex-vexriscv.dtsi index 71b32e95b88866..6ae55a82016b52 100644 --- a/dts/riscv/riscv32-litex-vexriscv.dtsi +++ b/dts/riscv/riscv32-litex-vexriscv.dtsi @@ -34,6 +34,15 @@ #size-cells = <1>; compatible = "litex,vexriscv"; ranges; + ctrl0: soc_controller@e0000000 { + compatible = "litex,soc-controller"; + reg = <0xe0000000 0x4 + 0xe0000004 0x4 + 0xe0000008 0x4>; + reg-names = "reset", + "scratch", + "bus_errors"; + }; intc0: interrupt-controller@bc0 { compatible = "litex,vexriscv-intc0"; #address-cells = <0>; diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index d721dd08a2c9ea..ae348b1288fb24 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -19,6 +19,7 @@ zephyr,canbus = &twai; zephyr,entropy = &trng0; zephyr,flash-controller = &flash; + zephyr,bt-hci = &esp32_bt_hci; }; cpus { @@ -66,6 +67,11 @@ status = "disabled"; }; + esp32_bt_hci: esp32_bt_hci { + compatible = "espressif,esp32-bt-hci"; + status = "disabled"; + }; + eth: eth { compatible = "espressif,esp32-eth"; interrupts = ; diff --git a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi index 3a88d973c47733..a855bd0df97b8d 100644 --- a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi +++ b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi @@ -63,6 +63,11 @@ status = "disabled"; }; + esp32_bt_hci: esp32_bt_hci { + compatible = "espressif,esp32-bt-hci"; + status = "disabled"; + }; + pinctrl: pin-controller { compatible = "espressif,esp32-pinctrl"; status = "okay"; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index 284b74211fdb53..2b571a65960876 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -70,6 +70,11 @@ status = "disabled"; }; + esp32_bt_hci: esp32_bt_hci { + compatible = "espressif,esp32-bt-hci"; + status = "disabled"; + }; + pinctrl: pin-controller { compatible = "espressif,esp32-pinctrl"; status = "okay"; diff --git a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi index 15b7128aea5ede..7c2050b109fda4 100644 --- a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi @@ -111,6 +111,21 @@ soc { + l1ccap: l1ccap@1fe80080 { + compatible = "intel,adsp-l1ccap"; + reg = <0x1fe80080 0x4>; + }; + + l1ccfg: l1ccfg@1fe80084 { + compatible = "intel,adsp-l1ccfg"; + reg = <0x1fe80084 0x4>; + }; + + l1pcfg: l1pcfg@1fe80088 { + compatible = "intel,adsp-l1pcfg"; + reg = <0x1fe80088 0x4>; + }; + lsbpm: lsbpm@71d80 { compatible = "intel,adsp-lsbpm"; reg = <0x71d80 0x0008>; diff --git a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi index e3462c834d1937..c26d2b815fe0ae 100644 --- a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi @@ -130,6 +130,21 @@ soc { + l1ccap: l1ccap@1fe80080 { + compatible = "intel,adsp-l1ccap"; + reg = <0x1fe80080 0x4>; + }; + + l1ccfg: l1ccfg@1fe80084 { + compatible = "intel,adsp-l1ccfg"; + reg = <0x1fe80084 0x4>; + }; + + l1pcfg: l1pcfg@1fe80088 { + compatible = "intel,adsp-l1pcfg"; + reg = <0x1fe80088 0x4>; + }; + lsbpm: lsbpm@71d80 { compatible = "intel,adsp-lsbpm"; reg = <0x71d80 0x0008>; diff --git a/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi new file mode 100644 index 00000000000000..5923d385291f79 --- /dev/null +++ b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi @@ -0,0 +1,584 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <0>; + cpu-power-states = <&d0i3 &d3>; + i-cache-line-size = <64>; + d-cache-line-size = <64>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <1>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <2>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <3>; + cpu-power-states = <&d0i3 &d3>; + }; + + cpu4: cpu@4 { + device_type = "cpu"; + compatible = "cdns,tensilica-xtensa-lx7"; + reg = <4>; + cpu-power-states = <&d0i3 &d3>; + }; + }; + + power-states { + d0i3: idle { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <200>; + exit-latency-us = <100>; + }; + /* PM_STATE_SOFT_OFF can be entered only by calling pm_state_force. + * The procedure is triggered by IPC from the HOST (SET_DX). + */ + d3: off { + compatible = "zephyr,power-state"; + power-state-name = "soft-off"; + min-residency-us = <0>; + exit-latency-us = <0>; + status = "disabled"; + }; + }; + + sram0: memory@a0020000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0020000 DT_SIZE_K(4608)>; + }; + + sram0virtual: virtualmemory@a0020000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0020000 DT_SIZE_K(8192)>; + }; + + sram1: memory@a0000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0xa0000000 DT_SIZE_K(64)>; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + clkctl: clkctl { + compatible = "intel,adsp-shim-clkctl"; + adsp-clkctl-clk-wovcro = <0>; + adsp-clkctl-clk-ipll = <1>; + adsp-clkctl-freq-enc = <0xc 0x4>; + adsp-clkctl-freq-mask = <0x0 0x0>; + adsp-clkctl-freq-default = <1>; + adsp-clkctl-freq-lowest = <0>; + wovcro-supported; + }; + + audioclk: audio-clock { + compatible = "fixed-clock"; + clock-frequency = <24576000>; + #clock-cells = <0>; + }; + + pllclk: pll-clock { + compatible = "fixed-clock"; + clock-frequency = <96000000>; + #clock-cells = <0>; + }; + + IMR1: memory@A1000000 { + compatible = "intel,adsp-imr"; + reg = <0xA1000000 DT_SIZE_M(16)>; + block-size = <0x1000>; + zephyr,memory-region = "IMR1"; + }; + + soc { + l1ccap: l1ccap@3fe80080 { + compatible = "intel,adsp-l1ccap"; + reg = <0x3fe80080 0x4>; + }; + + l1ccfg: l1ccfg@3fe80084 { + compatible = "intel,adsp-l1ccfg"; + reg = <0x3fe80084 0x4>; + }; + + l1pcfg: l1pcfg@3fe80088 { + compatible = "intel,adsp-l1pcfg"; + reg = <0x3fe80088 0x4>; + }; + + lsbpm: lsbpm@71d80 { + compatible = "intel,adsp-lsbpm"; + reg = <0x71d80 0x0008>; + }; + + hsbpm: hsbpm@17a800 { + compatible = "intel,adsp-hsbpm"; + reg = <0x17a800 0x0008>; + }; + + core_intc: core_intc@0 { + compatible = "cdns,xtensa-core-intc"; + reg = <0x00 0x400>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + hdamlddmic: hdamlddmic@cc0 { + compatible = "intel,adsp-hda-dmic-cap"; + reg = <0xcc0 0x40>; + status = "okay"; + }; + + dmic0: dai-dmic0@10100 { + compatible = "intel,dai-dmic"; + reg = <0x10100 0x8000>; + shim = <0x10000>; + fifo = <0x0008>; + interrupts = <0x08 0 0>; + interrupt-parent = <&ace_intc>; + power-domain = <&hub_ulp_domain>; + }; + + dmic1: dai-dmic1@10100 { + compatible = "intel,dai-dmic"; + reg = <0x10100 0x8000>; + shim = <0x10000>; + fifo = <0x0108>; + interrupts = <0x08 0 0>; + interrupt-parent = <&ace_intc>; + power-domain = <&hub_ulp_domain>; + }; + + dmicvss: dmicvss@16000 { + compatible = "intel,adsp-dmic-vss"; + reg = <0x16000 0x2000>; + status = "okay"; + }; + + /* + * FIXME this is modeling individual alh channels/instances + * with node labels, which has problems. A better representation + * is discussed here: + * + * https://github.com/zephyrproject-rtos/zephyr/pull/50287#discussion_r974591009 + */ + alh0: alh0@24400 { + compatible = "intel,alh-dai"; + reg = <0x00024400 0x00024600>; + status = "okay"; + }; + + alh1: alh1@24400 { + compatible = "intel,alh-dai"; + reg = <0x00024400 0x00024600>; + status = "okay"; + }; + + sspbase: ssp_base@28000 { + compatible = "intel,ssp-sspbase"; + reg = <0x28000 0x1000>; + }; + + hdamlssp: hdamlssp@d00 { + compatible = "intel,adsp-hda-ssp-cap"; + reg = <0xD00 0x40>; + status = "okay"; + }; + + ssp0: ssp@28100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x00028100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x00 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 1 + &hda_link_in 1>; + dma-names = "tx", "rx"; + ssp-index = <0>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp00: ssp@0 { + compatible = "intel,ssp-dai"; + reg = <0x0>; + status = "okay"; + }; + }; + + ssp1: ssp@29100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x00029100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x01 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 2 + &hda_link_in 2>; + dma-names = "tx", "rx"; + ssp-index = <1>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp10: ssp@10 { + compatible = "intel,ssp-dai"; + reg = <0x10>; + status = "okay"; + }; + }; + + ssp2: ssp@2a100 { + compatible = "intel,ssp"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0002a100 0x1000 + 0x00079C00 0x200>; + interrupts = <0x02 0 0>; + interrupt-parent = <&ace_intc>; + dmas = <&hda_link_out 3 + &hda_link_in 3>; + dma-names = "tx", "rx"; + ssp-index = <2>; + power-domain = <&io0_domain>; + status = "okay"; + + ssp20: ssp@20 { + compatible = "intel,ssp-dai"; + reg = <0x20>; + status = "okay"; + }; + }; + + mem_window0: mem_window@70200 { + compatible = "intel,adsp-mem-window"; + reg = <0x70200 0x8>; + offset = <0x4000>; + memory = <&sram0>; + initialize; + read-only; + }; + + mem_window1: mem_window@70208 { + compatible = "intel,adsp-mem-window"; + reg = <0x70208 0x8>; + memory = <&sram0>; + }; + + mem_window2: mem_window@70210 { + compatible = "intel,adsp-mem-window"; + reg = <0x70210 0x8>; + memory = <&sram0>; + }; + + mem_window3: mem_window@70218 { + compatible = "intel,adsp-mem-window"; + reg = <0x70218 0x8>; + memory = <&sram0>; + read-only; + }; + + adsp_idc: ace_idc@92000 { + compatible = "intel,adsp-idc"; + reg = <0x92000 0x0400>; + interrupts = <24 0 0>; + interrupt-parent = <&ace_intc>; + }; + + dfpmcch: dfpmcch@71ac0 { + compatible = "intel,adsp-dfpmcch"; + reg = <0x00071ac0 0x40>; + }; + + dfpmccu: dfpmccu@71b00 { + compatible = "intel,adsp-dfpmccu"; + reg = <0x71b00 0x100>; + + hub_ulp_domain: hub_ulp_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <15>; + }; + hub_hp_domain: hub_hpp_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <6>; + }; + io0_domain: io0_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <8>; + }; + io1_domain: io1_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <9>; + }; + io2_domain: io2_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <10>; + }; + io3_domain: io3_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <11>; + }; + hst_domain: hst_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <5>; + }; + ml0_domain: ml0_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <12>; + }; + ml1_domain: ml1_domain { + compatible = "intel,adsp-power-domain"; + bit-position = <13>; + }; + }; + + shim: shim@71f00 { + compatible = "intel,cavs-shim"; + reg = <0x71f00 0x100>; + }; + + tts: tts@72000 { + compatible = "intel,adsp-tts"; + reg = <0x72000 0x70>; + status = "okay"; + }; + + ace_rtc_counter: ace_rtc_counter@72008 { + compatible = "intel,ace-rtc-counter"; + reg = <0x72008 0x0064>; + }; + + ace_timestamp: ace_timestamp@72040 { + compatible = "intel,ace-timestamp"; + reg = <0x72040 0x0032>; + }; + + ace_art_counter: ace_art_counter@72058 { + compatible = "intel,ace-art-counter"; + reg = <0x72058 0x0064>; + }; + + hda_host_out: dma@72800 { + compatible = "intel,adsp-hda-host-out"; + #dma-cells = <1>; + reg = <0x00072800 0x40>; + dma-channels = <9>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&hst_domain>; + interrupts = <13 0 0>; + interrupt-parent = <&ace_intc>; + status = "okay"; + }; + + hda_host_in: dma@72c00 { + compatible = "intel,adsp-hda-host-in"; + #dma-cells = <1>; + reg = <0x00072c00 0x40>; + dma-channels = <11>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&hst_domain>; + interrupts = <12 0 0>; + interrupt-parent = <&ace_intc>; + status = "okay"; + }; + + adsp_host_ipc: ace_host_ipc@73000 { + compatible = "intel,adsp-host-ipc"; + status = "okay"; + reg = <0x73000 0x30>; + interrupts = <0 0 0>; + interrupt-parent = <&ace_intc>; + }; + + hda_link_out: dma@79400 { + compatible = "intel,adsp-hda-link-out"; + #dma-cells = <1>; + reg = <0x00079400 0x40>; + dma-channels = <9>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&io0_domain>; + status = "okay"; + }; + + hda_link_in: dma@79800 { + compatible = "intel,adsp-hda-link-in"; + #dma-cells = <1>; + reg = <0x00079800 0x40>; + dma-channels = <11>; + dma-buf-addr-alignment = <128>; + dma-buf-size-alignment = <32>; + dma-copy-alignment = <32>; + power-domain = <&io0_domain>; + status = "okay"; + }; + + /* This is actually an array of per-core designware + * controllers, but the special setup and extra + * masking layer makes it easier for MTL to handle + * this internally. + */ + ace_intc: ace_intc@94000 { + compatible = "intel,ace-intc"; + reg = <0x94000 0xc00>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <4 0 0>; + num-irqs = <28>; + interrupt-parent = <&core_intc>; + }; + + tlb: tlb@17e000 { + compatible = "intel,adsp-mtl-tlb"; + reg = <0x17e000 0x1000>; + paddr-size = <12>; + exec-bit-idx = <14>; + write-bit-idx= <15>; + }; + + timer: timer { + compatible = "intel,adsp-timer"; + syscon = <&tts>; + }; + }; + + hdas { + #address-cells = <1>; + #size-cells = <0>; + + hda0: hda@0 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0>; + }; + hda1: hda@1 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <1>; + }; + hda2: hda@2 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <2>; + }; + hda3: hda@3 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <3>; + }; + hda4: hda@4 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <4>; + }; + hda5: hda@5 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <5>; + }; + hda6: hda@6 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <6>; + }; + hda7: hda@7 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <7>; + }; + hda8: hda@8 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <8>; + }; + hda9: hda@9 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <9>; + }; + hda10: hda@a { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0a>; + }; + hda11: hda@b { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0b>; + }; + hda12: hda@c { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0c>; + }; + hda13: hda@d { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0d>; + }; + hda14: hda@e { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0e>; + }; + hda15: hda@f { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x0f>; + }; + hda16: hda@10 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x10>; + }; + hda17: hda@11 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x11>; + }; + hda18: hda@12 { + compatible = "intel,hda-dai"; + status = "okay"; + reg = <0x12>; + }; + }; +}; diff --git a/include/zephyr/arch/arc/v2/exception.h b/include/zephyr/arch/arc/v2/exception.h index 553024fa3a8c68..f606cf1ea9a7c7 100644 --- a/include/zephyr/arch/arc/v2/exception.h +++ b/include/zephyr/arch/arc/v2/exception.h @@ -18,11 +18,6 @@ extern "C" { #endif -#ifdef _ASMLANGUAGE -#else -typedef struct _irq_stack_frame z_arch_esf_t; -#endif - #ifdef __cplusplus } #endif diff --git a/include/zephyr/arch/arc/v2/linker.ld b/include/zephyr/arch/arc/v2/linker.ld index a7751d961194e6..c65aa5a648412e 100644 --- a/include/zephyr/arch/arc/v2/linker.ld +++ b/include/zephyr/arch/arc/v2/linker.ld @@ -81,6 +81,10 @@ SECTIONS { #include +#ifdef CONFIG_LLEXT +#include +#endif + GROUP_START(ROMABLE_REGION) SECTION_PROLOGUE(_TEXT_SECTION_NAME,,ALIGN(1024)) { diff --git a/include/zephyr/arch/arch_inlines.h b/include/zephyr/arch/arch_inlines.h index 4e1cd149dfb4d7..0f32159e2f1bf7 100644 --- a/include/zephyr/arch/arch_inlines.h +++ b/include/zephyr/arch/arch_inlines.h @@ -12,7 +12,7 @@ #ifndef ZEPHYR_INCLUDE_ARCH_INLINES_H_ #define ZEPHYR_INCLUDE_ARCH_INLINES_H_ -#if defined(CONFIG_X86) || defined(CONFIG_X86_64) +#if defined(CONFIG_X86) #include #elif defined(CONFIG_ARM) #include @@ -32,8 +32,6 @@ #include #elif defined(CONFIG_SPARC) #include -#else -#error "Unknown Architecture" #endif #endif /* ZEPHYR_INCLUDE_ARCH_INLINES_H_ */ diff --git a/include/zephyr/arch/arch_interface.h b/include/zephyr/arch/arch_interface.h index 04aef8157558b6..d7c33e511ce503 100644 --- a/include/zephyr/arch/arch_interface.h +++ b/include/zephyr/arch/arch_interface.h @@ -39,6 +39,7 @@ extern "C" { #endif /* NOTE: We cannot pull in kernel.h here, need some forward declarations */ +struct arch_esf; struct k_thread; struct k_mem_domain; @@ -46,6 +47,8 @@ typedef struct z_thread_stack_element k_thread_stack_t; typedef void (*k_thread_entry_t)(void *p1, void *p2, void *p3); +__deprecated typedef struct arch_esf z_arch_esf_t; + /** * @defgroup arch-timing Architecture timing APIs * @ingroup arch-interface @@ -491,10 +494,18 @@ static inline uint32_t arch_proc_id(void); /** * Broadcast an interrupt to all CPUs * - * This will invoke z_sched_ipi() on other CPUs in the system. + * This will invoke z_sched_ipi() on all other CPUs in the system. */ -void arch_sched_ipi(void); +void arch_sched_broadcast_ipi(void); +/** + * Direct IPIs to the specified CPUs + * + * This will invoke z_sched_ipi() on the CPUs identified by @a cpu_bitmap. + * + * @param cpu_bitmap A bitmap indicating which CPUs need the IPI + */ +void arch_sched_directed_ipi(uint32_t cpu_bitmap); int arch_smp_init(void); diff --git a/include/zephyr/arch/arm/cortex_a_r/exception.h b/include/zephyr/arch/arm/cortex_a_r/exception.h index 3bef647566d3ca..cd8377bc3a70c5 100644 --- a/include/zephyr/arch/arm/cortex_a_r/exception.h +++ b/include/zephyr/arch/arm/cortex_a_r/exception.h @@ -54,7 +54,7 @@ struct __extra_esf_info { }; #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ -struct __esf { +struct arch_esf { #if defined(CONFIG_EXTRA_EXCEPTION_INFO) struct __extra_esf_info extra_info; #endif @@ -75,8 +75,6 @@ struct __esf { extern uint32_t z_arm_coredump_fault_sp; -typedef struct __esf z_arch_esf_t; - extern void z_arm_exc_exit(bool fatal); #ifdef __cplusplus diff --git a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld index 947c18de313494..cffe2f3856e001 100644 --- a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld @@ -98,6 +98,10 @@ SECTIONS { #include +#ifdef CONFIG_LLEXT +#include +#endif + /* * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose', * before text section. diff --git a/include/zephyr/arch/arm/cortex_m/exception.h b/include/zephyr/arch/arm/cortex_m/exception.h index a9896cea1e4ed0..2deed9bdf832df 100644 --- a/include/zephyr/arch/arm/cortex_m/exception.h +++ b/include/zephyr/arch/arm/cortex_m/exception.h @@ -98,7 +98,7 @@ struct __extra_esf_info { }; #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ -struct __esf { +struct arch_esf { struct __basic_sf { sys_define_gpr_with_alias(a1, r0); sys_define_gpr_with_alias(a2, r1); @@ -119,8 +119,6 @@ struct __esf { extern uint32_t z_arm_coredump_fault_sp; -typedef struct __esf z_arch_esf_t; - extern void z_arm_exc_exit(void); #ifdef __cplusplus diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 88598cf5790ebd..094e4a5303f970 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -113,6 +113,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /* * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose', * before text section. diff --git a/include/zephyr/arch/arm/gdbstub.h b/include/zephyr/arch/arm/gdbstub.h index e8e606d7def805..55fceff173d10b 100644 --- a/include/zephyr/arch/arm/gdbstub.h +++ b/include/zephyr/arch/arm/gdbstub.h @@ -64,7 +64,7 @@ struct gdb_ctx { unsigned int registers[GDB_NUM_REGS]; }; -void z_gdb_entry(z_arch_esf_t *esf, unsigned int exc_cause); +void z_gdb_entry(struct arch_esf *esf, unsigned int exc_cause); #endif diff --git a/include/zephyr/arch/arm64/arm_mem.h b/include/zephyr/arch/arm64/arm_mem.h index 110f85a24caa60..4f81376caf7f28 100644 --- a/include/zephyr/arch/arm64/arm_mem.h +++ b/include/zephyr/arch/arm64/arm_mem.h @@ -7,7 +7,7 @@ #define ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MEM_H_ /* - * Define ARM specific memory flags used by z_phys_map() + * Define ARM specific memory flags used by k_mem_map_phys_bare() * followed public definitions in include/kernel/mm.h. */ /* For ARM64, K_MEM_CACHE_NONE is nGnRnE. */ diff --git a/include/zephyr/arch/arm64/exception.h b/include/zephyr/arch/arm64/exception.h index 05257c087fedac..a1348f608e3b9b 100644 --- a/include/zephyr/arch/arm64/exception.h +++ b/include/zephyr/arch/arm64/exception.h @@ -24,7 +24,7 @@ extern "C" { #endif -struct __esf { +struct arch_esf { uint64_t x0; uint64_t x1; uint64_t x2; @@ -55,8 +55,6 @@ struct __esf { #endif } __aligned(16); -typedef struct __esf z_arch_esf_t; - #ifdef __cplusplus } #endif diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld index 5a8e1404a98ae7..b360e4417bbe76 100644 --- a/include/zephyr/arch/arm64/scripts/linker.ld +++ b/include/zephyr/arch/arm64/scripts/linker.ld @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -66,6 +67,7 @@ MEMORY { FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE + LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ IDT_LIST (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K } @@ -77,6 +79,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /* * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose', * before text section. @@ -329,6 +335,8 @@ SECTIONS /DISCARD/ : { *(.note.GNU-stack) } + /* Sections generated from 'zephyr,memory-region' nodes */ + LINKER_DT_SECTIONS() /* Must be last in romable region */ SECTION_PROLOGUE(.last_section,,) diff --git a/include/zephyr/arch/cpu.h b/include/zephyr/arch/cpu.h index 11abe8df8c0b56..1e107512fa2a47 100644 --- a/include/zephyr/arch/cpu.h +++ b/include/zephyr/arch/cpu.h @@ -31,8 +31,6 @@ #include #elif defined(CONFIG_SPARC) #include -#else -#error "Unknown Architecture" #endif #endif /* ZEPHYR_INCLUDE_ARCH_CPU_H_ */ diff --git a/include/zephyr/arch/exception.h b/include/zephyr/arch/exception.h new file mode 100644 index 00000000000000..074a5e0b0d71cd --- /dev/null +++ b/include/zephyr/arch/exception.h @@ -0,0 +1,35 @@ +/* exception.h - automatically selects the correct exception.h file to include */ + +/* + * Copyright (c) 2024 Meta Platforms + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_EXCEPTION_H_ + +#if defined(CONFIG_X86_64) +#include +#elif defined(CONFIG_X86) +#include +#elif defined(CONFIG_ARM64) +#include +#elif defined(CONFIG_ARM) +#include +#elif defined(CONFIG_ARC) +#include +#elif defined(CONFIG_NIOS2) +#include +#elif defined(CONFIG_RISCV) +#include +#elif defined(CONFIG_XTENSA) +#include +#elif defined(CONFIG_MIPS) +#include +#elif defined(CONFIG_ARCH_POSIX) +#include +#elif defined(CONFIG_SPARC) +#include +#endif + +#endif /* ZEPHYR_INCLUDE_ARCH_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/mips/exception.h b/include/zephyr/arch/mips/exception.h index d4403f1d5995eb..f33af4c4387d84 100644 --- a/include/zephyr/arch/mips/exception.h +++ b/include/zephyr/arch/mips/exception.h @@ -17,7 +17,7 @@ extern "C" { #endif -struct __esf { +struct arch_esf { unsigned long ra; /* return address */ unsigned long gp; /* global pointer */ @@ -50,8 +50,6 @@ struct __esf { unsigned long cause; }; -typedef struct __esf z_arch_esf_t; - #ifdef __cplusplus } #endif diff --git a/include/zephyr/arch/mips/linker.ld b/include/zephyr/arch/mips/linker.ld index cbff890822c723..f7479c23e36b56 100644 --- a/include/zephyr/arch/mips/linker.ld +++ b/include/zephyr/arch/mips/linker.ld @@ -46,6 +46,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + SECTION_PROLOGUE(_VECTOR_SECTION_NAME,,) { . = ALIGN(0x1000); diff --git a/include/zephyr/arch/nios2/arch.h b/include/zephyr/arch/nios2/arch.h index 7df7ae9a91aa8c..5369f690b5d377 100644 --- a/include/zephyr/arch/nios2/arch.h +++ b/include/zephyr/arch/nios2/arch.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -99,34 +100,11 @@ static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) void arch_irq_enable(unsigned int irq); void arch_irq_disable(unsigned int irq); -struct __esf { - uint32_t ra; /* return address r31 */ - uint32_t r1; /* at */ - uint32_t r2; /* return value */ - uint32_t r3; /* return value */ - uint32_t r4; /* register args */ - uint32_t r5; /* register args */ - uint32_t r6; /* register args */ - uint32_t r7; /* register args */ - uint32_t r8; /* Caller-saved general purpose */ - uint32_t r9; /* Caller-saved general purpose */ - uint32_t r10; /* Caller-saved general purpose */ - uint32_t r11; /* Caller-saved general purpose */ - uint32_t r12; /* Caller-saved general purpose */ - uint32_t r13; /* Caller-saved general purpose */ - uint32_t r14; /* Caller-saved general purpose */ - uint32_t r15; /* Caller-saved general purpose */ - uint32_t estatus; - uint32_t instr; /* Instruction being executed when exc occurred */ -}; - -typedef struct __esf z_arch_esf_t; - FUNC_NORETURN void z_SysFatalErrorHandler(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); FUNC_NORETURN void z_NanoFatalErrorHandler(unsigned int reason, - const z_arch_esf_t *esf); + const struct arch_esf *esf); enum nios2_exception_cause { NIOS2_EXCEPTION_UNKNOWN = -1, diff --git a/include/zephyr/arch/nios2/exception.h b/include/zephyr/arch/nios2/exception.h new file mode 100644 index 00000000000000..223fa583114e6f --- /dev/null +++ b/include/zephyr/arch/nios2/exception.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct arch_esf { + uint32_t ra; /* return address r31 */ + uint32_t r1; /* at */ + uint32_t r2; /* return value */ + uint32_t r3; /* return value */ + uint32_t r4; /* register args */ + uint32_t r5; /* register args */ + uint32_t r6; /* register args */ + uint32_t r7; /* register args */ + uint32_t r8; /* Caller-saved general purpose */ + uint32_t r9; /* Caller-saved general purpose */ + uint32_t r10; /* Caller-saved general purpose */ + uint32_t r11; /* Caller-saved general purpose */ + uint32_t r12; /* Caller-saved general purpose */ + uint32_t r13; /* Caller-saved general purpose */ + uint32_t r14; /* Caller-saved general purpose */ + uint32_t r15; /* Caller-saved general purpose */ + uint32_t estatus; + uint32_t instr; /* Instruction being executed when exc occurred */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ */ diff --git a/include/zephyr/arch/nios2/linker.ld b/include/zephyr/arch/nios2/linker.ld index f7ba64088fc6ed..d65805ba7cf1e9 100644 --- a/include/zephyr/arch/nios2/linker.ld +++ b/include/zephyr/arch/nios2/linker.ld @@ -85,6 +85,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /* * .plt and .iplt are here according to * 'nios2-zephyr-elf-ld --verbose', before text section. diff --git a/include/zephyr/arch/posix/arch.h b/include/zephyr/arch/posix/arch.h index 83aceb1c14ba1f..7dbfb6b386450a 100644 --- a/include/zephyr/arch/posix/arch.h +++ b/include/zephyr/arch/posix/arch.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include /* Each board must define this */ @@ -38,12 +39,6 @@ extern "C" { #define ARCH_STACK_PTR_ALIGN 4 #endif -struct __esf { - uint32_t dummy; /*maybe we will want to add something someday*/ -}; - -typedef struct __esf z_arch_esf_t; - extern uint32_t sys_clock_cycle_get_32(void); static inline uint32_t arch_k_cycle_get_32(void) diff --git a/include/zephyr/arch/posix/exception.h b/include/zephyr/arch/posix/exception.h new file mode 100644 index 00000000000000..6c7962aa057993 --- /dev/null +++ b/include/zephyr/arch/posix/exception.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2014 Wind River Systems, Inc. + * Copyright (c) 2017 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct arch_esf { + uint32_t dummy; /*maybe we will want to add something someday*/ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ */ diff --git a/include/zephyr/arch/posix/linker.ld b/include/zephyr/arch/posix/linker.ld index 06dfb3254f1724..0943546c0c7b0d 100644 --- a/include/zephyr/arch/posix/linker.ld +++ b/include/zephyr/arch/posix/linker.ld @@ -21,6 +21,10 @@ SECTIONS { +#ifdef CONFIG_LLEXT +#include +#endif + SECTION_PROLOGUE(rom_start,,) { /* Located in generated directory. This file is populated by the diff --git a/include/zephyr/arch/riscv/arch.h b/include/zephyr/arch/riscv/arch.h index e7dcfbef3aed14..4cdedb700d3261 100644 --- a/include/zephyr/arch/riscv/arch.h +++ b/include/zephyr/arch/riscv/arch.h @@ -48,12 +48,12 @@ */ #ifdef CONFIG_PMP_POWER_OF_TWO_ALIGNMENT #define Z_RISCV_STACK_GUARD_SIZE \ - Z_POW2_CEIL(MAX(sizeof(z_arch_esf_t) + CONFIG_PMP_STACK_GUARD_MIN_SIZE, \ + Z_POW2_CEIL(MAX(sizeof(struct arch_esf) + CONFIG_PMP_STACK_GUARD_MIN_SIZE, \ Z_RISCV_STACK_PMP_ALIGN)) #define ARCH_KERNEL_STACK_OBJ_ALIGN Z_RISCV_STACK_GUARD_SIZE #else #define Z_RISCV_STACK_GUARD_SIZE \ - ROUND_UP(sizeof(z_arch_esf_t) + CONFIG_PMP_STACK_GUARD_MIN_SIZE, \ + ROUND_UP(sizeof(struct arch_esf) + CONFIG_PMP_STACK_GUARD_MIN_SIZE, \ Z_RISCV_STACK_PMP_ALIGN) #define ARCH_KERNEL_STACK_OBJ_ALIGN Z_RISCV_STACK_PMP_ALIGN #endif diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index ccb16cc2c670b4..5b996bc48d57f5 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -55,13 +55,18 @@ #elif DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_flash), jedec_spi_nor) /* For jedec,spi-nor we expect the spi controller to memory map the flash - * and for that mapping to be the second register property of the spi - * controller. + * and for that mapping to be on the register with the name flash_mmap and if a register with that + * name doesn't exists, we expect it to be in the second register property of the spi controller. */ #define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash)) -#define ROM_BASE (DT_REG_ADDR_BY_IDX(SPI_CTRL, 1) + FLASH_LOAD_OFFSET) +#define FLASH_MMAP_NAME flash_mmap +#define ROM_BASE \ + (DT_REG_ADDR_BY_NAME_OR(SPI_CTRL, FLASH_MMAP_NAME, DT_REG_ADDR_BY_IDX(SPI_CTRL, 1)) + \ + FLASH_LOAD_OFFSET) #ifndef ROM_SIZE -#define ROM_SIZE (DT_REG_SIZE_BY_IDX(SPI_CTRL, 1) - ROM_END_OFFSET) +#define ROM_SIZE \ + (DT_REG_SIZE_BY_NAME_OR(SPI_CTRL, FLASH_MMAP_NAME, DT_REG_SIZE_BY_IDX(SPI_CTRL, 1)) - \ + ROM_END_OFFSET) #endif #else /* Use Kconfig to cover the remaining cases */ @@ -122,6 +127,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /* * The .plt and .iplt are here according to * 'riscv32-zephyr-elf-ld --verbose', before text section. diff --git a/include/zephyr/arch/riscv/exception.h b/include/zephyr/arch/riscv/exception.h index 644df2cd1fbf91..097776227bb472 100644 --- a/include/zephyr/arch/riscv/exception.h +++ b/include/zephyr/arch/riscv/exception.h @@ -48,7 +48,7 @@ struct soc_esf { #if defined(CONFIG_RISCV_SOC_HAS_ISR_STACKING) SOC_ISR_STACKING_ESF_DECLARE; #else -struct __esf { +struct arch_esf { unsigned long ra; /* return address */ unsigned long t0; /* Caller-saved temporary register */ @@ -87,7 +87,6 @@ struct __esf { } __aligned(16); #endif /* CONFIG_RISCV_SOC_HAS_ISR_STACKING */ -typedef struct __esf z_arch_esf_t; #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE typedef struct soc_esf soc_esf_t; #endif diff --git a/include/zephyr/arch/sparc/arch.h b/include/zephyr/arch/sparc/arch.h index df3c40e4ba4a31..c1d87682f39bbe 100644 --- a/include/zephyr/arch/sparc/arch.h +++ b/include/zephyr/arch/sparc/arch.h @@ -14,6 +14,7 @@ #ifndef ZEPHYR_INCLUDE_ARCH_SPARC_ARCH_H_ #define ZEPHYR_INCLUDE_ARCH_SPARC_ARCH_H_ +#include #include #include #include @@ -107,19 +108,6 @@ static inline uint64_t arch_k_cycle_get_64(void) return sys_clock_cycle_get_64(); } -struct __esf { - uint32_t out[8]; - uint32_t global[8]; - uint32_t psr; - uint32_t pc; - uint32_t npc; - uint32_t wim; - uint32_t tbr; - uint32_t y; -}; - -typedef struct __esf z_arch_esf_t; - #define ARCH_EXCEPT(reason_p) \ do { \ register uint32_t _g1 __asm__("g1") = reason_p; \ diff --git a/include/zephyr/arch/sparc/exception.h b/include/zephyr/arch/sparc/exception.h new file mode 100644 index 00000000000000..a2d3fae52e2036 --- /dev/null +++ b/include/zephyr/arch/sparc/exception.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct arch_esf { + uint32_t out[8]; + uint32_t global[8]; + uint32_t psr; + uint32_t pc; + uint32_t npc; + uint32_t wim; + uint32_t tbr; + uint32_t y; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ */ diff --git a/include/zephyr/arch/sparc/linker.ld b/include/zephyr/arch/sparc/linker.ld index 725339ef0b7cd8..ccf333d4863c40 100644 --- a/include/zephyr/arch/sparc/linker.ld +++ b/include/zephyr/arch/sparc/linker.ld @@ -23,6 +23,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + __rom_region_start = .; SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) diff --git a/include/zephyr/arch/syscall.h b/include/zephyr/arch/syscall.h index 5b41561b681907..966f6003098ba8 100644 --- a/include/zephyr/arch/syscall.h +++ b/include/zephyr/arch/syscall.h @@ -9,12 +9,10 @@ #ifndef ZEPHYR_INCLUDE_ARCH_SYSCALL_H_ #define ZEPHYR_INCLUDE_ARCH_SYSCALL_H_ -#if defined(CONFIG_X86) #if defined(CONFIG_X86_64) #include -#else +#elif defined(CONFIG_X86) #include -#endif #elif defined(CONFIG_ARM64) #include #elif defined(CONFIG_ARM) diff --git a/include/zephyr/arch/x86/ia32/arch.h b/include/zephyr/arch/x86/ia32/arch.h index 490dfdb40f334d..b82e0db0f1733e 100644 --- a/include/zephyr/arch/x86/ia32/arch.h +++ b/include/zephyr/arch/x86/ia32/arch.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -333,53 +334,6 @@ static inline void arch_isr_direct_footer(int swap) static inline int name##_body(void) #endif /* !CONFIG_X86_KPTI */ -/** - * @brief Exception Stack Frame - * - * A pointer to an "exception stack frame" (ESF) is passed as an argument - * to exception handlers registered via nanoCpuExcConnect(). As the system - * always operates at ring 0, only the EIP, CS and EFLAGS registers are pushed - * onto the stack when an exception occurs. - * - * The exception stack frame includes the volatile registers (EAX, ECX, and - * EDX) as well as the 5 non-volatile registers (EDI, ESI, EBX, EBP and ESP). - * Those registers are pushed onto the stack by _ExcEnt(). - */ - -typedef struct nanoEsf { -#ifdef CONFIG_GDBSTUB - unsigned int ss; - unsigned int gs; - unsigned int fs; - unsigned int es; - unsigned int ds; -#endif - unsigned int esp; - unsigned int ebp; - unsigned int ebx; - unsigned int esi; - unsigned int edi; - unsigned int edx; - unsigned int eax; - unsigned int ecx; - unsigned int errorCode; - unsigned int eip; - unsigned int cs; - unsigned int eflags; -} z_arch_esf_t; - -extern unsigned int z_x86_exception_vector; - -struct _x86_syscall_stack_frame { - uint32_t eip; - uint32_t cs; - uint32_t eflags; - - /* These are only present if cs = USER_CODE_SEG */ - uint32_t esp; - uint32_t ss; -}; - static ALWAYS_INLINE unsigned int arch_irq_lock(void) { unsigned int key; diff --git a/include/zephyr/arch/x86/ia32/exception.h b/include/zephyr/arch/x86/ia32/exception.h new file mode 100644 index 00000000000000..de618f4e01d438 --- /dev/null +++ b/include/zephyr/arch/x86/ia32/exception.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2010-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Exception Stack Frame + * + * A pointer to an "exception stack frame" (ESF) is passed as an argument + * to exception handlers registered via nanoCpuExcConnect(). As the system + * always operates at ring 0, only the EIP, CS and EFLAGS registers are pushed + * onto the stack when an exception occurs. + * + * The exception stack frame includes the volatile registers (EAX, ECX, and + * EDX) as well as the 5 non-volatile registers (EDI, ESI, EBX, EBP and ESP). + * Those registers are pushed onto the stack by _ExcEnt(). + */ + +struct arch_esf { +#ifdef CONFIG_GDBSTUB + unsigned int ss; + unsigned int gs; + unsigned int fs; + unsigned int es; + unsigned int ds; +#endif + unsigned int esp; + unsigned int ebp; + unsigned int ebx; + unsigned int esi; + unsigned int edi; + unsigned int edx; + unsigned int eax; + unsigned int ecx; + unsigned int errorCode; + unsigned int eip; + unsigned int cs; + unsigned int eflags; +}; + +extern unsigned int z_x86_exception_vector; + +struct _x86_syscall_stack_frame { + uint32_t eip; + uint32_t cs; + uint32_t eflags; + + /* These are only present if cs = USER_CODE_SEG */ + uint32_t esp; + uint32_t ss; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ */ diff --git a/include/zephyr/arch/x86/ia32/linker.ld b/include/zephyr/arch/x86/ia32/linker.ld index 69ff541232695d..5994379eeefc8d 100644 --- a/include/zephyr/arch/x86/ia32/linker.ld +++ b/include/zephyr/arch/x86/ia32/linker.ld @@ -44,7 +44,7 @@ #include -#if defined(CONFIG_XIP) || defined(Z_VM_KERNEL) +#if defined(CONFIG_XIP) || defined(K_MEM_IS_VM_KERNEL) #define ROMABLE_REGION ROM #define RAMABLE_REGION RAM #else @@ -68,7 +68,7 @@ #define MMU_PAGE_ALIGN_PERM #endif -epoint = Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); +epoint = K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); ENTRY(epoint) /* SECTIONS definitions */ @@ -77,6 +77,10 @@ SECTIONS #include +#ifdef CONFIG_LLEXT +#include +#endif + /DISCARD/ : { *(.plt) diff --git a/include/zephyr/arch/x86/intel64/arch.h b/include/zephyr/arch/x86/intel64/arch.h index c176e4e0bb0ba2..86de01297f4727 100644 --- a/include/zephyr/arch/x86/intel64/arch.h +++ b/include/zephyr/arch/x86/intel64/arch.h @@ -6,6 +6,7 @@ #ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_ #define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_ +#include #include #include #if defined(CONFIG_PCIE) && !defined(_ASMLANGUAGE) @@ -52,61 +53,6 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) return (unsigned int) key; } -/* - * the exception stack frame - */ - -struct x86_esf { -#ifdef CONFIG_EXCEPTION_DEBUG - /* callee-saved */ - unsigned long rbx; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long r15; -#endif /* CONFIG_EXCEPTION_DEBUG */ - unsigned long rbp; - - /* Caller-saved regs */ - unsigned long rax; - unsigned long rcx; - unsigned long rdx; - unsigned long rsi; - unsigned long rdi; - unsigned long r8; - unsigned long r9; - unsigned long r10; - /* Must be aligned 16 bytes from the end of this struct due to - * requirements of 'fxsave (%rsp)' - */ - char fxsave[X86_FXSAVE_SIZE]; - unsigned long r11; - - /* Pushed by CPU or assembly stub */ - unsigned long vector; - unsigned long code; - unsigned long rip; - unsigned long cs; - unsigned long rflags; - unsigned long rsp; - unsigned long ss; -}; - -typedef struct x86_esf z_arch_esf_t; - -struct x86_ssf { - unsigned long rip; - unsigned long rflags; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long rdx; - unsigned long rsi; - char fxsave[X86_FXSAVE_SIZE]; - unsigned long rdi; - unsigned long rsp; -}; - #define ARCH_EXCEPT(reason_p) do { \ __asm__ volatile( \ "movq %[reason], %%rax\n\t" \ diff --git a/include/zephyr/arch/x86/intel64/exception.h b/include/zephyr/arch/x86/intel64/exception.h new file mode 100644 index 00000000000000..55c7cc2b4ee84f --- /dev/null +++ b/include/zephyr/arch/x86/intel64/exception.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 Intel Corp. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * the exception stack frame + */ + +struct arch_esf { +#ifdef CONFIG_EXCEPTION_DEBUG + /* callee-saved */ + unsigned long rbx; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; +#endif /* CONFIG_EXCEPTION_DEBUG */ + unsigned long rbp; + + /* Caller-saved regs */ + unsigned long rax; + unsigned long rcx; + unsigned long rdx; + unsigned long rsi; + unsigned long rdi; + unsigned long r8; + unsigned long r9; + unsigned long r10; + /* Must be aligned 16 bytes from the end of this struct due to + * requirements of 'fxsave (%rsp)' + */ + char fxsave[X86_FXSAVE_SIZE]; + unsigned long r11; + + /* Pushed by CPU or assembly stub */ + unsigned long vector; + unsigned long code; + unsigned long rip; + unsigned long cs; + unsigned long rflags; + unsigned long rsp; + unsigned long ss; +}; + +struct x86_ssf { + unsigned long rip; + unsigned long rflags; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long rdx; + unsigned long rsi; + char fxsave[X86_FXSAVE_SIZE]; + unsigned long rdi; + unsigned long rsp; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ */ diff --git a/include/zephyr/arch/x86/intel64/linker.ld b/include/zephyr/arch/x86/intel64/linker.ld index 8949b94e657fdf..1bc014570c6389 100644 --- a/include/zephyr/arch/x86/intel64/linker.ld +++ b/include/zephyr/arch/x86/intel64/linker.ld @@ -236,4 +236,7 @@ SECTIONS .shstrtab 0 : { *(.shstrtab) } #endif +#ifdef CONFIG_LLEXT + #include +#endif } diff --git a/include/zephyr/arch/x86/memory.ld b/include/zephyr/arch/x86/memory.ld index c9ede2b9d23293..3e2c0b6935275d 100644 --- a/include/zephyr/arch/x86/memory.ld +++ b/include/zephyr/arch/x86/memory.ld @@ -39,7 +39,7 @@ * the same as its physical location, although an identity mapping for RAM * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS. */ -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL #define KERNEL_BASE_ADDR (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) #define KERNEL_RAM_SIZE (CONFIG_KERNEL_VM_SIZE - CONFIG_KERNEL_VM_OFFSET) #define PHYS_RAM_AVAIL (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET) @@ -87,7 +87,7 @@ MEMORY * or copied into physical RAM by a loader (MMU) */ ROM (rx) : ORIGIN = PHYS_LOAD_ADDR, LENGTH = FLASH_ROM_SIZE -#elif defined(Z_VM_KERNEL) +#elif defined(K_MEM_IS_VM_KERNEL) ROM (rx) : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL #endif /* Linear address range to link the kernel. If non-XIP, everything is diff --git a/include/zephyr/arch/xtensa/exception.h b/include/zephyr/arch/xtensa/exception.h index 51a5d5aef9036c..acc6d4a30413b3 100644 --- a/include/zephyr/arch/xtensa/exception.h +++ b/include/zephyr/arch/xtensa/exception.h @@ -25,7 +25,9 @@ extern "C" { * register windows are in use. This isn't a struct type, it just * matches the register/stack-unit width. */ -typedef int z_arch_esf_t; +struct arch_esf { + int dummy; +}; #endif diff --git a/include/zephyr/arch/xtensa/xtensa_mmu.h b/include/zephyr/arch/xtensa/xtensa_mmu.h index d4deca40b311b2..91da6a4f656882 100644 --- a/include/zephyr/arch/xtensa/xtensa_mmu.h +++ b/include/zephyr/arch/xtensa/xtensa_mmu.h @@ -123,6 +123,16 @@ extern int xtensa_soc_mmu_ranges_num; */ void xtensa_mmu_init(void); +/** + * @brief Re-initialize hardware MMU. + * + * This configures the MMU hardware when the cpu lost context and has + * re-started. + * + * It assumes that the page table is already created and accessible in memory. + */ +void xtensa_mmu_reinit(void); + /** * @brief Tell other processors to flush TLBs. * diff --git a/include/zephyr/bluetooth/audio/aics.h b/include/zephyr/bluetooth/audio/aics.h index 55f2eab2f931ab..a554c1503959ab 100644 --- a/include/zephyr/bluetooth/audio/aics.h +++ b/include/zephyr/bluetooth/audio/aics.h @@ -27,7 +27,10 @@ * autonomously read the change counter value when executing a write request. * */ +#include +#include +#include #include #ifdef __cplusplus diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 0578f632bd2f40..21af8e5d385779 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -18,14 +18,21 @@ * @{ */ -#include +#include +#include +#include + +#include +#include +#include #include #include +#include #include #include -#include -#include - +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -41,6 +48,9 @@ extern "C" { #define BT_AUDIO_BROADCAST_CODE_SIZE 16 +/** Size of the stream language value, e.g. "eng" */ +#define BT_AUDIO_LANG_SIZE 3 + /** * @brief Codec capability types * @@ -373,11 +383,12 @@ enum bt_audio_metadata_type { /** UTF-8 encoded title or summary of stream content */ BT_AUDIO_METADATA_TYPE_PROGRAM_INFO = 0x03, - /** @brief Stream language + /** @brief Language * * 3 octet lower case language code defined by ISO 639-3 + * Possible values can be found at https://iso639-3.sil.org/code_tables/639/data */ - BT_AUDIO_METADATA_TYPE_STREAM_LANG = 0x04, + BT_AUDIO_METADATA_TYPE_LANG = 0x04, /** Array of 8-bit CCID values */ BT_AUDIO_METADATA_TYPE_CCID_LIST = 0x05, @@ -975,24 +986,29 @@ int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg) int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_codec_cfg_frame_dur frame_dur); -/** @brief Extract channel allocation from BT codec config +/** + * @brief Extract channel allocation from BT codec config * - * The value returned is a bit field representing one or more audio locations as - * specified by @ref bt_audio_location - * Shall match one or more of the bits set in BT_PAC_SNK_LOC/BT_PAC_SRC_LOC. + * The value returned is a bit field representing one or more audio locations as + * specified by @ref bt_audio_location + * Shall match one or more of the bits set in BT_PAC_SNK_LOC/BT_PAC_SRC_LOC. * - * Up to the configured @ref BT_AUDIO_CODEC_CAP_TYPE_CHAN_COUNT number of channels can be present. + * Up to the configured @ref BT_AUDIO_CODEC_CAP_TYPE_CHAN_COUNT number of channels can be present. * - * @param codec_cfg The codec configuration to extract data from. - * @param chan_allocation Pointer to the variable to store the extracted value in. + * @param codec_cfg The codec configuration to extract data from. + * @param chan_allocation Pointer to the variable to store the extracted value in. + * @param fallback_to_default If true this function will provide the default value of + * @ref BT_AUDIO_LOCATION_MONO_AUDIO if the type is not found when @p codec_cfg.id is @ref + * BT_HCI_CODING_FORMAT_LC3. * - * @retval 0 if value is found and stored in the pointer provided - * @retval -EINVAL if arguments are invalid - * @retval -ENODATA if not found - * @retval -EBADMSG if found value has invalid size or value + * @retval 0 if value is found and stored in the pointer provided + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg, - enum bt_audio_location *chan_allocation); + enum bt_audio_location *chan_allocation, + bool fallback_to_default); /** * @brief Set the channel allocation of a codec configuration. @@ -1011,7 +1027,7 @@ int bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg *codec_cfg, * * The overall SDU size will be octets_per_frame * blocks_per_sdu. * - * The Bluetooth specificationa are not clear about this value - it does not state that + * The Bluetooth specifications are not clear about this value - it does not state that * the codec shall use this SDU size only. A codec like LC3 supports variable bit-rate * (per SDU) hence it might be allowed for an encoder to reduce the frame size below this * value. @@ -1040,26 +1056,25 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg, uint16_t octets_per_frame); -/** @brief Extract number of audio frame blockss in each SDU from BT codec config +/** + * @brief Extract number of audio frame blocks in each SDU from BT codec config * - * The overall SDU size will be octets_per_frame * frame_blocks_per_sdu * number-of-channels. + * The overall SDU size will be octets_per_frame * frame_blocks_per_sdu * number-of-channels. * - * If this value is not present a default value of 1 shall be used. + * If this value is not present a default value of 1 shall be used. * - * A frame block is one or more frames that represents data for the same period of time but - * for different channels. If the stream have two audio channels and this value is two - * there will be four frames in the SDU. + * A frame block is one or more frames that represents data for the same period of time but + * for different channels. If the stream have two audio channels and this value is two + * there will be four frames in the SDU. * - * @param codec_cfg The codec configuration to extract data from. - * @param fallback_to_default If true this function will return the default value of 1 - * if the type is not found. In this case the function will only fail if a NULL - * pointer is provided. + * @param codec_cfg The codec configuration to extract data from. + * @param fallback_to_default If true this function will return the default value of 1 + * if the type is not found when @p codec_cfg.id is @ref BT_HCI_CODING_FORMAT_LC3. * - * @retval The count of codec frames in each SDU if value is found else of @p fallback_to_default - * is true then the value 1 is returned if frames per sdu is not found. - * @retval -EINVAL if arguments are invalid - * @retval -ENODATA if not found - * @retval -EBADMSG if found value has invalid size or value + * @retval The count of codec frame blocks in each SDU. + * @retval -EINVAL if arguments are invalid + * @retval -ENODATA if not found + * @retval -EBADMSG if found value has invalid size or value */ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default); @@ -1163,18 +1178,23 @@ int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg, */ int bt_audio_codec_cfg_meta_unset_val(struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_metadata_type type); -/** @brief Extract preferred contexts +/** + * @brief Extract preferred contexts * - * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. + * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. * - * @param codec_cfg The codec data to search in. + * @param codec_cfg The codec data to search in. + * @param fallback_to_default If true this function will provide the default value of + * @ref BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED if the type is not found when @p codec_cfg.id is + * @ref BT_HCI_CODING_FORMAT_LC3. * * @retval The preferred context type if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg); +int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg, + bool fallback_to_default); /** * @brief Set the preferred context of a codec configuration metadata. @@ -1243,31 +1263,33 @@ int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *co int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg, const uint8_t *program_info, size_t program_info_len); -/** @brief Extract stream language +/** @brief Extract language * - * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. + * See @ref BT_AUDIO_METADATA_TYPE_LANG for more information about this value. * - * @param codec_cfg The codec data to search in. + * @param[in] codec_cfg The codec data to search in. + * @param[out] lang Pointer to the language bytes (of length BT_AUDIO_LANG_SIZE) * - * @retval The stream language if positive or 0 + * @retval The language if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg); +int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **lang); /** - * @brief Set the stream language of a codec configuration metadata. + * @brief Set the language of a codec configuration metadata. * * @param codec_cfg The codec configuration to set data for. - * @param stream_lang The 24-bit stream language to set. + * @param lang The 24-bit language to set. * * @retval The data_len of @p codec_cfg on success * @retval -EINVAL if arguments are invalid * @retval -ENOMEM if the new value could not set or added due to memory */ -int bt_audio_codec_cfg_meta_set_stream_lang(struct bt_audio_codec_cfg *codec_cfg, - uint32_t stream_lang); +int bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t lang[BT_AUDIO_LANG_SIZE]); /** @brief Extract CCID list * @@ -1568,13 +1590,16 @@ int bt_audio_codec_cap_set_frame_dur(struct bt_audio_codec_cap *codec_cap, * @brief Extract the frequency from a codec capability. * * @param codec_cap The codec capabilities to extract data from. + * @param fallback_to_default If true this function will provide the default value of 1 + * if the type is not found when @p codec_cap.id is @ref BT_HCI_CODING_FORMAT_LC3. * - * @retval Bitfield of supported channel counts if 0 or positive + * @retval Number of supported channel counts if 0 or positive * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap); +int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap, + bool fallback_to_default); /** * @brief Set the channel count of a codec capability. @@ -1622,13 +1647,16 @@ int bt_audio_codec_cap_set_octets_per_frame( * @brief Extract the maximum codec frames per SDU from a codec capability. * * @param codec_cap The codec capabilities to extract data from. + * @param fallback_to_default If true this function will provide the default value of 1 + * if the type is not found when @p codec_cap.id is @ref BT_HCI_CODING_FORMAT_LC3. * * @retval Maximum number of codec frames per SDU supported * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap); +int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap, + bool fallback_to_default); /** * @brief Set the maximum codec frames per SDU of a codec capability. @@ -1766,31 +1794,33 @@ int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *co int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap, const uint8_t *program_info, size_t program_info_len); -/** @brief Extract stream language +/** @brief Extract language * - * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. + * See @ref BT_AUDIO_METADATA_TYPE_LANG for more information about this value. * - * @param codec_cap The codec data to search in. + * @param[in] codec_cap The codec data to search in. + * @param[out] lang Pointer to the language bytes (of length BT_AUDIO_LANG_SIZE) * - * @retval The stream language if positive or 0 + * @retval 0 On success * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap); +int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **lang); /** - * @brief Set the stream language of a codec capability metadata. + * @brief Set the language of a codec capability metadata. * * @param codec_cap The codec capability to set data for. - * @param stream_lang The 24-bit stream language to set. + * @param lang The 24-bit language to set. * * @retval The data_len of @p codec_cap on success * @retval -EINVAL if arguments are invalid * @retval -ENOMEM if the new value could not set or added due to memory */ -int bt_audio_codec_cap_meta_set_stream_lang(struct bt_audio_codec_cap *codec_cap, - uint32_t stream_lang); +int bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap *codec_cap, + const uint8_t lang[BT_AUDIO_LANG_SIZE]); /** @brief Extract CCID list * diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 32d9840c5be5bb..00957b2b81be54 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -17,9 +17,17 @@ * @{ */ -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/bap_lc3_preset.h b/include/zephyr/bluetooth/audio/bap_lc3_preset.h index d31c47fd4fb792..7ba6af250a2169 100644 --- a/include/zephyr/bluetooth/audio/bap_lc3_preset.h +++ b/include/zephyr/bluetooth/audio/bap_lc3_preset.h @@ -10,6 +10,7 @@ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BAP_LC3_PRESET_ #include +#include /** Struct to hold a BAP defined LC3 preset */ struct bt_bap_lc3_preset { diff --git a/include/zephyr/bluetooth/audio/cap.h b/include/zephyr/bluetooth/audio/cap.h index 6bf5e1b018e12b..afc1ca9018ef05 100644 --- a/include/zephyr/bluetooth/audio/cap.h +++ b/include/zephyr/bluetooth/audio/cap.h @@ -19,12 +19,18 @@ * @{ */ +#include +#include #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -296,6 +302,16 @@ struct bt_cap_unicast_audio_stop_param { */ int bt_cap_initiator_register_cb(const struct bt_cap_initiator_cb *cb); +/** + * @brief Unregister Common Audio Profile Initiator callbacks + * + * @param cb The callback structure that was previously registered. + * + * @retval 0 Success + * @retval -EINVAL @p cb is NULL or @p cb was not registered + */ +int bt_cap_initiator_unregister_cb(const struct bt_cap_initiator_cb *cb); + /** * @brief Setup and start unicast audio streams for a set of devices. * diff --git a/include/zephyr/bluetooth/audio/csip.h b/include/zephyr/bluetooth/audio/csip.h index 6f3a028024236a..7b8d8d2631fe40 100644 --- a/include/zephyr/bluetooth/audio/csip.h +++ b/include/zephyr/bluetooth/audio/csip.h @@ -19,7 +19,16 @@ * @{ */ +#include +#include +#include + +#include +#include #include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/gmap_lc3_preset.h b/include/zephyr/bluetooth/audio/gmap_lc3_preset.h index e5a22936c741e3..5e50de243e7fdb 100644 --- a/include/zephyr/bluetooth/audio/gmap_lc3_preset.h +++ b/include/zephyr/bluetooth/audio/gmap_lc3_preset.h @@ -9,7 +9,9 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_LC3_PRESET_ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_LC3_PRESET_ +#include #include +#include /* GMAP LC3 unicast presets defined by table 3.16 in the GMAP v1.0 specification */ diff --git a/include/zephyr/bluetooth/audio/has.h b/include/zephyr/bluetooth/audio/has.h index 0e5c165290215d..7bd20aec89e3aa 100644 --- a/include/zephyr/bluetooth/audio/has.h +++ b/include/zephyr/bluetooth/audio/has.h @@ -22,10 +22,12 @@ * to control hearing aid presets. */ -#include +#include +#include #include #include +#include #ifdef __cplusplus extern "C" { @@ -63,7 +65,7 @@ enum bt_has_properties { BT_HAS_PROP_AVAILABLE = BIT(1), }; -/** Hearing Aid device capablilities */ +/** Hearing Aid device capabilities */ enum bt_has_capabilities { BT_HAS_PRESET_SUPPORT = BIT(0), }; diff --git a/include/zephyr/bluetooth/audio/mcc.h b/include/zephyr/bluetooth/audio/mcc.h index 14dba829225301..fb71f011db96ef 100644 --- a/include/zephyr/bluetooth/audio/mcc.h +++ b/include/zephyr/bluetooth/audio/mcc.h @@ -22,6 +22,7 @@ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MCC_ #include +#include #include #include @@ -407,7 +408,7 @@ typedef void (*bt_mcc_read_content_control_id_cb)(struct bt_conn *conn, typedef void (*bt_mcc_otc_obj_selected_cb)(struct bt_conn *conn, int err); /** - * @brief Callback function for bt_mcc_otc_read_object_meatadata() + * @brief Callback function for bt_mcc_otc_read_object_metadata() * * Called when object metadata is read * diff --git a/include/zephyr/bluetooth/audio/mcs.h b/include/zephyr/bluetooth/audio/mcs.h index 7d9491944ef275..5212905497c276 100644 --- a/include/zephyr/bluetooth/audio/mcs.h +++ b/include/zephyr/bluetooth/audio/mcs.h @@ -23,6 +23,7 @@ */ #include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/media_proxy.h b/include/zephyr/bluetooth/audio/media_proxy.h index 0e236a1fd4a072..16bb978bfcc48b 100644 --- a/include/zephyr/bluetooth/audio/media_proxy.h +++ b/include/zephyr/bluetooth/audio/media_proxy.h @@ -40,6 +40,7 @@ #include #include +#include /* TODO: Remove dependency on mcs.h */ #include "mcs.h" diff --git a/include/zephyr/bluetooth/audio/micp.h b/include/zephyr/bluetooth/audio/micp.h index 500eb2048395f3..0fe9a7af681f5e 100644 --- a/include/zephyr/bluetooth/audio/micp.h +++ b/include/zephyr/bluetooth/audio/micp.h @@ -22,6 +22,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/pacs.h b/include/zephyr/bluetooth/audio/pacs.h index 6db4d34b0a285b..74f401d7bd54fe 100644 --- a/include/zephyr/bluetooth/audio/pacs.h +++ b/include/zephyr/bluetooth/audio/pacs.h @@ -10,7 +10,11 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_PACS_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_PACS_H_ +#include + #include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/pbp.h b/include/zephyr/bluetooth/audio/pbp.h index 71d7d107b4e9c8..d218720895d34a 100644 --- a/include/zephyr/bluetooth/audio/pbp.h +++ b/include/zephyr/bluetooth/audio/pbp.h @@ -19,8 +19,12 @@ * @{ */ -#include #include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/audio/tbs.h b/include/zephyr/bluetooth/audio/tbs.h index 523efc4264fc1d..49039a7ff6145f 100644 --- a/include/zephyr/bluetooth/audio/tbs.h +++ b/include/zephyr/bluetooth/audio/tbs.h @@ -14,6 +14,7 @@ #include #include +#include /* Call States */ #define BT_TBS_CALL_STATE_INCOMING 0x00 diff --git a/include/zephyr/bluetooth/audio/tmap.h b/include/zephyr/bluetooth/audio/tmap.h index 4bcdbb0a5bfc81..1c8e8ccb8921d5 100644 --- a/include/zephyr/bluetooth/audio/tmap.h +++ b/include/zephyr/bluetooth/audio/tmap.h @@ -9,8 +9,10 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_TMAP_ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_TMAP_ +#include #include #include +#include /** Call Gateway (CG) supported */ #define BT_TMAP_CG_SUPPORTED \ diff --git a/include/zephyr/bluetooth/audio/vcp.h b/include/zephyr/bluetooth/audio/vcp.h index 1128bf18d1e4b7..755ee12d065abd 100644 --- a/include/zephyr/bluetooth/audio/vcp.h +++ b/include/zephyr/bluetooth/audio/vcp.h @@ -23,6 +23,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 72c386ae4d68bb..202d29eb9caa2a 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -235,6 +235,11 @@ int bt_enable(bt_ready_cb_t cb); * stored with @kconfig{CONFIG_BT_SETTINGS}. These can be restored * with settings_load() before reenabling the stack. * + * This API does _not_ clear previously registered callbacks + * like @ref bt_le_scan_cb_register and @ref bt_conn_cb_register. + * That is, the application shall not re-register them when + * the Bluetooth subsystem is re-enabled later. + * * Close and release HCI resources. Result is architecture dependent. * * @return Zero on success or (negative) error code otherwise. @@ -1817,8 +1822,11 @@ int bt_le_per_adv_sync_delete(struct bt_le_per_adv_sync *per_adv_sync); * such as synced, terminated and when data is received. * * @param cb Callback struct. Must point to memory that remains valid. + * + * @retval 0 Success. + * @retval -EEXIST if @p cb was already registered. */ -void bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb); +int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb); /** * @brief Enables receiving periodic advertising reports for a sync. @@ -2304,8 +2312,11 @@ int bt_le_scan_stop(void); * API was used to start the scanner. * * @param cb Callback struct. Must point to memory that remains valid. + * + * @retval 0 Success. + * @retval -EEXIST if @p cb was already registered. */ -void bt_le_scan_cb_register(struct bt_le_scan_cb *cb); +int bt_le_scan_cb_register(struct bt_le_scan_cb *cb); /** * @brief Unregister scanner packet callbacks. diff --git a/include/zephyr/bluetooth/classic/rfcomm.h b/include/zephyr/bluetooth/classic/rfcomm.h index 3b4f7f44ddbfd7..1d3056643bd0b6 100644 --- a/include/zephyr/bluetooth/classic/rfcomm.h +++ b/include/zephyr/bluetooth/classic/rfcomm.h @@ -66,10 +66,9 @@ struct bt_rfcomm_dlc_ops { /** DLC sent callback * * @param dlc The dlc which has sent data. - * @param buf Buffer containing data has been sent. * @param err Sent result. */ - void (*sent)(struct bt_rfcomm_dlc *dlc, struct net_buf *buf, int err); + void (*sent)(struct bt_rfcomm_dlc *dlc, int err); }; /** @brief Role of RFCOMM session and dlc. Used only by internal APIs diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index ca8a7bb3fb941d..32c9aa9f11e4f7 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -515,6 +515,57 @@ struct bt_conn_le_tx_power_report { int8_t delta; }; +/** @brief Path Loss zone that has been entered. + * + * The path loss zone that has been entered in the most recent LE Path Loss Monitoring + * Threshold Change event as documented in Core Spec. Version 5.4 Vol.4, Part E, 7.7.65.32. + * + * @note BT_CONN_LE_PATH_LOSS_ZONE_UNAVAILABLE has been added to notify when path loss becomes + * unavailable. + */ +enum bt_conn_le_path_loss_zone { + /** Low path loss zone entered. */ + BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_LOW, + /** Middle path loss zone entered. */ + BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_MIDDLE, + /** High path loss zone entered. */ + BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_HIGH, + /** Path loss has become unavailable. */ + BT_CONN_LE_PATH_LOSS_ZONE_UNAVAILABLE, +}; + +BUILD_ASSERT(BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_LOW == BT_HCI_LE_ZONE_ENTERED_LOW); +BUILD_ASSERT(BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_MIDDLE == BT_HCI_LE_ZONE_ENTERED_MIDDLE); +BUILD_ASSERT(BT_CONN_LE_PATH_LOSS_ZONE_ENTERED_HIGH == BT_HCI_LE_ZONE_ENTERED_HIGH); + +/** @brief LE Path Loss Monitoring Threshold Change Report Structure. */ +struct bt_conn_le_path_loss_threshold_report { + + /** Path Loss zone as documented in Core Spec. Version 5.4 Vol.4, Part E, 7.7.65.32. */ + enum bt_conn_le_path_loss_zone zone; + + /** Current path loss (dB). */ + uint8_t path_loss; +}; + +/** @brief LE Path Loss Monitoring Parameters Structure as defined in Core Spec. Version 5.4 + * Vol.4, Part E, 7.8.119 LE Set Path Loss Reporting Parameters command. + */ +struct bt_conn_le_path_loss_reporting_param { + /** High threshold for the path loss (dB). */ + uint8_t high_threshold; + /** Hysteresis value for the high threshold (dB). */ + uint8_t high_hysteresis; + /** Low threshold for the path loss (dB). */ + uint8_t low_threshold; + /** Hysteresis value for the low threshold (dB). */ + uint8_t low_hysteresis; + /** Minimum time in number of connection events to be observed once the + * path loss crosses the threshold before an event is generated. + */ + uint16_t min_time_spent; +}; + /** @brief Passkey Keypress Notification type * * The numeric values are the same as in the Core specification for Pairing @@ -601,6 +652,34 @@ int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, bool local_enable, bool remote_enable); +/** @brief Set Path Loss Monitoring Parameters. + * + * Change the configuration for path loss threshold change events for a given conn handle. + * + * @note To use this API @kconfig{CONFIG_BT_PATH_LOSS_MONITORING} must be set. + * + * @param conn Connection object. + * @param param Path Loss Monitoring parameters + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_set_path_loss_mon_param(struct bt_conn *conn, + const struct bt_conn_le_path_loss_reporting_param *param); + +/** @brief Enable or Disable Path Loss Monitoring. + * + * Enable or disable Path Loss Monitoring, which will decide whether Path Loss Threshold events + * are sent from the controller to the host. + * + * @note To use this API @kconfig{CONFIG_BT_PATH_LOSS_MONITORING} must be set. + * + * @param conn Connection Object. + * @param enable Enable/disable path loss reporting. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_set_path_loss_mon_enable(struct bt_conn *conn, bool enable); + /** @brief Update the connection parameters. * * If the local device is in the peripheral role then updating the connection @@ -768,7 +847,8 @@ struct bt_conn_le_create_param { * This uses the General Connection Establishment procedure. * * The application must disable explicit scanning before initiating - * a new LE connection. + * a new LE connection if @kconfig{CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL} + * is not enabled. * * @param[in] peer Remote address. * @param[in] create_param Create connection parameters. @@ -1154,7 +1234,22 @@ struct bt_conn_cb { const struct bt_conn_le_tx_power_report *report); #endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ - struct bt_conn_cb *_next; +#if defined(CONFIG_BT_PATH_LOSS_MONITORING) + /** @brief LE Path Loss Threshold event. + * + * This callback notifies the application that there has been a path loss threshold + * crossing or reporting the initial path loss threshold zone after using + * @ref bt_conn_le_set_path_loss_mon_enable. + * + * @param conn Connection object. + * @param report Path loss threshold report. + */ + void (*path_loss_threshold_report)(struct bt_conn *conn, + const struct bt_conn_le_path_loss_threshold_report *report); +#endif /* CONFIG_BT_PATH_LOSS_MONITORING */ + + /** @internal Internally used field for list handling */ + sys_snode_t _node; }; /** @brief Register connection callbacks. @@ -1162,8 +1257,11 @@ struct bt_conn_cb { * Register callbacks to monitor the state of connections. * * @param cb Callback struct. Must point to memory that remains valid. + * + * @retval 0 Success. + * @retval -EEXIST if @p cb was already registered. */ -void bt_conn_cb_register(struct bt_conn_cb *cb); +int bt_conn_cb_register(struct bt_conn_cb *cb); /** * @brief Unregister connection callbacks. diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 5f50a4c802d668..e1c42be9fcd1c7 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -169,6 +169,7 @@ typedef ssize_t (*bt_gatt_attr_write_func_t)(struct bt_conn *conn, struct bt_gatt_attr { /** Attribute UUID */ const struct bt_uuid *uuid; + /** Attribute read callback */ bt_gatt_attr_read_func_t read; /** Attribute write callback */ bt_gatt_attr_write_func_t write; diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 258f86519b61a9..c0ea108023c340 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -97,6 +97,15 @@ int bt_hci_get_conn_handle(const struct bt_conn *conn, uint16_t *conn_handle); */ int bt_hci_get_adv_handle(const struct bt_le_ext_adv *adv, uint8_t *adv_handle); +/** @brief Get periodic advertising sync handle. + * + * @param sync Periodic advertising sync set. + * @param sync_handle Place to store the periodic advertising sync handle. + * + * @return 0 on success or negative error value on failure. + */ +int bt_hci_get_adv_sync_handle(const struct bt_le_per_adv_sync *sync, uint16_t *sync_handle); + /** @brief Obtain the version string given a core version number. * * The core version of a controller can be obtained by issuing diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 2e91eda5c13c86..1aa5aa915a3e8a 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -276,8 +276,17 @@ struct bt_hci_cmd_hdr { #define BT_FEAT_LE_ISO(feat) (BT_FEAT_LE_CIS(feat) | \ BT_FEAT_LE_BIS(feat)) -/* LE States */ -#define BT_LE_STATES_PER_CONN_ADV(states) (states & 0x0000004000000000) +/* LE States. See Core_v5.4, Vol 4, Part E, Section 7.8.27 */ +#define BT_LE_STATES_PER_CONN_ADV(states) (states & BIT64_MASK(38)) + +#if defined(CONFIG_BT_SCAN_AND_INITIATE_IN_PARALLEL) +/* Both passive and active scanner can be run in parallel with initiator. */ +#define BT_LE_STATES_SCAN_INIT(states) ((states) & BIT64_MASK(22) && \ + (states) & BIT64_MASK(23)) + +#else +#define BT_LE_STATES_SCAN_INIT(states) 0 +#endif /* Bonding/authentication types */ #define BT_HCI_NO_BONDING 0x00 @@ -675,6 +684,26 @@ struct bt_hci_cp_le_set_tx_power_report_enable { uint8_t remote_enable; } __packed; +struct bt_hci_cp_le_set_path_loss_reporting_parameters { + uint16_t handle; + uint8_t high_threshold; + uint8_t high_hysteresis; + uint8_t low_threshold; + uint8_t low_hysteresis; + uint16_t min_time_spent; +} __packed; + +struct bt_hci_cp_le_set_path_loss_reporting_enable { + uint16_t handle; + uint8_t enable; +} __packed; + +#define BT_HCI_OP_LE_SET_PATH_LOSS_REPORTING_PARAMETERS BT_OP(BT_OGF_LE, 0x0078) /* 0x2078 */ + +#define BT_HCI_LE_PATH_LOSS_REPORTING_DISABLE 0x00 +#define BT_HCI_LE_PATH_LOSS_REPORTING_ENABLE 0x01 +#define BT_HCI_OP_LE_SET_PATH_LOSS_REPORTING_ENABLE BT_OP(BT_OGF_LE, 0x0079) /* 0x2079 */ + #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) /* 0x0c31 */ @@ -3020,6 +3049,18 @@ struct bt_hci_evt_le_req_peer_sca_complete { uint8_t sca; } __packed; +#define BT_HCI_LE_ZONE_ENTERED_LOW 0x0 +#define BT_HCI_LE_ZONE_ENTERED_MIDDLE 0x1 +#define BT_HCI_LE_ZONE_ENTERED_HIGH 0x2 +#define BT_HCI_LE_PATH_LOSS_UNAVAILABLE 0xFF + +#define BT_HCI_EVT_LE_PATH_LOSS_THRESHOLD 0x20 +struct bt_hci_evt_le_path_loss_threshold { + uint16_t handle; + uint8_t current_path_loss; + uint8_t zone_entered; +} __packed; + /** Reason for Transmit power reporting. */ /* Local Transmit power changed. */ diff --git a/include/zephyr/bluetooth/hci_vs.h b/include/zephyr/bluetooth/hci_vs.h index 3561e20e9aa585..dabbe2902eaf9c 100644 --- a/include/zephyr/bluetooth/hci_vs.h +++ b/include/zephyr/bluetooth/hci_vs.h @@ -451,7 +451,7 @@ struct bt_hci_evt_mesh_scanning_report { struct bt_hci_evt_mesh_scan_report reports[0]; } __packed; -struct net_buf *hci_vs_err_stack_frame(unsigned int reason, const z_arch_esf_t *esf); +struct net_buf *hci_vs_err_stack_frame(unsigned int reason, const struct arch_esf *esf); struct net_buf *hci_vs_err_trace(const char *file, uint32_t line, uint64_t pc); struct net_buf *hci_vs_err_assert(const char *file, uint32_t line); diff --git a/include/zephyr/bluetooth/l2cap.h b/include/zephyr/bluetooth/l2cap.h index 4ba0610b77dd75..f471c9253794b1 100644 --- a/include/zephyr/bluetooth/l2cap.h +++ b/include/zephyr/bluetooth/l2cap.h @@ -190,13 +190,9 @@ struct bt_l2cap_le_chan { * L2CAP_LE_CREDIT_BASED_CONNECTION_REQ/RSP or L2CAP_CONFIGURATION_REQ. */ struct bt_l2cap_le_endpoint tx; -#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL) - /** Channel Transmission queue */ + /** Channel Transmission queue (for SDUs) */ struct k_fifo tx_queue; - /** Channel Pending Transmission buffer */ - struct net_buf *tx_buf; - /** Channel Transmission work */ - struct k_work_delayable tx_work; +#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL) /** Segment SDU packet from upper layer */ struct net_buf *_sdu; uint16_t _sdu_len; @@ -218,6 +214,13 @@ struct bt_l2cap_le_chan { struct k_work_delayable rtx_work; struct k_work_sync rtx_sync; #endif + + /** @internal To be used with @ref bt_conn.upper_data_ready */ + sys_snode_t _pdu_ready; + /** @internal To be used with @ref bt_conn.upper_data_ready */ + atomic_t _pdu_ready_lock; + /** @internal Holds the length of the current PDU/segment */ + size_t _pdu_remaining; }; /** @@ -260,6 +263,13 @@ struct bt_l2cap_br_chan { /* Response Timeout eXpired (RTX) timer */ struct k_work_delayable rtx_work; struct k_work_sync rtx_sync; + + /** @internal To be used with @ref bt_conn.upper_data_ready */ + sys_snode_t _pdu_ready; + /** @internal To be used with @ref bt_conn.upper_data_ready */ + atomic_t _pdu_ready_lock; + /** @internal Queue of net bufs not yet sent to lower layer */ + struct k_fifo _pdu_tx_queue; }; /** @brief L2CAP Channel operations structure. */ @@ -597,6 +607,7 @@ int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan); * @return -EINVAL if `buf` or `chan` is NULL. * @return -EINVAL if `chan` is not either BR/EDR or LE credit-based. * @return -EINVAL if buffer doesn't have enough bytes reserved to fit header. + * @return -EINVAL if buffer's reference counter != 1 * @return -EMSGSIZE if `buf` is larger than `chan`'s MTU. * @return -ENOTCONN if underlying conn is disconnected. * @return -ESHUTDOWN if L2CAP channel is disconnected. diff --git a/include/zephyr/bluetooth/testing.h b/include/zephyr/bluetooth/testing.h index 58aae9726ffa1a..74806a53a6df1f 100644 --- a/include/zephyr/bluetooth/testing.h +++ b/include/zephyr/bluetooth/testing.h @@ -53,8 +53,11 @@ struct bt_test_cb { /** Register callbacks for Bluetooth testing purposes * * @param cb bt_test_cb callback structure + * + * @retval 0 Success. + * @retval -EEXIST if @p cb was already registered. */ -void bt_test_cb_register(struct bt_test_cb *cb); +int bt_test_cb_register(struct bt_test_cb *cb); /** Unregister callbacks for Bluetooth testing purposes * diff --git a/include/zephyr/data/json.h b/include/zephyr/data/json.h index 7534b3674f69dd..07393109009a34 100644 --- a/include/zephyr/data/json.h +++ b/include/zephyr/data/json.h @@ -45,6 +45,7 @@ enum json_tokens { JSON_TOK_FLOAT = '1', JSON_TOK_OPAQUE = '2', JSON_TOK_OBJ_ARRAY = '3', + JSON_TOK_ENCODED_OBJ = '4', JSON_TOK_TRUE = 't', JSON_TOK_FALSE = 'f', JSON_TOK_NULL = 'n', diff --git a/include/zephyr/debug/coredump.h b/include/zephyr/debug/coredump.h index 9d4f37a4f870f9..f61f4e94a38b72 100644 --- a/include/zephyr/debug/coredump.h +++ b/include/zephyr/debug/coredump.h @@ -232,7 +232,7 @@ struct coredump_backend_api { coredump_backend_cmd_t cmd; }; -void coredump(unsigned int reason, const z_arch_esf_t *esf, +void coredump(unsigned int reason, const struct arch_esf *esf, struct k_thread *thread); void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr); void coredump_buffer_output(uint8_t *buf, size_t buflen); @@ -242,7 +242,7 @@ int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg); #else -static inline void coredump(unsigned int reason, const z_arch_esf_t *esf, +static inline void coredump(unsigned int reason, const struct arch_esf *esf, struct k_thread *thread) { ARG_UNUSED(reason); @@ -279,7 +279,7 @@ static inline int coredump_cmd(enum coredump_cmd_id query_id, void *arg) #endif /* CONFIG_DEBUG_COREDUMP */ /** - * @fn void coredump(unsigned int reason, const z_arch_esf_t *esf, struct k_thread *thread); + * @fn void coredump(unsigned int reason, const struct arch_esf *esf, struct k_thread *thread); * @brief Perform coredump. * * Normally, this is called inside z_fatal_error() to generate coredump diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 5d891c1e9ef5ed..4f8c9a260a7d85 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ extern "C" { * @brief Device Model * @defgroup device_model Device Model * @since 1.0 - * @version 1.0.0 + * @version 1.1.0 * @{ */ @@ -386,6 +387,9 @@ struct device_state { struct pm_device_base; struct pm_device; struct pm_device_isr; +#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__) +struct device_dt_metadata; +#endif #ifdef CONFIG_DEVICE_DEPS_DYNAMIC #define Z_DEVICE_DEPS_CONST @@ -418,6 +422,10 @@ struct device { */ Z_DEVICE_DEPS_CONST device_handle_t *deps; #endif /* CONFIG_DEVICE_DEPS */ +#if defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) || defined(__DOXYGEN__) + struct pm_state_constraint const *pm_constraints; + size_t pm_constraints_size; +#endif /* CONFIG_PM */ #if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__) /** * Reference to the device PM resources (only available if @@ -429,6 +437,9 @@ struct device { struct pm_device_isr *pm_isr; }; #endif +#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__) + const struct device_dt_metadata *dt_meta; +#endif /* CONFIG_DEVICE_DT_METADATA */ }; /** @@ -866,6 +877,156 @@ __syscall int device_init(const struct device *dev); #endif /* CONFIG_DEVICE_DEPS */ +#if defined(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS) || defined(__DOXYGEN__) + +/** + * @brief Synthesize the name of the object that holds a device pm constraint. + * + * @param dev_id Device identifier. + */ +#define Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id) _CONCAT(__devicepmconstraints_, dev_id) + +/** + * @brief initialize a device pm constraint with information from devicetree. + * + * @param node_id Node identifier. + */ +#define Z_PM_STATE_CONSTRAINT_DT_INIT(node_id) \ + { \ + .state = PM_STATE_DT_INIT(node_id), \ + .substate_id = DT_PROP_OR(node_id, substate_id, 0), \ + } + +#define Z_PM_STATE_FROM_DT_DEVICE(i, node_id) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, \ + zephyr_disabling_power_states, i), okay), \ + (Z_PM_STATE_CONSTRAINT_DT_INIT(DT_PHANDLE_BY_IDX(node_id, \ + zephyr_disabling_power_states, i)),), ()) + +/** + * @brief Helper macro to generate a list of device pm constraints. + */ +#define Z_PM_STATE_CONSTRAINTS_FROM_DT_DEVICE(node_id) \ + { \ + LISTIFY(DT_PROP_LEN_OR(node_id, zephyr_disabling_power_states, 0), \ + Z_PM_STATE_FROM_DT_DEVICE, (), node_id) \ + } + +/** + * @brief Define device pm constraints. + * + * Defines a list of `pm_state_constraint` for a specific device from its + * devicetree definition. + * + * This information tell us which power states would cause power loss + * and intended to be used by a device to set power state constraints when + * it is in the middle of an operation. + */ +#define Z_DEVICE_PM_CONSTRAINTS_DEFINE(node_id, dev_id, ...) \ + Z_DECL_ALIGN(struct pm_state_constraint) \ + Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id)[] = \ + Z_PM_STATE_CONSTRAINTS_FROM_DT_DEVICE(node_id); + +#endif /* CONFIG_PM_POLICY_DEVICE_CONSTRAINTS */ + +#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__) +/** + * @brief Devicetree node labels associated with a device + */ +struct device_dt_nodelabels { + /* @brief number of elements in the nodelabels array */ + size_t num_nodelabels; + /* @brief array of node labels as strings, exactly as they + * appear in the final devicetree + */ + const char *nodelabels[]; +}; + +/** + * @brief Devicetree metadata associated with a device + * + * This is currently limited to node labels, but the structure is + * generic enough to be extended later without requiring breaking + * changes. + */ +struct device_dt_metadata { + /** + * @brief Node labels associated with the device + * @see device_get_dt_nodelabels() + */ + const struct device_dt_nodelabels *nl; +}; + +/** + * @brief Get a @ref device reference from a devicetree node label. + * + * If: + * + * 1. a device was defined from a devicetree node, for example + * with DEVICE_DT_DEFINE() or another similar macro, and + * 2. that devicetree node has @p nodelabel as one of its node labels, and + * 3. the device initialized successfully at boot time, + * + * then this function returns a pointer to the device. Otherwise, it + * returns NULL. + * + * @param nodelabel a devicetree node label + * @return a device reference for a device created from a node with that + * node label, or NULL if either no such device exists or the device + * failed to initialize + */ +__syscall const struct device *device_get_by_dt_nodelabel(const char *nodelabel); + +/** + * @brief Get the devicetree node labels associated with a device + * @param dev device whose metadata to look up + * @return information about the devicetree node labels + */ +static inline const struct device_dt_nodelabels * +device_get_dt_nodelabels(const struct device *dev) +{ + return dev->dt_meta->nl; +} + +/** + * @brief Maximum devicetree node label length. + * + * The maximum length is set so that device_get_by_dt_nodelabel() can + * be used from userspace. + */ +#define Z_DEVICE_MAX_NODELABEL_LEN Z_DEVICE_MAX_NAME_LEN + +/** + * @brief Name of the identifier for a device's DT metadata structure + * @param dev_id device identifier + */ +#define Z_DEVICE_DT_METADATA_NAME_GET(dev_id) UTIL_CAT(__dev_dt_meta_, dev_id) + +/** + * @brief Name of the identifier for the array of node label strings + * saved for a device. + */ +#define Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) UTIL_CAT(__dev_dt_nodelabels_, dev_id) + +/** + * @brief Initialize an entry in the device DT node label lookup table + * + * Allocates and initializes a struct device_dt_metadata in the + * appropriate iterable section for use finding devices. + */ +#define Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id) \ + static const struct device_dt_nodelabels \ + Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) = { \ + .num_nodelabels = DT_NUM_NODELABELS(node_id), \ + .nodelabels = DT_NODELABEL_STRING_ARRAY(node_id), \ + }; \ + \ + static const struct device_dt_metadata \ + Z_DEVICE_DT_METADATA_NAME_GET(dev_id) = { \ + .nl = &Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id), \ + }; +#endif /* CONFIG_DEVICE_DT_METADATA */ + /** * @brief Init sub-priority of the device * @@ -904,16 +1065,24 @@ __syscall int device_init(const struct device *dev); * @param api_ Reference to device API ops. * @param state_ Reference to device state. * @param deps_ Reference to device dependencies. + * @param dev_id_ Device identifier token, as passed to Z_DEVICE_BASE_DEFINE */ -#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_) \ - { \ - .name = name_, \ - .config = (config_), \ - .api = (api_), \ - .state = (state_), \ - .data = (data_), \ - IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ - IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \ +#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, \ + constraints_size_, constraints_, dev_id_) \ + { \ + .name = name_, \ + .config = (config_), \ + .api = (api_), \ + .state = (state_), \ + .data = (data_), \ + IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ + IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ + (.pm_constraints = (constraints_),)) \ + IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ + (.pm_constraints_size = (constraints_size_),)) \ + IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \ + IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ + (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET(dev_id_),)) \ } /** @@ -942,13 +1111,14 @@ __syscall int device_init(const struct device *dev); * @param ... Optional dependencies, manually specified. */ #define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \ - deps) \ + deps, constraints) \ 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) + Z_DEVICE_INIT(name, pm, data, config, api, state, deps, \ + DT_PROP_LEN_OR(node_id, zephyr_disabling_power_states, 0), constraints, dev_id) /* deprecated device initialization levels */ #define Z_DEVICE_LEVEL_DEPRECATED_EARLY \ @@ -1026,20 +1196,26 @@ __syscall int device_init(const struct device *dev); * @param state Reference to device state. * @param ... Optional dependencies, manually specified. */ -#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \ - level, prio, api, state, ...) \ - Z_DEVICE_NAME_CHECK(name); \ - \ - IF_ENABLED(CONFIG_DEVICE_DEPS, \ - (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \ - \ - Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ - prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \ - \ - COND_CODE_1(DEVICE_DT_DEFER(node_id), \ - (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \ - init_fn)), \ - (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \ +#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \ + level, prio, api, state, ...) \ + Z_DEVICE_NAME_CHECK(name); \ + \ + IF_ENABLED(CONFIG_DEVICE_DEPS, \ + (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \ + \ + IF_ENABLED(CONFIG_PM_POLICY_DEVICE_CONSTRAINTS, \ + (Z_DEVICE_PM_CONSTRAINTS_DEFINE(node_id, dev_id, __VA_ARGS__);))\ + \ + IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \ + (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);)) \ + \ + Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ + prio, api, state, Z_DEVICE_DEPS_NAME(dev_id), \ + Z_DEVICE_PM_CONSTRAINTS_NAME(dev_id)); \ + COND_CODE_1(DEVICE_DT_DEFER(node_id), \ + (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \ + init_fn)), \ + (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \ level, prio))); /** diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index c1c90220a1aa87..349e5836fbce57 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -29,7 +29,7 @@ * @brief devicetree.h API * @defgroup devicetree Devicetree * @since 2.2 - * @version 1.0.0 + * @version 1.1.0 * @{ * @} */ @@ -593,6 +593,33 @@ #define DT_SAME_NODE(node_id1, node_id2) \ (DT_DEP_ORD(node_id1) == (DT_DEP_ORD(node_id2))) +/** + * @brief Get a devicetree node's node labels as an array of strings + * + * Example devicetree fragment: + * + * @code{.dts} + * foo: bar: node@deadbeef {}; + * @endcode + * + * Example usage: + * + * @code{.c} + * DT_NODELABEL_STRING_ARRAY(DT_NODELABEL(foo)) + * @endcode + * + * This expands to: + * + * @code{.c} + * { "foo", "bar", } + * @endcode + * + * @param node_id node identifier + * @return an array initializer for an array of the node's node labels as strings + */ +#define DT_NODELABEL_STRING_ARRAY(node_id) \ + { DT_FOREACH_NODELABEL(node_id, DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL) } + /** * @} */ @@ -2202,6 +2229,20 @@ #define DT_REG_HAS_IDX(node_id, idx) \ IS_ENABLED(DT_CAT4(node_id, _REG_IDX_, idx, _EXISTS)) +/** + * @brief Is @p name a valid register block name? + * + * If this returns 1, then DT_REG_ADDR_BY_NAME(node_id, name) or + * DT_REG_SIZE_BY_NAME(node_id, name) are valid. + * If it returns 0, it is an error to use those macros with name @p name. + * @param node_id node identifier + * @param name name to check + * @return 1 if @p name is a valid register block name, + * 0 otherwise. + */ +#define DT_REG_HAS_NAME(node_id, name) \ + IS_ENABLED(DT_CAT4(node_id, _REG_NAME_, name, _EXISTS)) + /** * @brief Get the base address of the register block at index @p idx * @param node_id node identifier @@ -2264,6 +2305,18 @@ #define DT_REG_ADDR_BY_NAME(node_id, name) \ DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS) +/** + * @brief Like DT_REG_ADDR_BY_NAME(), but with a fallback to @p default_value + * @param node_id node identifier + * @param name lowercase-and-underscores register specifier name + * @param default_value a fallback value to expand to + * @return address of the register block specified by name if present, + * @p default_value otherwise + */ +#define DT_REG_ADDR_BY_NAME_OR(node_id, name, default_value) \ + COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \ + (DT_REG_ADDR_BY_NAME(node_id, name)), (default_value)) + /** * @brief 64-bit version of DT_REG_ADDR_BY_NAME() * @@ -2288,6 +2341,19 @@ #define DT_REG_SIZE_BY_NAME(node_id, name) \ DT_CAT4(node_id, _REG_NAME_, name, _VAL_SIZE) +/** + * @brief Like DT_REG_SIZE_BY_NAME(), but with a fallback to @p default_value + * @param node_id node identifier + * @param name lowercase-and-underscores register specifier name + * @param default_value a fallback value to expand to + * @return size of the register block specified by name if present, + * @p default_value otherwise + */ +#define DT_REG_SIZE_BY_NAME_OR(node_id, name, default_value) \ + COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \ + (DT_REG_SIZE_BY_NAME(node_id, name)), (default_value)) + + /** * @} */ @@ -2308,6 +2374,32 @@ */ #define DT_NUM_IRQS(node_id) DT_CAT(node_id, _IRQ_NUM) +/** + * @brief Get the number of node labels that a node has + * + * Example devicetree fragment: + * + * @code{.dts} + * / { + * foo {}; + * bar: bar@1000 {}; + * baz: baz2: baz@2000 {}; + * }; + * @endcode + * + * Example usage: + * + * @code{.c} + * DT_NUM_NODELABELS(DT_PATH(foo)) // 0 + * DT_NUM_NODELABELS(DT_NODELABEL(bar)) // 1 + * DT_NUM_NODELABELS(DT_NODELABEL(baz)) // 2 + * @endcode + * + * @param node_id node identifier + * @return number of node labels that the node has + */ +#define DT_NUM_NODELABELS(node_id) DT_CAT(node_id, _NODELABEL_NUM) + /** * @brief Get the interrupt level for the node * @@ -3162,6 +3254,86 @@ compat)(fn, __VA_ARGS__)), \ ()) +/** + * @brief Invokes @p fn for each node label of a given node + * + * The order of the node labels in this macro's expansion matches + * the order in the final devicetree, with duplicates removed. + * + * Node labels are passed to @p fn as tokens. Note that devicetree + * node labels are always valid C tokens (see "6.2 Labels" in + * Devicetree Specification v0.4 for details). The node labels are + * passed as tokens to @p fn as-is, without any lowercasing or + * conversion of special characters to underscores. + * + * Example devicetree fragment: + * + * @code{.dts} + * foo: bar: FOO: node@deadbeef {}; + * @endcode + * + * Example usage: + * + * @code{.c} + * int foo = 1; + * int bar = 2; + * int FOO = 3; + * + * #define FN(nodelabel) + nodelabel + * int sum = 0 DT_FOREACH_NODELABEL(DT_NODELABEL(foo), FN) + * @endcode + * + * This expands to: + * + * @code{.c} + * int sum = 0 + 1 + 2 + 3; + * @endcode + * + * @param node_id node identifier whose node labels to use + * @param fn macro which will be passed each node label in order + */ +#define DT_FOREACH_NODELABEL(node_id, fn) DT_CAT(node_id, _FOREACH_NODELABEL)(fn) + +/** + * @brief Invokes @p fn for each node label of a given node with + * multiple arguments. + * + * This is like DT_FOREACH_NODELABEL() except you can also pass + * additional arguments to @p fn. + * + * Example devicetree fragment: + * + * @code{.dts} + * foo: bar: node@deadbeef {}; + * @endcode + * + * Example usage: + * + * @code{.c} + * int foo = 0; + * int bar = 1; + * + * #define VAR_PLUS(nodelabel, to_add) int nodelabel ## _added = nodelabel + to_add; + * + * DT_FOREACH_NODELABEL_VARGS(DT_NODELABEL(foo), VAR_PLUS, 1) + * @endcode + * + * This expands to: + * + * @code{.c} + * int foo = 0; + * int bar = 1; + * int foo_added = foo + 1; + * int bar_added = bar + 1; + * @endcode + * + * @param node_id node identifier whose node labels to use + * @param fn macro which will be passed each node label in order + * @param ... additional arguments to pass to @p fn + */ +#define DT_FOREACH_NODELABEL_VARGS(node_id, fn, ...) \ + DT_CAT(node_id, _FOREACH_NODELABEL_VARGS)(fn, __VA_ARGS__) + /** * @} */ @@ -3289,7 +3461,7 @@ * @param status okay or disabled as a token, not a string */ #define DT_NODE_HAS_COMPAT_STATUS(node_id, compat, status) \ - DT_NODE_HAS_COMPAT(node_id, compat) && DT_NODE_HAS_STATUS(node_id, status) + UTIL_AND(DT_NODE_HAS_COMPAT(node_id, compat), DT_NODE_HAS_STATUS(node_id, status)) /** * @brief Does a devicetree node have a property? @@ -3484,6 +3656,26 @@ #define DT_INST_CHILD_NUM_STATUS_OKAY(inst) \ DT_CHILD_NUM_STATUS_OKAY(DT_DRV_INST(inst)) +/** + * @brief Get a string array of DT_DRV_INST(inst)'s node labels + * + * Equivalent to DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst)). + * + * @param inst instance number + * @return an array initializer for an array of the instance's node labels as strings + */ +#define DT_INST_NODELABEL_STRING_ARRAY(inst) DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst)) + +/** + * @brief Get the number of node labels by instance number + * + * Equivalent to DT_NUM_NODELABELS(DT_DRV_INST(inst)). + * + * @param inst instance number + * @return the number of node labels that the node with that instance number has + */ +#define DT_INST_NUM_NODELABELS(inst) DT_NUM_NODELABELS(DT_DRV_INST(inst)) + /** * @brief Call @p fn on all child nodes of DT_DRV_INST(inst). * @@ -3915,6 +4107,15 @@ */ #define DT_INST_REG_HAS_IDX(inst, idx) DT_REG_HAS_IDX(DT_DRV_INST(inst), idx) +/** + * @brief is @p name a valid register block name on a `DT_DRV_COMPAT` instance? + * @param inst instance number + * @param name name to check + * @return 1 if @p name is a valid register block name, + * 0 otherwise. + */ +#define DT_INST_REG_HAS_NAME(inst, name) DT_REG_HAS_NAME(DT_DRV_INST(inst), name) + /** * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's address * @param inst instance number @@ -3941,6 +4142,17 @@ #define DT_INST_REG_ADDR_BY_NAME(inst, name) \ DT_REG_ADDR_BY_NAME(DT_DRV_INST(inst), name) +/** + * @brief Like DT_INST_REG_ADDR_BY_NAME(), but with a fallback to @p default_value + * @param inst instance number + * @param name lowercase-and-underscores register specifier name + * @param default_value a fallback value to expand to + * @return address of the register block specified by name if present, + * @p default_value otherwise + */ +#define DT_INST_REG_ADDR_BY_NAME_OR(inst, name, default_value) \ + DT_REG_ADDR_BY_NAME_OR(DT_DRV_INST(inst), name, default_value) + /** * @brief 64-bit version of DT_INST_REG_ADDR_BY_NAME() * @@ -3965,6 +4177,17 @@ #define DT_INST_REG_SIZE_BY_NAME(inst, name) \ DT_REG_SIZE_BY_NAME(DT_DRV_INST(inst), name) +/** + * @brief Like DT_INST_REG_SIZE_BY_NAME(), but with a fallback to @p default_value + * @param inst instance number + * @param name lowercase-and-underscores register specifier name + * @param default_value a fallback value to expand to + * @return size of the register block specified by name if present, + * @p default_value otherwise + */ +#define DT_INST_REG_SIZE_BY_NAME_OR(inst, name, default_value) \ + DT_REG_SIZE_BY_NAME_OR(DT_DRV_INST(inst), name, default_value) + /** * @brief Get a `DT_DRV_COMPAT`'s (only) register block address * @param inst instance number @@ -4324,6 +4547,32 @@ DT_DRV_COMPAT)(fn, __VA_ARGS__)), \ ()) +/** + * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance + * + * Equivalent to DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn). + * + * @param inst instance number + * @param fn macro which will be passed each node label for the node + * with that instance number + */ +#define DT_INST_FOREACH_NODELABEL(inst, fn) \ + DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn) + +/** + * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance + * with multiple arguments + * + * Equivalent to DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, ...). + * + * @param inst instance number + * @param fn macro which will be passed each node label for the node + * with that instance number + * @param ... additional arguments to pass to @p fn + */ +#define DT_INST_FOREACH_NODELABEL_VARGS(inst, fn, ...) \ + DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__) + /** * @brief Invokes @p fn for each element of property @p prop for * a `DT_DRV_COMPAT` instance. @@ -4557,10 +4806,6 @@ #define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \ IS_ENABLED(DT_CAT3(node_id, _STATUS_, status)) -/** @brief Helper macro to OR multiple has property checks in a loop macro */ -#define DT_INST_NODE_HAS_PROP_AND_OR(inst, prop) \ - DT_INST_NODE_HAS_PROP(inst, prop) || - /** * @def DT_U64_C * @brief Macro to add ULL postfix to the devicetree address constants @@ -4571,6 +4816,13 @@ #define DT_U64_C(_v) UINT64_C(_v) #endif +/* Helpers for DT_NODELABEL_STRING_ARRAY. We define our own stringify + * in order to avoid adding a dependency on toolchain.h.. + */ +#define DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL(nodelabel) DT_STRINGIFY_INTERNAL(nodelabel), +#define DT_STRINGIFY_INTERNAL(arg) DT_STRINGIFY_INTERNAL_HELPER(arg) +#define DT_STRINGIFY_INTERNAL_HELPER(arg) #arg + /** @endcond */ /* have these last so they have access to all previously defined macros */ diff --git a/include/zephyr/drivers/bluetooth.h b/include/zephyr/drivers/bluetooth.h new file mode 100644 index 00000000000000..f447c76b792534 --- /dev/null +++ b/include/zephyr/drivers/bluetooth.h @@ -0,0 +1,257 @@ +/** @file + * @brief Bluetooth HCI driver API. + * + * Copyright (c) 2024 Johan Hedberg + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_ +#define ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_ + +/** + * @brief Bluetooth HCI APIs + * @defgroup bt_hci_api Bluetooth HCI APIs + * @ingroup bluetooth + * @{ + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_hci_setup_params { + /** The public identity address to give to the controller. This field is used when the + * driver selects @kconfig{CONFIG_BT_HCI_SET_PUBLIC_ADDR} to indicate that it supports + * setting the controller's public address. + */ + bt_addr_t public_addr; +}; + +enum { + /* The host should never send HCI_Reset */ + BT_HCI_QUIRK_NO_RESET = BIT(0), + /* The controller does not auto-initiate a DLE procedure when the + * initial connection data length parameters are not equal to the + * default data length parameters. Therefore the host should initiate + * the DLE procedure after connection establishment. + */ + BT_HCI_QUIRK_NO_AUTO_DLE = BIT(1), +}; + +/** Possible values for the 'bus' member of the bt_hci_driver struct */ +enum bt_hci_bus { + BT_HCI_BUS_VIRTUAL = 0, + BT_HCI_BUS_USB = 1, + BT_HCI_BUS_PCCARD = 2, + BT_HCI_BUS_UART = 3, + BT_HCI_BUS_RS232 = 4, + BT_HCI_BUS_PCI = 5, + BT_HCI_BUS_SDIO = 6, + BT_HCI_BUS_SPI = 7, + BT_HCI_BUS_I2C = 8, + BT_HCI_BUS_IPM = 9, +}; + +#define BT_DT_HCI_QUIRK_OR(node_id, prop, idx) DT_STRING_TOKEN_BY_IDX(node_id, prop, idx) +#define BT_DT_HCI_QUIRKS_GET(node_id) COND_CODE_1(DT_NODE_HAS_PROP(node_id, bt_hci_quirks), \ + (DT_FOREACH_PROP_ELEM_SEP(node_id, \ + bt_hci_quirks, \ + BT_DT_HCI_QUIRK_OR, \ + (|))), \ + (0)) +#define BT_DT_HCI_QUIRKS_INST_GET(inst) BT_DT_HCI_QUIRKS_GET(DT_DRV_INST(inst)) + +#define BT_DT_HCI_NAME_GET(node_id) DT_PROP_OR(node_id, bt_hci_name, "HCI") +#define BT_DT_HCI_NAME_INST_GET(inst) BT_DT_HCI_NAME_GET(DT_DRV_INST(inst)) + +#define BT_DT_HCI_BUS_GET(node_id) DT_STRING_TOKEN_OR(node_id, bt_hci_bus, BT_HCI_BUS_VIRTUAL) +#define BT_DT_HCI_BUS_INST_GET(inst) BT_DT_HCI_BUS_GET(DT_DRV_INST(inst)) + +typedef int (*bt_hci_recv_t)(const struct device *dev, struct net_buf *buf); + +__subsystem struct bt_hci_driver_api { + int (*open)(const struct device *dev, bt_hci_recv_t recv); + int (*close)(const struct device *dev); + int (*send)(const struct device *dev, struct net_buf *buf); +#if defined(CONFIG_BT_HCI_SETUP) + int (*setup)(const struct device *dev, + const struct bt_hci_setup_params *param); +#endif /* defined(CONFIG_BT_HCI_SETUP) */ +}; + +/** + * @brief Open the HCI transport. + * + * Opens the HCI transport for operation. This function must not + * return until the transport is ready for operation, meaning it + * is safe to start calling the send() handler. + * + * @param dev HCI device + * @param recv This is callback through which the HCI driver provides the + * host with data from the controller. The buffer passed to + * the callback will have its type set with bt_buf_set_type(). + * The callback is expected to be called from thread context. + * + * @return 0 on success or negative POSIX error number on failure. + */ +static inline int bt_hci_open(const struct device *dev, bt_hci_recv_t recv) +{ + const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api; + + return api->open(dev, recv); +} + +/** + * @brief Close the HCI transport. + * + * Closes the HCI transport. This function must not return until the + * transport is closed. + * + * @param dev HCI device + * + * @return 0 on success or negative POSIX error number on failure. + */ +static inline int bt_hci_close(const struct device *dev) +{ + const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api; + + if (api->close == NULL) { + return -ENOSYS; + } + + return api->close(dev); +} + +/** + * @brief Send HCI buffer to controller. + * + * Send an HCI packet to the controller. The packet type of the buffer + * must be set using bt_buf_set_type(). + * + * @note This function must only be called from a cooperative thread. + * + * @param dev HCI device + * @param buf Buffer containing data to be sent to the controller. + * + * @return 0 on success or negative POSIX error number on failure. + */ +static inline int bt_hci_send(const struct device *dev, struct net_buf *buf) +{ + const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api; + + return api->send(dev, buf); +} + +#if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__) +/** + * @brief HCI vendor-specific setup + * + * Executes vendor-specific commands sequence to initialize + * BT Controller before BT Host executes Reset sequence. This is normally + * called directly after bt_hci_open(). + * + * @note @kconfig{CONFIG_BT_HCI_SETUP} must be selected for this + * field to be available. + * + * @return 0 on success or negative POSIX error number on failure. + */ +static inline int bt_hci_setup(const struct device *dev, struct bt_hci_setup_params *params) +{ + const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api; + + if (api->setup == NULL) { + return -ENOSYS; + } + + return api->setup(dev, params); +} +#endif + +/** + * @} + */ + +/* The following functions are not strictly part of the HCI driver API, in that + * they do not take as input a struct device which implements the HCI driver API. + */ + +/** + * @brief Setup the HCI transport, which usually means to reset the + * Bluetooth IC. + * + * @note A weak version of this function is included in the H4 driver, so + * defining it is optional per board. + * + * @param dev The device structure for the bus connecting to the IC + * + * @return 0 on success, negative error value on failure + */ +int bt_hci_transport_setup(const struct device *dev); + +/** + * @brief Teardown the HCI transport. + * + * @note A weak version of this function is included in the IPC driver, so + * defining it is optional. NRF5340 includes support to put network core + * in reset state. + * + * @param dev The device structure for the bus connecting to the IC + * + * @return 0 on success, negative error value on faulure + */ +int bt_hci_transport_teardown(const struct device *dev); + +/** Allocate an HCI event buffer. + * + * This function allocates a new buffer for an HCI event. It is given the + * event code and the total length of the parameters. Upon successful return + * the buffer is ready to have the parameters encoded into it. + * + * @param evt HCI event OpCode. + * @param len Length of event parameters. + * + * @return Newly allocated buffer. + */ +struct net_buf *bt_hci_evt_create(uint8_t evt, uint8_t len); + +/** Allocate an HCI Command Complete event buffer. + * + * This function allocates a new buffer for HCI Command Complete event. + * It is given the OpCode (encoded e.g. using the BT_OP macro) and the total + * length of the parameters. Upon successful return the buffer is ready to have + * the parameters encoded into it. + * + * @param op HCI command OpCode. + * @param plen Length of command parameters. + * + * @return Newly allocated buffer. + */ +struct net_buf *bt_hci_cmd_complete_create(uint16_t op, uint8_t plen); + +/** Allocate an HCI Command Status event buffer. + * + * This function allocates a new buffer for HCI Command Status event. + * It is given the OpCode (encoded e.g. using the BT_OP macro) and the status + * code. Upon successful return the buffer is ready to have the parameters + * encoded into it. + * + * @param op HCI command OpCode. + * @param status Status code. + * + * @return Newly allocated buffer. + */ +struct net_buf *bt_hci_cmd_status_create(uint16_t op, uint8_t status); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_ */ diff --git a/include/zephyr/drivers/bluetooth/hci_driver.h b/include/zephyr/drivers/bluetooth/hci_driver.h index 08aacc853f36cd..6f76889876e374 100644 --- a/include/zephyr/drivers/bluetooth/hci_driver.h +++ b/include/zephyr/drivers/bluetooth/hci_driver.h @@ -37,8 +37,6 @@ enum { BT_QUIRK_NO_AUTO_DLE = BIT(1), }; -#define IS_BT_QUIRK_NO_AUTO_DLE(bt_dev) ((bt_dev)->drv->quirks & BT_QUIRK_NO_AUTO_DLE) - /** * @brief Receive data from the controller/HCI driver. * @@ -49,8 +47,10 @@ enum { * @param buf Network buffer containing data from the controller. * * @return 0 on success or negative error number on failure. + * + * @deprecated Use the new HCI driver interface instead: @ref bt_hci_api */ -int bt_recv(struct net_buf *buf); +__deprecated int bt_recv(struct net_buf *buf); /** Possible values for the 'bus' member of the bt_hci_driver struct */ enum bt_hci_driver_bus { @@ -156,8 +156,10 @@ struct bt_hci_driver { * @param drv A bt_hci_driver struct representing the driver. * * @return 0 on success or negative error number on failure. + * + * @deprecated Use the new HCI driver interface instead: @ref bt_hci_api */ -int bt_hci_driver_register(const struct bt_hci_driver *drv); +__deprecated int bt_hci_driver_register(const struct bt_hci_driver *drv); /** * @brief Setup the HCI transport, which usually means to reset the diff --git a/include/zephyr/drivers/bluetooth/hci_driver_bluenrg.h b/include/zephyr/drivers/bluetooth/hci_driver_bluenrg.h new file mode 100644 index 00000000000000..d65b93c586a758 --- /dev/null +++ b/include/zephyr/drivers/bluetooth/hci_driver_bluenrg.h @@ -0,0 +1,47 @@ +/** @file + * @brief BlueNRG HCI extended API. + */ + +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_HCI_DRIVER_BLUENRG_H_ +#define ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_HCI_DRIVER_BLUENRG_H_ + +/** + * @brief BlueNRG HCI Driver-Specific API + * @defgroup bluenrg_hci_driver BlueNRG HCI driver extended API + * @ingroup bluetooth + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Hardware reset the BlueNRG network coprocessor. + * + * Performs hardware reset of the BLE network coprocessor. + * It can also force to enter firmware updater mode. + * + * @param updater_mode flag to indicate whether updater mode needs to be entered. + * + * @return a non-negative value indicating success, or a + * negative error code for failure + */ + +int bluenrg_bt_reset(bool updater_mode); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_HCI_DRIVER_BLUENRG_H_ */ diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index bf3af29ede29e7..9dee92ddd69fc8 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -351,14 +351,14 @@ struct can_driver_config { /** The maximum bitrate supported by the CAN controller/transceiver combination. */ uint32_t max_bitrate; /** Initial CAN classic/CAN FD arbitration phase bitrate. */ - uint32_t bus_speed; + uint32_t bitrate; /** Initial CAN classic/CAN FD arbitration phase sample point in permille. */ uint16_t sample_point; #ifdef CONFIG_CAN_FD_MODE /** Initial CAN FD data phase sample point in permille. */ uint16_t sample_point_data; /** Initial CAN FD data phase bitrate. */ - uint32_t bus_speed_data; + uint32_t bitrate_data; #endif /* CONFIG_CAN_FD_MODE */ }; @@ -374,11 +374,12 @@ struct can_driver_config { .phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, phys)), \ .min_bitrate = DT_CAN_TRANSCEIVER_MIN_BITRATE(node_id, _min_bitrate), \ .max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, _max_bitrate), \ - .bus_speed = DT_PROP_OR(node_id, bus_speed, CONFIG_CAN_DEFAULT_BITRATE), \ + .bitrate = DT_PROP_OR(node_id, bitrate, \ + DT_PROP_OR(node_id, bus_speed, CONFIG_CAN_DEFAULT_BITRATE)), \ .sample_point = DT_PROP_OR(node_id, sample_point, 0), \ IF_ENABLED(CONFIG_CAN_FD_MODE, \ - (.bus_speed_data = DT_PROP_OR(node_id, bus_speed_data, \ - CONFIG_CAN_DEFAULT_BITRATE_DATA), \ + (.bitrate_data = DT_PROP_OR(node_id, bitrate_data, \ + DT_PROP_OR(node_id, bus_speed_data, CONFIG_CAN_DEFAULT_BITRATE_DATA)), \ .sample_point_data = DT_PROP_OR(node_id, sample_point_data, 0),)) \ } diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 062fae034e3114..a9ce911e5c7f06 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -44,6 +44,8 @@ #include #elif defined(CONFIG_SOC_SERIES_STM32H7X) #include +#elif defined(CONFIG_SOC_SERIES_STM32H7RSX) +#include #elif defined(CONFIG_SOC_SERIES_STM32U5X) #include #elif defined(CONFIG_SOC_SERIES_STM32WBAX) @@ -61,6 +63,7 @@ #define STM32_APB1_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb1_prescaler) #define STM32_APB2_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb2_prescaler) #define STM32_APB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb3_prescaler) +#define STM32_APB5_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb5_prescaler) #define STM32_APB7_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb7_prescaler) #define STM32_AHB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb3_prescaler) #define STM32_AHB4_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb4_prescaler) @@ -86,13 +89,22 @@ #define STM32_ADC12_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc12_prescaler) #define STM32_ADC34_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc34_prescaler) -/** STM2H7 specifics RCC dividers */ +/** STM2H7RS specific RCC dividers */ +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) +#define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), dcpre) +#define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre) +#define STM32_PPRE1 DT_PROP(DT_NODELABEL(rcc), ppre1) +#define STM32_PPRE2 DT_PROP(DT_NODELABEL(rcc), ppre2) +#define STM32_PPRE4 DT_PROP(DT_NODELABEL(rcc), ppre4) +#define STM32_PPRE5 DT_PROP(DT_NODELABEL(rcc), ppre5) +#else #define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), d1cpre) #define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre) #define STM32_D2PPRE1 DT_PROP(DT_NODELABEL(rcc), d2ppre1) #define STM32_D2PPRE2 DT_PROP(DT_NODELABEL(rcc), d2ppre2) #define STM32_D1PPRE DT_PROP(DT_NODELABEL(rcc), d1ppre) #define STM32_D3PPRE DT_PROP(DT_NODELABEL(rcc), d3ppre) +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ /** STM2WBA specifics RCC dividers */ #define STM32_AHB5_DIV DT_PROP(DT_NODELABEL(rcc), ahb5_div) @@ -133,7 +145,8 @@ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32u5_pll_clock, okay) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wb_pll_clock, okay) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wba_pll_clock, okay) || \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7_pll_clock, okay) + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7_pll_clock, okay) || \ + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7rs_pll_clock, okay) #define STM32_PLL_ENABLED 1 #define STM32_PLL_M_DIVISOR DT_PROP(DT_NODELABEL(pll), div_m) #define STM32_PLL_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul_n) @@ -143,6 +156,8 @@ #define STM32_PLL_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_q, 1) #define STM32_PLL_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_r) #define STM32_PLL_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_r, 1) +#define STM32_PLL_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_s) +#define STM32_PLL_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_s, 1) #define STM32_PLL_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), fracn) #define STM32_PLL_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll), fracn, 1) #endif @@ -164,7 +179,8 @@ #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32u5_pll_clock, okay) || \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7_pll_clock, okay) + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7_pll_clock, okay) || \ + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7rs_pll_clock, okay) #define STM32_PLL2_ENABLED 1 #define STM32_PLL2_M_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_m) #define STM32_PLL2_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll2), mul_n) @@ -174,12 +190,17 @@ #define STM32_PLL2_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_q, 1) #define STM32_PLL2_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_r) #define STM32_PLL2_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_r, 1) +#define STM32_PLL2_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_s) +#define STM32_PLL2_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_s, 1) +#define STM32_PLL2_T_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_t) +#define STM32_PLL2_T_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_t, 1) #define STM32_PLL2_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), fracn) #define STM32_PLL2_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll2), fracn, 1) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7_pll_clock, okay) || \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32u5_pll_clock, okay) + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32u5_pll_clock, okay) || \ + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7rs_pll_clock, okay) #define STM32_PLL3_ENABLED 1 #define STM32_PLL3_M_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_m) #define STM32_PLL3_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll3), mul_n) @@ -189,6 +210,8 @@ #define STM32_PLL3_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_q, 1) #define STM32_PLL3_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_r) #define STM32_PLL3_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_r, 1) +#define STM32_PLL3_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_s) +#define STM32_PLL3_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_s, 1) #define STM32_PLL3_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), fracn) #define STM32_PLL3_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll3), fracn, 1) #endif diff --git a/include/zephyr/drivers/disk.h b/include/zephyr/drivers/disk.h index 623b65118b3be4..c248ccd93db3cc 100644 --- a/include/zephyr/drivers/disk.h +++ b/include/zephyr/drivers/disk.h @@ -49,6 +49,24 @@ extern "C" { #define DISK_IOCTL_GET_ERASE_BLOCK_SZ 4 /** Commit any cached read/writes to disk */ #define DISK_IOCTL_CTRL_SYNC 5 +/** Initialize the disk. This IOCTL must be issued before the disk can be + * used for I/O. It is reference counted, so only the first successful + * invocation of this macro on an uninitialized disk will initialize the IO + * device + */ +#define DISK_IOCTL_CTRL_INIT 6 +/** Deinitialize the disk. This IOCTL can be used to de-initialize the disk, + * enabling it to be removed from the system if the disk is hot-pluggable. + * Disk usage is reference counted, so for a given disk the + * `DISK_IOCTL_CTRL_DEINIT` IOCTL must be issued as many times as the + * `DISK_IOCTL_CTRL_INIT` IOCTL was issued in order to de-initialize it. + * + * This macro optionally accepts a pointer to a boolean as the `buf` parameter, + * which if true indicates the disk should be forcibly stopped, ignoring all + * reference counts. The disk driver must report success if a forced stop is + * requested, but this operation is inherently unsafe. + */ +#define DISK_IOCTL_CTRL_DEINIT 7 /** * @brief Possible return bitmasks for disk_status() @@ -77,6 +95,8 @@ struct disk_info { const struct disk_operations *ops; /** Device associated to this disk */ const struct device *dev; + /** Internally used disk reference count */ + uint16_t refcnt; }; /** diff --git a/include/zephyr/drivers/espi.h b/include/zephyr/drivers/espi.h index 05e5cda2251b49..62e4ce5e28bf0a 100644 --- a/include/zephyr/drivers/espi.h +++ b/include/zephyr/drivers/espi.h @@ -112,14 +112,38 @@ enum espi_channel { * eSPI bus event to indicate events for which user can register callbacks */ enum espi_bus_event { + /** Indicates the eSPI bus was reset either via eSPI reset pin. + * eSPI drivers should convey the eSPI reset status to eSPI driver clients + * following eSPI specification reset pin convention: + * 0-eSPI bus in reset, 1-eSPI bus out-of-reset + * + * Note: There is no need to send this callback for in-band reset. + */ ESPI_BUS_RESET = BIT(0), + + /** Indicates the eSPI HW has received channel enable notification from eSPI host, + * once the eSPI channel is signal as ready to the eSPI host, + * eSPI drivers should convey the eSPI channel ready to eSPI driver client via this event. + */ ESPI_BUS_EVENT_CHANNEL_READY = BIT(1), + + /** Indicates the eSPI HW has received a virtual wire message from eSPI host. + * eSPI drivers should convey the eSPI virtual wire latest status. + */ ESPI_BUS_EVENT_VWIRE_RECEIVED = BIT(2), + + /** Indicates the eSPI HW has received a Out-of-band package from eSPI host. + */ ESPI_BUS_EVENT_OOB_RECEIVED = BIT(3), + + /** Indicates the eSPI HW has received a peripheral eSPI host event. + * eSPI drivers should convey the peripheral type. + */ ESPI_BUS_PERIPHERAL_NOTIFICATION = BIT(4), - ESPI_BUS_SAF_NOTIFICATION = BIT(5), + ESPI_BUS_TAF_NOTIFICATION = BIT(5), }; + /** * @brief eSPI peripheral channel events. * @@ -354,6 +378,12 @@ struct espi_request_packet { /** * @brief eSPI out-of-band transaction packet format + * + * For Tx packet, eSPI driver client shall specify the OOB payload data and its length in bytes. + * For Rx packet, eSPI driver client shall indicate the maximum number of bytes that can receive, + * while the eSPI driver should update the length field with the actual data received/available. + * + * In all cases, the length does not include OOB header size 3 bytes. */ struct espi_oob_packet { uint8_t *buf; @@ -895,12 +925,11 @@ static inline int z_impl_espi_flash_erase(const struct device *dev, * | | | eSPI reset | eSPI host * | | IRQ +<------------+ resets the * | | <-----------+ | bus - * | | | | - * | | Processed | | + * |<-----------------------------| | | + * | Report eSPI bus reset | Processed | | * | | within the | | * | | driver | | * | | | | - * | | | VW CH ready| eSPI host * | | IRQ +<------------+ enables VW * | | <-----------+ | channel diff --git a/include/zephyr/drivers/flash.h b/include/zephyr/drivers/flash.h index beb8838d71e9e3..7ceea4a5b254e6 100644 --- a/include/zephyr/drivers/flash.h +++ b/include/zephyr/drivers/flash.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2017-2024 Nordic Semiconductor ASA * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 @@ -58,9 +58,59 @@ struct flash_pages_layout { */ struct flash_parameters { const size_t write_block_size; + /* Device capabilities. Only drivers are supposed to set the + * capabilities directly, users need to call the FLASH_CAPS_ + * macros on pointer to flash_parameters to get capabilities. + */ + struct { + /* Device has no explicit erase, so it either erases on + * write or does not require it at all. + * This also includes devices that support erase but + * do not require it. + */ + bool no_explicit_erase: 1; + } caps; uint8_t erase_value; /* Byte value of erased flash */ }; +/** Set for ordinary Flash where erase is needed before write of random data */ +#define FLASH_ERASE_C_EXPLICIT 0x01 +/** Reserved for users as initializer for variables that will later store + * capabilities. + */ +#define FLASH_ERASE_CAPS_UNSET (int)-1 +/* The values below are now reserved but not used */ +#define FLASH_ERASE_C_SUPPORTED 0x02 +#define FLASH_ERASE_C_VAL_BIT 0x04 +#define FLASH_ERASE_UNIFORM_PAGE 0x08 + + +/* @brief Parser for flash_parameters for retrieving erase capabilities + * + * The functions parses flash_parameters type object and returns combination + * of erase capabilities of 0 if device does not have any. + * Not that in some cases availability of erase may be dependent on driver + * options, so even if by hardware design a device provides some erase + * capabilities, the function may return 0 if these been disabled or not + * implemented by driver. + * + * @param p pointer to flash_parameters type object + * + * @return 0 or combination of FLASH_ERASE_C_ capabilities. + */ +static inline +int flash_params_get_erase_cap(const struct flash_parameters *p) +{ +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) + return (p->caps.no_explicit_erase) ? 0 : FLASH_ERASE_C_EXPLICIT; +#else + return FLASH_ERASE_C_EXPLICIT; +#endif +#endif + return 0; +} + /** * @} */ @@ -91,6 +141,11 @@ typedef int (*flash_api_write)(const struct device *dev, off_t offset, * the driver, with the driver responsible for ensuring the "erase-protect" * after the operation completes (successfully or not) matches the erase-protect * state when the operation was started. + * + * The callback is optional for RAM non-volatile devices, which do not + * require erase by design, but may be provided if it allows device to + * work more effectively, or if device has a support for internal fill + * operation the erase in driver uses. */ typedef int (*flash_api_erase)(const struct device *dev, off_t offset, size_t size); @@ -228,12 +283,19 @@ static inline int z_impl_flash_write(const struct device *dev, off_t offset, * Any necessary erase protection management is performed by the driver * erase implementation itself. * + * The function should be used only for devices that are really + * explicit erase devices; in case when code relies on erasing + * device, i.e. setting it to erase-value, prior to some operations, + * but should work with explicit erase and RAM non-volatile devices, + * then flash_flatten should rather be used. + * * @param dev : flash device * @param offset : erase area starting offset * @param size : size of area to be erased * * @return 0 on success, negative errno code on fail. * + * @see flash_flatten() * @see flash_get_page_info_by_offs() * @see flash_get_page_info_by_idx() */ @@ -242,15 +304,59 @@ __syscall int flash_erase(const struct device *dev, off_t offset, size_t size); static inline int z_impl_flash_erase(const struct device *dev, off_t offset, size_t size) { + int rc = -ENOSYS; + const struct flash_driver_api *api = (const struct flash_driver_api *)dev->api; - int rc; - rc = api->erase(dev, offset, size); + if (api->erase != NULL) { + rc = api->erase(dev, offset, size); + } return rc; } +__syscall int flash_fill(const struct device *dev, uint8_t val, off_t offset, size_t size); + +/** + * @brief Erase part or all of a flash memory or level it + * + * If device is explicit erase type device or device driver provides erase + * callback, the callback of the device is called, in which it behaves + * the same way as flash_erase. + * If a device is does not require explicit erase, either because + * it has no erase at all or has auto-erase/erase-on-write, + * and does not provide erase callback then erase is emulated by + * leveling selected device memory area with erase_value assigned to + * device. + * + * Erase page offset and size are constrains of paged, explicit erase devices, + * but can be relaxed with devices without such requirement, which means that + * it is up to user code to make sure they are correct as the function + * will return on, if these constrains are not met, -EINVAL for + * paged device, but may succeed on non-explicit erase devices. + * For RAM non-volatile devices the erase pages are emulated, + * at this point, to allow smooth transition for code relying on + * device being paged to function properly; but this is completely + * software constrain. + * + * Generally: if your code previously required device to be erase + * prior to some actions to work, replace flash_erase calls with this + * function; but if your code can work with non-volatile RAM type devices, + * without emulating erase, you should rather have different path + * of execution for page-erase, i.e. Flash, devices and call + * flash_erase for them. + * + * @param dev : flash device + * @param offset : erase area starting offset + * @param size : size of area to be erased + * + * @return 0 on success, negative errno code on fail. + * + * @see flash_erase() + */ +__syscall int flash_flatten(const struct device *dev, off_t offset, size_t size); + struct flash_pages_info { off_t start_offset; /* offset from the base of flash address */ size_t size; diff --git a/include/zephyr/drivers/i2c/rtio.h b/include/zephyr/drivers/i2c/rtio.h index d4dc6c32ae22ec..2f094540f70119 100644 --- a/include/zephyr/drivers/i2c/rtio.h +++ b/include/zephyr/drivers/i2c/rtio.h @@ -22,7 +22,7 @@ struct i2c_rtio { struct k_sem lock; struct k_spinlock slock; struct rtio *r; - struct rtio_mpsc io_q; + struct mpsc io_q; struct rtio_iodev iodev; struct rtio_iodev_sqe *txn_head; struct rtio_iodev_sqe *txn_curr; diff --git a/include/zephyr/drivers/misc/README b/include/zephyr/drivers/misc/README index 17a18102f36783..a820cf63408759 100644 --- a/include/zephyr/drivers/misc/README +++ b/include/zephyr/drivers/misc/README @@ -15,3 +15,7 @@ This directory contains header files of the Miscellaneous Drivers. layer graphic operations like widgets, shapes, fonts, text, or bitmaps rendering. These operations are controlled by a vendor-specific API designed for this device. + +* STM32 Wake-up Pins + STM32 wake-up pins are part of the Power Control (PWR) peripheral. + They can be used to wake-up the system from Poweroff through GPIO pins. diff --git a/include/zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h b/include/zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h new file mode 100644 index 00000000000000..f5b48552e2789b --- /dev/null +++ b/include/zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public APIs for STM32 PWR wake-up pins configuration + */ + +#ifndef ZEPHYR_DRIVERS_MISC_STM32_WKUP_PINS_H_ +#define ZEPHYR_DRIVERS_MISC_STM32_WKUP_PINS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configure a GPIO pin as a source for STM32 PWR wake-up pins + * + * @param gpio Container for GPIO pin information specified in devicetree + * + * @return 0 on success, -EINVAL on invalid values + */ +int stm32_pwr_wkup_pin_cfg_gpio(const struct gpio_dt_spec *gpio); + +/** + * @brief Enable or Disable pull-up and pull-down configuration for + * GPIO Ports that are associated with STM32 PWR wake-up pins + */ +void stm32_pwr_wkup_pin_cfg_pupd(void); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_MISC_STM32_WKUP_PINS_H_ */ diff --git a/include/zephyr/drivers/sensor_data_types.h b/include/zephyr/drivers/sensor_data_types.h index e1a2bc5c3e4013..604fa614e123aa 100644 --- a/include/zephyr/drivers/sensor_data_types.h +++ b/include/zephyr/drivers/sensor_data_types.h @@ -110,6 +110,7 @@ struct sensor_q31_data { q31_t power; /**< Unit: watts */ q31_t angle; /**< Unit: degrees */ q31_t electric_charge; /**< Unit: mAh */ + q31_t humidity; /**< Unit: RH */ }; } readings[1]; }; diff --git a/include/zephyr/drivers/serial/uart_emul.h b/include/zephyr/drivers/serial/uart_emul.h index 08e6be05b1aeb7..83598a235d945a 100644 --- a/include/zephyr/drivers/serial/uart_emul.h +++ b/include/zephyr/drivers/serial/uart_emul.h @@ -52,7 +52,7 @@ void uart_emul_callback_tx_data_ready_set(const struct device *dev, * * @return Number of bytes appended */ -uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t size); +uint32_t uart_emul_put_rx_data(const struct device *dev, const uint8_t *data, size_t size); /** * @brief Read data from TX buffer @@ -91,6 +91,14 @@ uint32_t uart_emul_flush_tx_data(const struct device *dev); */ void uart_emul_set_errors(const struct device *dev, int errors); +/** + * @brief Configures if rx buffer should be released on timeout, even when only partially filled. + * + * @param dev The emulated UART device instance + * @param release_on_timeout When true, buffer will be released on timeout + */ +void uart_emul_set_release_buffer_on_timeout(const struct device *dev, bool release_on_timeout); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index a24a63a209ad4d..6e394ba8b2b40c 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -615,7 +615,7 @@ typedef void (*spi_callback_t)(const struct device *dev, int result, void *data) /** * @typedef spi_api_io * @brief Callback API for asynchronous I/O - * See spi_transceive_async() for argument descriptions + * See spi_transceive_signal() for argument descriptions */ typedef int (*spi_api_io_async)(const struct device *dev, const struct spi_config *config, @@ -932,20 +932,6 @@ static inline int spi_transceive_signal(const struct device *dev, return api->transceive_async(dev, config, tx_bufs, rx_bufs, cb, sig); } -/** - * @brief Alias for spi_transceive_signal for backwards compatibility - * - * @deprecated Use @ref spi_transceive_signal instead. - */ -__deprecated static inline int spi_transceive_async(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs, - struct k_poll_signal *sig) -{ - return spi_transceive_signal(dev, config, tx_bufs, rx_bufs, sig); -} - /** * @brief Read the specified amount of data from the SPI driver. * @@ -978,25 +964,12 @@ static inline int spi_read_signal(const struct device *dev, return spi_transceive_signal(dev, config, NULL, rx_bufs, sig); } -/** - * @brief Alias for spi_read_signal for backwards compatibility - * - * @deprecated Use @ref spi_read_signal instead. - */ -__deprecated static inline int spi_read_async(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *rx_bufs, - struct k_poll_signal *sig) -{ - return spi_read_signal(dev, config, rx_bufs, sig); -} - /** * @brief Write the specified amount of data from the SPI driver. * * @note This function is asynchronous. * - * @note This function is a helper function calling spi_transceive_async. + * @note This function is a helper function calling spi_transceive_signal. * * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC} * and @kconfig{CONFIG_POLL} are selected. @@ -1022,19 +995,6 @@ static inline int spi_write_signal(const struct device *dev, return spi_transceive_signal(dev, config, tx_bufs, NULL, sig); } -/** - * @brief Alias for spi_write_signal for backwards compatibility - * - * @deprecated Use @ref spi_write_signal instead. - */ -__deprecated static inline int spi_write_async(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - struct k_poll_signal *sig) -{ - return spi_write_signal(dev, config, tx_bufs, sig); -} - #endif /* CONFIG_POLL */ #endif /* CONFIG_SPI_ASYNC */ diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 94b6b2049f6ff2..7b94e3f93a88a5 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -154,7 +154,9 @@ __subsystem struct tcpc_driver_api { int (*set_debug_detach)(const struct device *dev); int (*set_drp_toggle)(const struct device *dev, bool enable); int (*get_snk_ctrl)(const struct device *dev); + int (*set_snk_ctrl)(const struct device *dev, bool enable); int (*get_src_ctrl)(const struct device *dev); + int (*set_src_ctrl)(const struct device *dev, bool enable); int (*get_chip_info)(const struct device *dev, struct tcpc_chip_info *chip_info); int (*set_low_power_mode)(const struct device *dev, bool enable); int (*sop_prime_enable)(const struct device *dev, bool enable); @@ -756,6 +758,25 @@ static inline int tcpc_get_snk_ctrl(const struct device *dev) return api->get_snk_ctrl(dev); } +/** + * @brief Set the VBUS sinking state of the TCPC + * + * @param dev Runtime device structure + * @param enable True if sinking should be enabled, false if disabled + * @retval 0 on success + * @retval -ENOSYS if not implemented + */ +static inline int tcpc_set_snk_ctrl(const struct device *dev, bool enable) +{ + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; + + if (api->set_snk_ctrl == NULL) { + return -ENOSYS; + } + + return api->set_snk_ctrl(dev, enable); +} + /** * @brief Queries the current sourcing state of the TCPC * @@ -777,6 +798,25 @@ static inline int tcpc_get_src_ctrl(const struct device *dev) return api->get_src_ctrl(dev); } +/** + * @brief Set the VBUS sourcing state of the TCPC + * + * @param dev Runtime device structure + * @param enable True if sourcing should be enabled, false if disabled + * @retval 0 on success + * @retval -ENOSYS if not implemented + */ +static inline int tcpc_set_src_ctrl(const struct device *dev, bool enable) +{ + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; + + if (api->set_src_ctrl == NULL) { + return -ENOSYS; + } + + return api->set_src_ctrl(dev, enable); +} + /** * @brief Controls the BIST Mode of the TCPC. It disables RX alerts while the * mode is active. diff --git a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h index f21844a149047c..18c44cab86fddb 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h @@ -92,6 +92,8 @@ /* ENET */ #define IMX_CCM_ENET_CLK 0x1200UL #define IMX_CCM_ENET_PLL 0x1201UL +#define IMX_CCM_ENET1G_CLK 0x1202UL +#define IMX_CCM_ENET1G_PLL 0x1203UL /* FLEXSPI */ #define IMX_CCM_FLEXSPI_CLK 0x1300UL @@ -114,4 +116,11 @@ #define IMX_CCM_TPM5_CLK 0x1604UL #define IMX_CCM_TPM6_CLK 0x1605UL +/* QTMR */ +#define IMX_CCM_QTMR_CLK 0x6000UL +#define IMX_CCM_QTMR1_CLK 0x6000UL +#define IMX_CCM_QTMR2_CLK 0x6001UL +#define IMX_CCM_QTMR3_CLK 0x6002UL +#define IMX_CCM_QTMR4_CLK 0x6003UL + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_IMX_CCM_REV2_H_ */ diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index 4d5f20f371e000..71241be75ce808 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -76,9 +76,15 @@ #define MCUX_ENET_QOS_CLK MCUX_LPC_CLK_ID(0x0D, 0x00) +#define MCUX_ENET_CLK MCUX_LPC_CLK_ID(0x0D, 0x80) +#define MCUX_ENET_PLL MCUX_LPC_CLK_ID(0x0D, 0x81) + #define MCUX_LCDIC_CLK MCUX_LPC_CLK_ID(0x0E, 0x00) #define MCUX_LPADC1_CLK MCUX_LPC_CLK_ID(0x0F, 0x00) #define MCUX_LPADC2_CLK MCUX_LPC_CLK_ID(0x0F, 0x01) +#define MCUX_FLEXCAN0_CLK MCUX_LPC_CLK_ID(0x10, 0x00) +#define MCUX_FLEXCAN1_CLK MCUX_LPC_CLK_ID(0x10, 0x01) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h new file mode 100644 index 00000000000000..579ae56b0e250e --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_ + +#include "stm32_common_clocks.h" + +/** Domain clocks */ + +/* RM0477 */ + +/** System clock */ +/* defined in stm32_common_clocks.h */ + +/** Fixed clocks */ +/* Low speed clocks defined in stm32_common_clocks.h */ +#define STM32_SRC_HSE (STM32_SRC_LSI + 1) +#define STM32_SRC_HSI48 (STM32_SRC_HSE + 1) +#define STM32_SRC_HSI_KER (STM32_SRC_HSI48 + 1) /* HSI + HSIKERON */ +#define STM32_SRC_CSI_KER (STM32_SRC_HSI_KER + 1) /* CSI + CSIKERON */ +/** PLL outputs */ +#define STM32_SRC_PLL1_P (STM32_SRC_CSI_KER + 1) +#define STM32_SRC_PLL1_Q (STM32_SRC_PLL1_P + 1) +#define STM32_SRC_PLL1_R (STM32_SRC_PLL1_Q + 1) +#define STM32_SRC_PLL1_S (STM32_SRC_PLL1_R + 1) +#define STM32_SRC_PLL2_P (STM32_SRC_PLL1_S + 1) +#define STM32_SRC_PLL2_Q (STM32_SRC_PLL2_P + 1) +#define STM32_SRC_PLL2_R (STM32_SRC_PLL2_Q + 1) +#define STM32_SRC_PLL2_S (STM32_SRC_PLL2_R + 1) +#define STM32_SRC_PLL2_T (STM32_SRC_PLL2_S + 1) +#define STM32_SRC_PLL3_P (STM32_SRC_PLL2_T + 1) +#define STM32_SRC_PLL3_Q (STM32_SRC_PLL3_P + 1) +#define STM32_SRC_PLL3_R (STM32_SRC_PLL3_Q + 1) +#define STM32_SRC_PLL3_S (STM32_SRC_PLL3_R + 1) + +/** Clock muxes */ +#define STM32_SRC_CKPER (STM32_SRC_PLL3_S + 1) +/** Others: Not yet supported */ + +/** Bus clocks */ +#define STM32_CLOCK_BUS_AHB1 0x138 +#define STM32_CLOCK_BUS_AHB2 0x13C +#define STM32_CLOCK_BUS_AHB3 0x158 +#define STM32_CLOCK_BUS_AHB4 0x140 +#define STM32_CLOCK_BUS_AHB5 0x134 +#define STM32_CLOCK_BUS_APB1 0x148 +#define STM32_CLOCK_BUS_APB1_2 0x14C +#define STM32_CLOCK_BUS_APB2 0x150 +#define STM32_CLOCK_BUS_APB4 0x154 +#define STM32_CLOCK_BUS_APB5 0x144 +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB5 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_AHB3 + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +/** + * @brief STM32H7RS clock configuration bit field. + * + * - reg (0/1) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..3) [ 16 : 18 ] + * + * @param reg RCC_DxCCIP register offset + * @param shift Position within RCC_DxCCIP. + * @param mask Mask for the RCC_DxCCIP field. + * @param val Clock value (0, 1, 2 or 3). + */ +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_DxCCIP register offset (RM0477.pdf) */ +#define D1CCIPR_REG 0x4C +#define D2CCIPR_REG 0x50 +#define D3CCIPR_REG 0x54 +#define D4CCIPR_REG 0x58 + +/** @brief RCC_BDCR register offset */ +#define BDCR_REG 0x70 + +/** @brief Device domain clocks selection helpers (RM0477.pdf) */ + +/* TODO to be completed */ + +/** D1CCIPR devices */ +#define FMC_SEL(val) STM32_CLOCK(val, 3, 0, D1CCIPR_REG) +#define SDMMC_SEL(val) STM32_CLOCK(val, 1, 2, D1CCIPR_REG) +#define XSPI1_SEL(val) STM32_CLOCK(val, 3, 4, D1CCIPR_REG) +#define XSPI2_SEL(val) STM32_CLOCK(val, 3, 6, D1CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 24, D1CCIPR_REG) +#define CKPER_SEL(val) STM32_CLOCK(val, 3, 28, D1CCIPR_REG) + +/** D2CCIPR devices */ +#define USART234578_SEL(val) STM32_CLOCK(val, 7, 0, D2CCIPR_REG) +#define SPI23_SEL(val) STM32_CLOCK(val, 7, 4, D2CCIPR_REG) +#define I2C23_SEL(val) STM32_CLOCK(val, 3, 8, D2CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, D2CCIPR_REG) +#define I3C1_SEL(val) STM32_CLOCK(val, 3, 12, D2CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 7, 16, D2CCIPR_REG) +#define FDCAN_SEL(val) STM32_CLOCK(val, 3, 22, D2CCIPR_REG) + +/** D3CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 7, 0, D3CCIPR_REG) +#define SPI45_SEL(val) STM32_CLOCK(val, 7, 4, D3CCIPR_REG) +#define SPI1_SEL(val) STM32_CLOCK(val, 7, 8, D3CCIPR_REG) +#define SAI1_SEL(val) STM32_CLOCK(val, 7, 16, D3CCIPR_REG) +#define SAI2_SEL(val) STM32_CLOCK(val, 7, 20, D3CCIPR_REG) + +/** D4CCIPR devices */ +#define LPUART1_SEL(val) STM32_CLOCK(val, 7, 0, D4CCIPR_REG) +#define SPI6_SEL(val) STM32_CLOCK(val, 7, 4, D4CCIPR_REG) +#define LPTIM23_SEL(val) STM32_CLOCK(val, 7, 8, D4CCIPR_REG) +#define LPTIM45_SEL(val) STM32_CLOCK(val, 7, 12, D4CCIPR_REG) + +/** BDCR devices */ +#define RTC_SEL(val) STM32_CLOCK(val, 3, 8, BDCR_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/dma/dma_smartbond.h b/include/zephyr/dt-bindings/dma/dma_smartbond.h new file mode 100644 index 00000000000000..4240801c9756a1 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/dma_smartbond.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DMA_SMARTBOND_H_ +#define DMA_SMARTBOND_H_ + +/** + * @brief Vendror-specific DMA peripheral triggering sources. + * + * A valid triggering source should be provided when DMA + * is configured for peripheral to peripheral or memory to peripheral + * transactions. + */ +#define DMA_SMARTBOND_TRIG_MUX_SPI 0x0 +#define DMA_SMARTBOND_TRIG_MUX_SPI2 0x1 +#define DMA_SMARTBOND_TRIG_MUX_UART 0x2 +#define DMA_SMARTBOND_TRIG_MUX_UART2 0x3 +#define DMA_SMARTBOND_TRIG_MUX_I2C 0x4 +#define DMA_SMARTBOND_TRIG_MUX_I2C2 0x5 +#define DMA_SMARTBOND_TRIG_MUX_USB 0x6 +#define DMA_SMARTBOND_TRIG_MUX_UART3 0x7 +#define DMA_SMARTBOND_TRIG_MUX_PCM 0x8 +#define DMA_SMARTBOND_TRIG_MUX_SRC 0x9 +#define DMA_SMARTBOND_TRIG_MUX_GPADC 0xC +#define DMA_SMARTBOND_TRIG_MUX_SDADC 0xD +#define DMA_SMARTBOND_TRIG_MUX_NONE 0xF + +#endif /* DMA_SMARTBOND_H_ */ diff --git a/include/zephyr/dt-bindings/ethernet/nxp_enet.h b/include/zephyr/dt-bindings/ethernet/nxp_enet.h index e084825da4c754..0e307c9ebfc6fa 100644 --- a/include/zephyr/dt-bindings/ethernet/nxp_enet.h +++ b/include/zephyr/dt-bindings/ethernet/nxp_enet.h @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #define NXP_ENET_MII_MODE 0 #define NXP_ENET_RMII_MODE 1 +#define NXP_ENET_RGMII_MODE 2 #define NXP_ENET_INVALID_MII_MODE 100 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_NXP_ENET_H_ */ diff --git a/include/zephyr/dt-bindings/gpio/stm32-gpio.h b/include/zephyr/dt-bindings/gpio/stm32-gpio.h new file mode 100644 index 00000000000000..f9a3a4b60af6c5 --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/stm32-gpio.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_STM32_GPIO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_STM32_GPIO_H_ + +/** + * @brief STM32 GPIO specific flags + * + * The driver flags are encoded in the 8 upper bits of @ref gpio_dt_flags_t as + * follows: + * + * - Bit 8: Configure a GPIO pin to power on the system after Poweroff. + * + * @ingroup gpio_interface + * @{ + */ + +/** + * Configures a GPIO pin to power on the system after Poweroff. + * This flag is reserved to GPIO pins that are associated with wake-up pins + * in STM32 PWR devicetree node, through the property "wkup-gpios". + */ +#define STM32_GPIO_WKUP (1 << 8) + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_STM32_GPIO_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h index fdfde7fccac0b8..38b8f6e42db802 100644 --- a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h +++ b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl-s1.h @@ -26,7 +26,7 @@ /** Position of the function field. */ #define GECKO_FUN_POS 24U /** Mask for the function field. */ -#define GECKO_FUN_MSK 0xFFFU +#define GECKO_FUN_MSK 0xFFU /** Position of the pin field. */ #define GECKO_PIN_POS 0U diff --git a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h index 5624f1e809ee9c..a49f4fe793e54d 100644 --- a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h @@ -26,7 +26,7 @@ /** Position of the function field. */ #define GECKO_FUN_POS 24U /** Mask for the function field. */ -#define GECKO_FUN_MSK 0xFFFU +#define GECKO_FUN_MSK 0xFFU /** Position of the pin field. */ #define GECKO_PIN_POS 0U diff --git a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h index 0e752e54d4e0e0..0c5933c580e503 100644 --- a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h +++ b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h @@ -22,9 +22,13 @@ #define STM32_PORTI 8 #define STM32_PORTJ 9 #define STM32_PORTK 10 /* IO port K */ +#define STM32_PORTM 12 /* IO port M (0xC) */ +#define STM32_PORTN 13 +#define STM32_PORTO 14 +#define STM32_PORTP 15 /* IO port P (0xF) */ #ifndef STM32_PORTS_MAX -#define STM32_PORTS_MAX (STM32_PORTK + 1) +#define STM32_PORTS_MAX (STM32_PORTP + 1) #endif /** diff --git a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h index f5d0309897a860..52612f6948d512 100644 --- a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h @@ -44,7 +44,7 @@ #define STM32_LINE_SHIFT 5U #define STM32_LINE_MASK 0xFU #define STM32_PORT_SHIFT 9U -#define STM32_PORT_MASK 0xFU +#define STM32_PORT_MASK 0x1FU /** * @brief Pin configuration configuration bit field. @@ -53,9 +53,9 @@ * * - mode [ 0 : 4 ] * - line [ 5 : 8 ] - * - port [ 9 : 12 ] + * - port [ 9 : 13 ] * - * @param port Port ('A'..'K') + * @param port Port ('A'..'P') * @param line Pin (0..15) * @param mode Mode (ANALOG, GPIO_IN, ALTERNATE). */ diff --git a/include/zephyr/dt-bindings/power/stm32_pwr.h b/include/zephyr/dt-bindings/power/stm32_pwr.h new file mode 100644 index 00000000000000..8c7962f14ada8c --- /dev/null +++ b/include/zephyr/dt-bindings/power/stm32_pwr.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_POWER_STM32_PWR_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_STM32_PWR_H_ + +/** + * @brief STM32 power controller + * @{ + */ + +/** + * @name flags for wake-up pins sources + * @{ + */ + +#define STM32_PWR_WKUP_PIN_SRC_0 0 +#define STM32_PWR_WKUP_PIN_SRC_1 1 +#define STM32_PWR_WKUP_PIN_SRC_2 (1 << 2) + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_STM32_PWR_H_ */ diff --git a/include/zephyr/dt-bindings/reset/stm32h7rs_reset.h b/include/zephyr/dt-bindings/reset/stm32h7rs_reset.h new file mode 100644 index 00000000000000..a4a90a9cc10154 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/stm32h7rs_reset.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Google Inc + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32H7RS_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32H7RS_RESET_H_ + +#include "stm32-common.h" + +/* RCC bus reset register offset */ +#define STM32_RESET_BUS_AHB1 0x80 +#define STM32_RESET_BUS_AHB2 0x84 +#define STM32_RESET_BUS_AHB3 0xA4 +#define STM32_RESET_BUS_AHB5 0x7C +#define STM32_RESET_BUS_APB5 0x8C +#define STM32_RESET_BUS_AHB4 0x88 +#define STM32_RESET_BUS_APB1L 0x90 +#define STM32_RESET_BUS_APB1H 0x94 +#define STM32_RESET_BUS_APB2 0x98 +#define STM32_RESET_BUS_APB4 0x9C + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32H7RS_RESET_H_ */ diff --git a/include/zephyr/fatal.h b/include/zephyr/fatal.h index be3dd2078c5cdf..0fa1e93363ed40 100644 --- a/include/zephyr/fatal.h +++ b/include/zephyr/fatal.h @@ -12,6 +12,7 @@ #define ZEPHYR_INCLUDE_FATAL_H #include +#include #include #include @@ -64,7 +65,7 @@ FUNC_NORETURN void k_fatal_halt(unsigned int reason); * @param esf Exception context, with details and partial or full register * state when the error occurred. May in some cases be NULL. */ -void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf); +void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *esf); /** * Called by architecture code upon a fatal error. @@ -80,7 +81,7 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf); * @param esf Exception context, with details and partial or full register * state when the error occurred. May in some cases be NULL. */ -void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +void z_fatal_error(unsigned int reason, const struct arch_esf *esf); /** @} */ diff --git a/include/zephyr/fs/fcb.h b/include/zephyr/fs/fcb.h index 959a60b3286468..63d68ef0898bf2 100644 --- a/include/zephyr/fs/fcb.h +++ b/include/zephyr/fs/fcb.h @@ -37,7 +37,7 @@ extern "C" { * @{ */ -#define FCB_MAX_LEN (CHAR_MAX | CHAR_MAX << 7) /**< Max length of element */ +#define FCB_MAX_LEN (0x3fffu) /**< Max length of element (16,383) */ /** * @brief FCB entry info structure. This data structure describes the element diff --git a/include/zephyr/fs/fs_interface.h b/include/zephyr/fs/fs_interface.h index 5db637635b954c..1f0d26ce5bc1e9 100644 --- a/include/zephyr/fs/fs_interface.h +++ b/include/zephyr/fs/fs_interface.h @@ -13,10 +13,23 @@ extern "C" { #endif -#if defined(CONFIG_FILE_SYSTEM_MAX_FILE_NAME) && (CONFIG_FILE_SYSTEM_MAX_FILE_NAME - 0) > 0 +#if defined(CONFIG_FILE_SYSTEM_MAX_FILE_NAME) && (CONFIG_FILE_SYSTEM_MAX_FILE_NAME - 0) > 0 + +/* No in-tree file system supports name longer than 255 characters */ +#if (CONFIG_FILE_SYSTEM_LITTLEFS || CONFIG_FAT_FILESYSTEM_ELM || \ + CONFIG_FILE_SYSTEM_EXT2) && (CONFIG_FILE_SYSTEM_MAX_FILE_NAME > 255) +#error "Max allowed CONFIG_FILE_SYSTEM_MAX_FILE_NAME is 255 characters, when any in-tree FS enabled" +#endif + +/* Enabled FAT driver, without LFN, restricts name length to 12 characters */ +#if defined(CONFIG_FAT_FILESYSTEM_ELM) && !(CONFIG_FS_FATFS_LFN) && \ + (CONFIG_FILE_SYSTEM_MAX_FILE_NAME > 12) +#error "CONFIG_FILE_SYSTEM_MAX_FILE_NAME can not be > 12 if FAT is enabled without LFN" +#endif + #define MAX_FILE_NAME CONFIG_FILE_SYSTEM_MAX_FILE_NAME -#else /* CONFIG_FILE_SYSTEM_MAX_FILE_NAME */ +#else /* Select from enabled file systems */ #if defined(CONFIG_FAT_FILESYSTEM_ELM) @@ -34,7 +47,7 @@ extern "C" { #endif #if !defined(MAX_FILE_NAME) && defined(CONFIG_FILE_SYSTEM_LITTLEFS) -#define MAX_FILE_NAME 256 +#define MAX_FILE_NAME 255 #endif #if !defined(MAX_FILE_NAME) /* filesystem selection */ diff --git a/include/zephyr/ipc/icmsg.h b/include/zephyr/ipc/icmsg.h index 3bc03804ca824a..80e3412095acb4 100644 --- a/include/zephyr/ipc/icmsg.h +++ b/include/zephyr/ipc/icmsg.h @@ -111,7 +111,7 @@ int icmsg_close(const struct icmsg_config_t *conf, * @param[in] len Size of data in the @p msg buffer. * * - * @retval 0 on success. + * @retval Number of sent bytes. * @retval -EBUSY when the instance has not finished handshake with the remote * instance. * @retval -ENODATA when the requested data to send is empty. diff --git a/include/zephyr/irq.h b/include/zephyr/irq.h index 1fa559edccd347..4810a27b3e0ddb 100644 --- a/include/zephyr/irq.h +++ b/include/zephyr/irq.h @@ -215,7 +215,7 @@ irq_disconnect_dynamic(unsigned int irq, unsigned int priority, * * @note * This routine must also serve as a memory barrier to ensure the uniprocessor - * implementation of `k_spinlock_t` is correct. + * implementation of spinlocks is correct. * * This routine can be called recursively, as long as the caller keeps track * of each lock-out key that is generated. Interrupts are re-enabled by @@ -263,7 +263,7 @@ unsigned int z_smp_global_lock(void); * * @note * This routine must also serve as a memory barrier to ensure the uniprocessor - * implementation of `k_spinlock_t` is correct. + * implementation of spinlocks is correct. * * This routine can only be invoked from supervisor mode. Some architectures * (for example, ARM) will fail silently if invoked from user mode instead diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a6cf1ca352db33..8b25d4036d203c 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -2089,7 +2089,7 @@ __syscall int k_queue_is_empty(struct k_queue *queue); static inline int z_impl_k_queue_is_empty(struct k_queue *queue) { - return (int)sys_sflist_is_empty(&queue->data_q); + return sys_sflist_is_empty(&queue->data_q) ? 1 : 0; } /** @@ -4865,7 +4865,7 @@ void k_mbox_data_get(struct k_mbox_msg *rx_msg, void *buffer); struct k_pipe { unsigned char *buffer; /**< Pipe buffer: may be NULL */ size_t size; /**< Buffer size */ - size_t bytes_used; /**< # bytes used in buffer */ + size_t bytes_used; /**< Number of bytes used in buffer */ size_t read_index; /**< Where in buffer to read from */ size_t write_index; /**< Where in buffer to write */ struct k_spinlock lock; /**< Synchronization lock */ @@ -5731,14 +5731,17 @@ struct k_poll_event { /** per-type data */ union { - void *obj; - struct k_poll_signal *signal; - struct k_sem *sem; - struct k_fifo *fifo; - struct k_queue *queue; - struct k_msgq *msgq; + /* The typed_* fields below are used by K_POLL_EVENT_*INITIALIZER() macros to ensure + * type safety of polled objects. + */ + void *obj, *typed_K_POLL_TYPE_IGNORE; + struct k_poll_signal *signal, *typed_K_POLL_TYPE_SIGNAL; + struct k_sem *sem, *typed_K_POLL_TYPE_SEM_AVAILABLE; + struct k_fifo *fifo, *typed_K_POLL_TYPE_FIFO_DATA_AVAILABLE; + struct k_queue *queue, *typed_K_POLL_TYPE_DATA_AVAILABLE; + struct k_msgq *msgq, *typed_K_POLL_TYPE_MSGQ_DATA_AVAILABLE; #ifdef CONFIG_PIPES - struct k_pipe *pipe; + struct k_pipe *pipe, *typed_K_POLL_TYPE_PIPE_DATA_AVAILABLE; #endif }; }; @@ -5751,7 +5754,7 @@ struct k_poll_event { .mode = _event_mode, \ .unused = 0, \ { \ - .obj = _event_obj, \ + .typed_##_event_type = _event_obj, \ }, \ } @@ -5764,7 +5767,7 @@ struct k_poll_event { .mode = _event_mode, \ .unused = 0, \ { \ - .obj = _event_obj, \ + .typed_##_event_type = _event_obj, \ }, \ } diff --git a/include/zephyr/kernel/internal/mm.h b/include/zephyr/kernel/internal/mm.h index 61a8c69c5eef4b..2b5a9330e54619 100644 --- a/include/zephyr/kernel/internal/mm.h +++ b/include/zephyr/kernel/internal/mm.h @@ -16,11 +16,14 @@ * @{ */ -/* +/** + * @def K_MEM_VIRT_OFFSET + * @brief Address offset of permanent virtual mapping from physical address. + * * This is the offset to subtract from a virtual address mapped in the * kernel's permanent mapping of RAM, to obtain its physical address. * - * virt_addr = phys_addr + Z_MEM_VM_OFFSET + * virt_addr = phys_addr + K_MEM_VIRT_OFFSET * * This only works for virtual addresses within the interval * [CONFIG_KERNEL_VM_BASE, CONFIG_KERNEL_VM_BASE + (CONFIG_SRAM_SIZE * 1024)). @@ -35,17 +38,39 @@ * constraints defined. */ #ifdef CONFIG_MMU -#define Z_MEM_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ - (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) +#define K_MEM_VIRT_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ + (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) #else -#define Z_MEM_VM_OFFSET 0 +#define K_MEM_VIRT_OFFSET 0 #endif /* CONFIG_MMU */ -#define Z_MEM_PHYS_ADDR(virt) ((virt) - Z_MEM_VM_OFFSET) -#define Z_MEM_VIRT_ADDR(phys) ((phys) + Z_MEM_VM_OFFSET) +/** + * @brief Get physical address from virtual address. + * + * This only works in the kernel's permanent mapping of RAM. + * + * @param virt Virtual address + * + * @return Physical address. + */ +#define K_MEM_PHYS_ADDR(virt) ((virt) - K_MEM_VIRT_OFFSET) + +/** + * @brief Get virtual address from physical address. + * + * This only works in the kernel's permanent mapping of RAM. + * + * @param phys Physical address + * + * @return Virtual address. + */ +#define K_MEM_VIRT_ADDR(phys) ((phys) + K_MEM_VIRT_OFFSET) -#if Z_MEM_VM_OFFSET != 0 -#define Z_VM_KERNEL 1 +#if K_MEM_VIRT_OFFSET != 0 +/** + * @brief Kernel is mapped in virtual memory if defined. + */ +#define K_MEM_IS_VM_KERNEL 1 #ifdef CONFIG_XIP #error "XIP and a virtual memory kernel are not allowed" #endif @@ -58,8 +83,18 @@ #include #include -/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */ -static inline uintptr_t z_mem_phys_addr(void *virt) +/** + * @brief Get physical address from virtual address. + * + * This only works in the kernel's permanent mapping of RAM. + * + * Just like K_MEM_PHYS_ADDR() but with type safety and assertions. + * + * @param virt Virtual address + * + * @return Physical address. + */ +static inline uintptr_t k_mem_phys_addr(void *virt) { uintptr_t addr = (uintptr_t)virt; @@ -98,11 +133,21 @@ static inline uintptr_t z_mem_phys_addr(void *virt) * the above checks won't be sufficient with demand paging */ - return Z_MEM_PHYS_ADDR(addr); + return K_MEM_PHYS_ADDR(addr); } -/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */ -static inline void *z_mem_virt_addr(uintptr_t phys) +/** + * @brief Get virtual address from physical address. + * + * This only works in the kernel's permanent mapping of RAM. + * + * Just like K_MEM_VIRT_ADDR() but with type safety and assertions. + * + * @param phys Physical address + * + * @return Virtual address. + */ +static inline void *k_mem_virt_addr(uintptr_t phys) { #if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK) __ASSERT(sys_mm_is_phys_addr_in_range(phys), @@ -125,7 +170,7 @@ static inline void *z_mem_virt_addr(uintptr_t phys) * the above check won't be sufficient with demand paging */ - return (void *)Z_MEM_VIRT_ADDR(phys); + return (void *)K_MEM_VIRT_ADDR(phys); } #ifdef __cplusplus @@ -140,6 +185,9 @@ extern "C" { * linear address representing the base of where the physical region is mapped * in the virtual address space for the Zephyr kernel. * + * The memory mapped via this function must be unmapped using + * k_mem_unmap_phys_bare(). + * * This function alters the active page tables in the area reserved * for the kernel. This function will choose the virtual address * and return it to the caller. @@ -173,8 +221,8 @@ extern "C" { * @param[in] size Size of the memory region * @param[in] flags Caching mode and access flags, see K_MAP_* macros */ -void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, - uint32_t flags); +void k_mem_map_phys_bare(uint8_t **virt_ptr, uintptr_t phys, size_t size, + uint32_t flags); /** * Unmap a virtual memory region from kernel's virtual address space. @@ -188,7 +236,7 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, * * This will align the input parameters to page boundaries so that * this can be used with the virtual address as returned by - * z_phys_map(). + * k_mem_map_phys_bare(). * * This API is only available if CONFIG_MMU is enabled. * @@ -203,17 +251,45 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, * @param virt Starting address of the virtual address region to be unmapped. * @param size Size of the virtual address region */ -void z_phys_unmap(uint8_t *virt, size_t size); +void k_mem_unmap_phys_bare(uint8_t *virt, size_t size); /** * Map memory into virtual address space with guard pages. * * This maps memory into virtual address space with a preceding and - * a succeeding guard pages. + * a succeeding guard pages. The memory mapped via this function must be + * unmapped using k_mem_unmap_phys_guard(). * - * @see k_mem_map() for additional information if called via that. + * This function maps a contiguous physical memory region into kernel's + * virtual address space with a preceding and a succeeding guard pages. + * Given a physical address and a size, return a linear address representing + * the base of where the physical region is mapped in the virtual address + * space for the Zephyr kernel. + * + * This function alters the active page tables in the area reserved + * for the kernel. This function will choose the virtual address + * and return it to the caller. + * + * If user thread access control needs to be managed in any way, do not enable + * K_MEM_PERM_USER flags here; instead manage the region's permissions + * with memory domain APIs after the mapping has been established. Setting + * K_MEM_PERM_USER here will allow all user threads to access this memory + * which is usually undesirable. + * + * Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed. * - * @see k_mem_phys_map() for additional information if called via that. + * The returned virtual memory pointer will be page-aligned. The size + * parameter, and any base address for re-mapping purposes must be page- + * aligned. + * + * Note that the allocation includes two guard pages immediately before + * and after the requested region. The total size of the allocation will be + * the requested size plus the size of these two guard pages. + * + * Many K_MEM_MAP_* flags have been implemented to alter the behavior of this + * function, with details in the documentation for these flags. + * + * @see k_mem_map() for additional information if called via that. * * @param phys Physical address base of the memory region if not requesting * anonymous memory. Must be page-aligned. @@ -225,26 +301,27 @@ void z_phys_unmap(uint8_t *virt, size_t size); * space, insufficient physical memory to establish the mapping, * or insufficient memory for paging structures. */ -void *k_mem_map_impl(uintptr_t phys, size_t size, uint32_t flags, bool is_anon); +void *k_mem_map_phys_guard(uintptr_t phys, size_t size, uint32_t flags, bool is_anon); /** - * Un-map mapped memory + * Un-map memory mapped via k_mem_map_phys_guard(). * * This removes the memory mappings for the provided page-aligned region, * and the two guard pages surrounding the region. * - * @see k_mem_unmap() for additional information if called via that. + * This function alters the active page tables in the area reserved + * for the kernel. * - * @see k_mem_phys_unmap() for additional information if called via that. + * @see k_mem_unmap() for additional information if called via that. * - * @note Calling this function on a region which was not mapped to begin - * with is undefined behavior. + * @note Calling this function on a region which was not mapped via + * k_mem_map_phys_guard() to begin with is undefined behavior. * * @param addr Page-aligned memory region base virtual address * @param size Page-aligned memory region size * @param is_anon True if the mapped memory is from anonymous memory. */ -void k_mem_unmap_impl(void *addr, size_t size, bool is_anon); +void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon); #ifdef __cplusplus } diff --git a/include/zephyr/kernel/mm.h b/include/zephyr/kernel/mm.h index 90dd75354835d8..88ad40af42140f 100644 --- a/include/zephyr/kernel/mm.h +++ b/include/zephyr/kernel/mm.h @@ -170,51 +170,7 @@ size_t k_mem_free_get(void); */ static inline void *k_mem_map(size_t size, uint32_t flags) { - return k_mem_map_impl((uintptr_t)NULL, size, flags, true); -} - -/** - * Map a physical memory region into kernel's virtual address space with guard pages. - * - * This function maps a contiguous physical memory region into kernel's - * virtual address space. Given a physical address and a size, return a - * linear address representing the base of where the physical region is mapped - * in the virtual address space for the Zephyr kernel. - * - * This function alters the active page tables in the area reserved - * for the kernel. This function will choose the virtual address - * and return it to the caller. - * - * If user thread access control needs to be managed in any way, do not enable - * K_MEM_PERM_USER flags here; instead manage the region's permissions - * with memory domain APIs after the mapping has been established. Setting - * K_MEM_PERM_USER here will allow all user threads to access this memory - * which is usually undesirable. - * - * Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed. - * - * The returned virtual memory pointer will be page-aligned. The size - * parameter, and any base address for re-mapping purposes must be page- - * aligned. - * - * Note that the allocation includes two guard pages immediately before - * and after the requested region. The total size of the allocation will be - * the requested size plus the size of these two guard pages. - * - * Many K_MEM_MAP_* flags have been implemented to alter the behavior of this - * function, with details in the documentation for these flags. - * - * @param phys Physical address base of the memory region. - * This must be page-aligned. - * @param size Size of the memory mapping. This must be page-aligned. - * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags. - * - * @return The mapped memory location, or NULL if insufficient virtual address - * space or insufficient memory for paging structures. - */ -static inline void *k_mem_phys_map(uintptr_t phys, size_t size, uint32_t flags) -{ - return k_mem_map_impl(phys, size, flags, false); + return k_mem_map_phys_guard((uintptr_t)NULL, size, flags, true); } /** @@ -232,30 +188,7 @@ static inline void *k_mem_phys_map(uintptr_t phys, size_t size, uint32_t flags) */ static inline void k_mem_unmap(void *addr, size_t size) { - k_mem_unmap_impl(addr, size, true); -} - -/** - * Un-map memory mapped via k_mem_phys_map(). - * - * This unmaps a virtual memory region from kernel's virtual address space. - * - * This function alters the active page tables in the area reserved - * for the kernel. - * - * This removes a memory mapping for the provided page-aligned region - * and the guard pages. The kernel may re-use the associated virtual address - * region later. - * - * @note Calling this function on a region which was not mapped via - * k_mem_phys_map() to begin with is undefined behavior. - * - * @param addr Page-aligned memory region base virtual address - * @param size Page-aligned memory region size - */ -static inline void k_mem_phys_unmap(void *addr, size_t size) -{ - k_mem_unmap_impl(addr, size, false); + k_mem_unmap_phys_guard(addr, size, true); } /** diff --git a/include/zephyr/kernel/mm/demand_paging.h b/include/zephyr/kernel/mm/demand_paging.h index f88f5c2067e934..e3c85c98244d66 100644 --- a/include/zephyr/kernel/mm/demand_paging.h +++ b/include/zephyr/kernel/mm/demand_paging.h @@ -229,7 +229,7 @@ __syscall void k_mem_paging_histogram_backing_store_page_out_get( * @param [out] dirty Whether the page to evict is dirty * @return The page frame to evict */ -struct z_page_frame *k_mem_paging_eviction_select(bool *dirty); +struct k_mem_page_frame *k_mem_paging_eviction_select(bool *dirty); /** * Initialization function @@ -258,16 +258,16 @@ void k_mem_paging_eviction_init(void); * contents for later retrieval. The location value must be page-aligned. * * This function may be called multiple times on the same data page. If its - * page frame has its Z_PAGE_FRAME_BACKED bit set, it is expected to return + * page frame has its K_MEM_PAGE_FRAME_BACKED bit set, it is expected to return * the previous backing store location for the data page containing a cached * clean copy. This clean copy may be updated on page-out, or used to * discard clean pages without needing to write out their contents. * * If the backing store is full, some other backing store location which caches * a loaded data page may be selected, in which case its associated page frame - * will have the Z_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). + * will have the K_MEM_PAGE_FRAME_BACKED bit cleared (as it is no longer cached). * - * z_page_frame_to_virt(pf) will indicate the virtual address the page is + * k_mem_page_frame_to_virt(pf) will indicate the virtual address the page is * currently mapped to. Large, sparse backing stores which can contain the * entire address space may simply generate location tokens purely as a * function of that virtual address with no other management necessary. @@ -285,7 +285,7 @@ void k_mem_paging_eviction_init(void); * @return 0 Success * @return -ENOMEM Backing store is full */ -int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, +int k_mem_paging_backing_store_location_get(struct k_mem_page_frame *pf, uintptr_t *location, bool page_fault); @@ -302,9 +302,9 @@ int k_mem_paging_backing_store_location_get(struct z_page_frame *pf, void k_mem_paging_backing_store_location_free(uintptr_t location); /** - * Copy a data page from Z_SCRATCH_PAGE to the specified location + * Copy a data page from K_MEM_SCRATCH_PAGE to the specified location * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * Immediately before this is called, K_MEM_SCRATCH_PAGE will be mapped read-write * to the intended source page frame for the calling context. * * Calls to this and k_mem_paging_backing_store_page_in() will always be @@ -315,9 +315,9 @@ void k_mem_paging_backing_store_location_free(uintptr_t location); void k_mem_paging_backing_store_page_out(uintptr_t location); /** - * Copy a data page from the provided location to Z_SCRATCH_PAGE. + * Copy a data page from the provided location to K_MEM_SCRATCH_PAGE. * - * Immediately before this is called, Z_SCRATCH_PAGE will be mapped read-write + * Immediately before this is called, K_MEM_SCRATCH_PAGE will be mapped read-write * to the intended destination page frame for the calling context. * * Calls to this and k_mem_paging_backing_store_page_out() will always be @@ -331,7 +331,7 @@ void k_mem_paging_backing_store_page_in(uintptr_t location); * Update internal accounting after a page-in * * This is invoked after k_mem_paging_backing_store_page_in() and interrupts - * have been* re-locked, making it safe to access the z_page_frame data. + * have been* re-locked, making it safe to access the k_mem_page_frame data. * The location value will be the same passed to * k_mem_paging_backing_store_page_in(). * @@ -340,14 +340,14 @@ void k_mem_paging_backing_store_page_in(uintptr_t location); * if it is paged out again. This may be a no-op in some implementations. * * If the backing store caches paged-in data pages, this is the appropriate - * time to set the Z_PAGE_FRAME_BACKED bit. The kernel only skips paging + * time to set the K_MEM_PAGE_FRAME_BACKED bit. The kernel only skips paging * out clean data pages if they are noted as clean in the page tables and the - * Z_PAGE_FRAME_BACKED bit is set in their associated page frame. + * K_MEM_PAGE_FRAME_BACKED bit is set in their associated page frame. * * @param pf Page frame that was loaded in * @param location Location of where the loaded data page was retrieved */ -void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, +void k_mem_paging_backing_store_page_finalize(struct k_mem_page_frame *pf, uintptr_t location); /** @@ -360,7 +360,7 @@ void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf, * - Initialize any internal data structures and accounting for the backing * store. * - If the backing store already contains all or some loaded kernel data pages - * at boot time, Z_PAGE_FRAME_BACKED should be appropriately set for their + * at boot time, K_MEM_PAGE_FRAME_BACKED should be appropriately set for their * associated page frames, and any internal accounting set up appropriately. */ void k_mem_paging_backing_store_init(void); diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index baa2046f07c8e0..cf7daff9a6cf79 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -240,8 +240,8 @@ struct z_kernel { #endif #if defined(CONFIG_SMP) && defined(CONFIG_SCHED_IPI_SUPPORTED) - /* Need to signal an IPI at the next scheduling point */ - bool pending_ipi; + /* Identify CPUs to send IPIs to at the next scheduling point */ + atomic_t pending_ipi; #endif }; diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index 8a1db6da081f5b..d860222ffac798 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -292,7 +292,7 @@ extern char lnkr_boot_noinit_size[]; /* lnkr_pinned_start[] and lnkr_pinned_end[] must encapsulate * all the pinned sections as these are used by * the MMU code to mark the physical page frames with - * Z_PAGE_FRAME_PINNED. + * K_MEM_PAGE_FRAME_PINNED. */ extern char lnkr_pinned_start[]; extern char lnkr_pinned_end[]; diff --git a/include/zephyr/linker/linker-tool-gcc.h b/include/zephyr/linker/linker-tool-gcc.h index ab8a3ad7f9aaa9..c2a004b8855c95 100644 --- a/include/zephyr/linker/linker-tool-gcc.h +++ b/include/zephyr/linker/linker-tool-gcc.h @@ -89,7 +89,7 @@ */ #if defined(CONFIG_ARCH_POSIX) #define GROUP_LINK_IN(where) -#elif !defined(Z_VM_KERNEL) +#elif !defined(K_MEM_IS_VM_KERNEL) #define GROUP_LINK_IN(where) > where #endif @@ -113,7 +113,7 @@ */ #if defined(CONFIG_ARCH_POSIX) #define GROUP_ROM_LINK_IN(vregion, lregion) -#elif defined(Z_VM_KERNEL) +#elif defined(K_MEM_IS_VM_KERNEL) #define GROUP_ROM_LINK_IN(vregion, lregion) > vregion AT > lregion #else #define GROUP_ROM_LINK_IN(vregion, lregion) > lregion @@ -133,7 +133,7 @@ */ #if defined(CONFIG_ARCH_POSIX) #define GROUP_DATA_LINK_IN(vregion, lregion) -#elif defined(CONFIG_XIP) || defined(Z_VM_KERNEL) +#elif defined(CONFIG_XIP) || defined(K_MEM_IS_VM_KERNEL) #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion #else #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion @@ -151,7 +151,7 @@ */ #if defined(CONFIG_ARCH_POSIX) #define GROUP_NOLOAD_LINK_IN(vregion, lregion) -#elif defined(Z_VM_KERNEL) +#elif defined(K_MEM_IS_VM_KERNEL) #define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > lregion #elif defined(CONFIG_XIP) #define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > vregion @@ -172,7 +172,7 @@ * @param align Alignment directives, such as SUBALIGN(). ALIGN() itself is * not allowed. May be blank. */ -#ifdef Z_VM_KERNEL +#ifdef K_MEM_IS_VM_KERNEL /* If we have a virtual memory map we need ALIGN_WITH_INPUT in all sections */ #define SECTION_PROLOGUE(name, options, align) \ name options : ALIGN_WITH_INPUT align diff --git a/include/zephyr/linker/llext-sections.ld b/include/zephyr/linker/llext-sections.ld new file mode 100644 index 00000000000000..b8cc32e3d1bf1a --- /dev/null +++ b/include/zephyr/linker/llext-sections.ld @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + + /* + * Special section used by LLEXT if CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID + * is enabled. Declare this section to prevent it from being considered orphan. + * + * This section is used to temporarily save the exported symbols' names in the + * Zephyr ELF for post-processing, but it is not included in the final binary. + * + * NOTE: This section MUST start at address 0, as the post-processing scripts + * assume that the address of any data in this section (i.e., symbol names) is + * strictly equivalent to the offset inside the section. + */ +#ifdef CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID + SECTION_PROLOGUE(llext_exports_strtab, 0 (COPY), ) + { + KEEP(*(llext_exports_strtab)) + } +#endif diff --git a/include/zephyr/llext/elf.h b/include/zephyr/llext/elf.h index 7e8628b37d5b94..b39af854312dae 100644 --- a/include/zephyr/llext/elf.h +++ b/include/zephyr/llext/elf.h @@ -196,6 +196,7 @@ struct elf64_shdr { elf64_xword sh_entsize; }; +#define SHT_NULL 0x0 #define SHT_PROGBITS 0x1 #define SHT_SYMTAB 0x2 #define SHT_STRTAB 0x3 diff --git a/include/zephyr/llext/loader.h b/include/zephyr/llext/loader.h index b8477eb30039f3..7eb49d611bed30 100644 --- a/include/zephyr/llext/loader.h +++ b/include/zephyr/llext/loader.h @@ -68,9 +68,6 @@ struct llext_loader { */ void *(*peek)(struct llext_loader *ldr, size_t pos); - /** Total calculated .data size for relocatable extensions */ - size_t prog_data_size; - /** @cond ignore */ elf_ehdr_t hdr; elf_shdr_t sects[LLEXT_MEM_COUNT]; diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index e42dc37c9efa44..62190ed08e586f 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -27,14 +28,27 @@ extern "C" { * Symbols may be named function or global objects that have been exported * for linking. These constant symbols are useful in the base image * as they may be placed in ROM. + * + * @note When updating this structure, make sure to also update the + * 'scripts/build/llext_prepare_exptab.py' build script. */ struct llext_const_symbol { - /** Name of symbol */ - const char *const name; + /** At build time, we always write to 'name'. + * At runtime, which field is used depends + * on CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID. + */ + union { + /** Name of symbol */ + const char *const name; + + /** Symbol Link Identifier */ + const uintptr_t slid; + }; /** Address of symbol */ const void *const addr; }; +BUILD_ASSERT(sizeof(struct llext_const_symbol) == 2 * sizeof(uintptr_t)); /** * @brief Symbols are named memory addresses @@ -75,10 +89,21 @@ struct llext_symtable { * * @param x Symbol to export to extensions */ +#if defined(CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) +#define EXPORT_SYMBOL(x) \ + static const char Z_GENERIC_SECTION("llext_exports_strtab") __used \ + x ## _sym_name[] = STRINGIFY(x); \ + static const STRUCT_SECTION_ITERABLE(llext_const_symbol, x ## _sym) = { \ + .name = x ## _sym_name, .addr = (const void *)&x, \ + } +#elif defined(CONFIG_LLEXT) #define EXPORT_SYMBOL(x) \ static const STRUCT_SECTION_ITERABLE(llext_const_symbol, x ## _sym) = { \ .name = STRINGIFY(x), .addr = (const void *)&x, \ } +#else +#define EXPORT_SYMBOL(x) +#endif /** * @brief Exports a symbol from an extension to the base image diff --git a/include/zephyr/modem/pipelink.h b/include/zephyr/modem/pipelink.h new file mode 100644 index 00000000000000..efe178861a328a --- /dev/null +++ b/include/zephyr/modem/pipelink.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2024 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifndef ZEPHYR_MODEM_PIPELINK_ +#define ZEPHYR_MODEM_PIPELINK_ + +/** Pipelink event */ +enum modem_pipelink_event { + /** Modem pipe has been connected and can be opened */ + MODEM_PIPELINK_EVENT_CONNECTED = 0, + /** Modem pipe has been disconnected and can't be opened */ + MODEM_PIPELINK_EVENT_DISCONNECTED, +}; + +/** @cond INTERNAL_HIDDEN */ + +/** Forward declaration */ +struct modem_pipelink; + +/** @endcond */ + +/** + * @brief Pipelink callback definition + * @param link Modem pipelink instance + * @param event Modem pipelink event + * @param user_data User data passed to modem_pipelink_attach() + */ +typedef void (*modem_pipelink_callback)(struct modem_pipelink *link, + enum modem_pipelink_event event, + void *user_data); + +/** @cond INTERNAL_HIDDEN */ + +/** Pipelink structure */ +struct modem_pipelink { + struct modem_pipe *pipe; + modem_pipelink_callback callback; + void *user_data; + bool connected; + struct k_spinlock spinlock; +}; + +/** @endcond */ + +/** + * @brief Attach callback to pipelink + * @param link Pipelink instance + * @param callback Pipelink callback + * @param user_data User data passed to pipelink callback + */ +void modem_pipelink_attach(struct modem_pipelink *link, + modem_pipelink_callback callback, + void *user_data); + +/** + * @brief Check whether pipelink pipe is connected + * @param link Pipelink instance + * @retval true if pipe is connected + * @retval false if pipe is not connected + */ +bool modem_pipelink_is_connected(struct modem_pipelink *link); + +/** + * @brief Get pipe from pipelink + * @param link Pipelink instance + * @retval Pointer to pipe if pipelink has been initialized + * @retval NULL if pipelink has not been initialized + */ +struct modem_pipe *modem_pipelink_get_pipe(struct modem_pipelink *link); + +/** + * @brief Clear callback + * @param link Pipelink instance + */ +void modem_pipelink_release(struct modem_pipelink *link); + +/** @cond INTERNAL_HIDDEN */ + +/** Initialize modem pipelink */ +void modem_pipelink_init(struct modem_pipelink *link, struct modem_pipe *pipe); + +/** Notify user of pipelink that pipe has been connected */ +void modem_pipelink_notify_connected(struct modem_pipelink *link); + +/** Notify user of pipelink that pipe has been disconnected */ +void modem_pipelink_notify_disconnected(struct modem_pipelink *link); + +/** @endcond */ + +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief Synthesize pipelink symbol from devicetree node identifier and name + * @param node_id Devicetree node identifier + * @param name Pipelink name + */ +#define MODEM_PIPELINK_DT_SYM(node_id, name) \ + _CONCAT_4(__modem_pipelink_, DT_DEP_ORD(node_id), _, name) + +/** @endcond */ + +/** + * @brief Declare pipelink from devicetree node identifier and name + * @param node_id Devicetree node identifier + * @param name Pipelink name + */ +#define MODEM_PIPELINK_DT_DECLARE(node_id, name) \ + extern struct modem_pipelink MODEM_PIPELINK_DT_SYM(node_id, name) + +/** + * @brief Define pipelink from devicetree node identifier and name + * @param node_id Devicetree node identifier + * @param name Pipelink name + */ +#define MODEM_PIPELINK_DT_DEFINE(node_id, name) \ + struct modem_pipelink MODEM_PIPELINK_DT_SYM(node_id, name) + +/** + * @brief Get pointer to pipelink from devicetree node identifier and name + * @param node_id Devicetree node identifier + * @param name Pipelink name + */ +#define MODEM_PIPELINK_DT_GET(node_id, name) \ + (&MODEM_PIPELINK_DT_SYM(node_id, name)) + +/** + * @brief Device driver instance variants of MODEM_PIPELINK_DT macros + * @{ + */ + +#define MODEM_PIPELINK_DT_INST_DECLARE(inst, name) \ + MODEM_PIPELINK_DT_DECLARE(DT_DRV_INST(inst), name) + +#define MODEM_PIPELINK_DT_INST_DEFINE(inst, name) \ + MODEM_PIPELINK_DT_DEFINE(DT_DRV_INST(inst), name) + +#define MODEM_PIPELINK_DT_INST_GET(inst, name) \ + MODEM_PIPELINK_DT_GET(DT_DRV_INST(inst), name) + +/** @} */ + +#endif /* ZEPHYR_MODEM_PIPELINK_ */ diff --git a/include/zephyr/net/dhcpv4.h b/include/zephyr/net/dhcpv4.h index c31d5f91417822..925c4e13568ac5 100644 --- a/include/zephyr/net/dhcpv4.h +++ b/include/zephyr/net/dhcpv4.h @@ -40,6 +40,7 @@ enum net_dhcpv4_state { NET_DHCPV4_RENEWING, NET_DHCPV4_REBINDING, NET_DHCPV4_BOUND, + NET_DHCPV4_DECLINE, } __packed; /** @endcond */ diff --git a/include/zephyr/net/ipv4_autoconf.h b/include/zephyr/net/ipv4_autoconf.h index 3b686faffca5a5..8d1873b439f9ed 100644 --- a/include/zephyr/net/ipv4_autoconf.h +++ b/include/zephyr/net/ipv4_autoconf.h @@ -14,12 +14,44 @@ /** Current state of IPv4 Autoconfiguration */ enum net_ipv4_autoconf_state { NET_IPV4_AUTOCONF_INIT, /**< Initialization state */ - NET_IPV4_AUTOCONF_PROBE, /**< Probing state */ - NET_IPV4_AUTOCONF_ANNOUNCE, /**< Announce state */ NET_IPV4_AUTOCONF_ASSIGNED, /**< Assigned state */ NET_IPV4_AUTOCONF_RENEW, /**< Renew state */ }; +struct net_if; + +/** + * @brief Start IPv4 autoconfiguration RFC 3927: IPv4 Link Local + * + * @details Start IPv4 IP autoconfiguration + * + * @param iface A valid pointer on an interface + */ +#if defined(CONFIG_NET_IPV4_AUTO) +void net_ipv4_autoconf_start(struct net_if *iface); +#else +static inline void net_ipv4_autoconf_start(struct net_if *iface) +{ + ARG_UNUSED(iface); +} +#endif + +/** + * @brief Reset autoconf process + * + * @details Reset IPv4 IP autoconfiguration + * + * @param iface A valid pointer on an interface + */ +#if defined(CONFIG_NET_IPV4_AUTO) +void net_ipv4_autoconf_reset(struct net_if *iface); +#else +static inline void net_ipv4_autoconf_reset(struct net_if *iface) +{ + ARG_UNUSED(iface); +} +#endif + /** @cond INTERNAL_HIDDEN */ /** @@ -28,7 +60,7 @@ enum net_ipv4_autoconf_state { #if defined(CONFIG_NET_IPV4_AUTO) void net_ipv4_autoconf_init(void); #else -#define net_ipv4_autoconf_init(...) +static inline void net_ipv4_autoconf_init(void) { } #endif /** @endcond */ diff --git a/include/zephyr/net/net_context.h b/include/zephyr/net/net_context.h index 8e85af1fde97a1..10327dc599597e 100644 --- a/include/zephyr/net/net_context.h +++ b/include/zephyr/net/net_context.h @@ -359,6 +359,10 @@ __net_socket struct net_context { * see RFC 5014 for details. */ uint16_t addr_preferences; +#endif +#if defined(CONFIG_NET_CONTEXT_TIMESTAMPING) + /** Enable RX, TX or both timestamps of packets send through sockets. */ + uint8_t timestamping; #endif } options; @@ -1285,6 +1289,7 @@ enum net_context_option { NET_OPT_UNICAST_HOP_LIMIT = 15, /**< IPv6 unicast hop limit */ NET_OPT_TTL = 16, /**< IPv4 unicast TTL */ NET_OPT_ADDR_PREFERENCES = 17, /**< IPv6 address preference */ + NET_OPT_TIMESTAMPING = 18, /**< Packet timestamping */ }; /** diff --git a/include/zephyr/net/net_event.h b/include/zephyr/net/net_event.h index b149934f8bcacf..9bcba06be76eb7 100644 --- a/include/zephyr/net/net_event.h +++ b/include/zephyr/net/net_event.h @@ -96,6 +96,9 @@ enum net_event_ipv4_cmd { NET_EVENT_IPV4_CMD_DHCP_STOP, NET_EVENT_IPV4_CMD_MCAST_JOIN, NET_EVENT_IPV4_CMD_MCAST_LEAVE, + NET_EVENT_IPV4_CMD_ACD_SUCCEED, + NET_EVENT_IPV4_CMD_ACD_FAILED, + NET_EVENT_IPV4_CMD_ACD_CONFLICT, }; /* L4 network events */ @@ -109,6 +112,10 @@ enum net_event_ipv4_cmd { enum net_event_l4_cmd { NET_EVENT_L4_CMD_CONNECTED = 1, NET_EVENT_L4_CMD_DISCONNECTED, + NET_EVENT_L4_CMD_IPV4_CONNECTED, + NET_EVENT_L4_CMD_IPV4_DISCONNECTED, + NET_EVENT_L4_CMD_IPV6_CONNECTED, + NET_EVENT_L4_CMD_IPV6_DISCONNECTED, NET_EVENT_L4_CMD_DNS_SERVER_ADD, NET_EVENT_L4_CMD_DNS_SERVER_DEL, NET_EVENT_L4_CMD_HOSTNAME_CHANGED, @@ -274,6 +281,21 @@ enum net_event_l4_cmd { #define NET_EVENT_IPV4_MCAST_LEAVE \ (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_MCAST_LEAVE) +/** Event emitted when an IPv4 address conflict detection succeeds. */ +#define NET_EVENT_IPV4_ACD_SUCCEED \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ACD_SUCCEED) + +/** Event emitted when an IPv4 address conflict detection fails. */ +#define NET_EVENT_IPV4_ACD_FAILED \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ACD_FAILED) + +/** Event emitted when an IPv4 address conflict was detected after the address + * was confirmed as safe to use. It's up to the application to determine on + * how to act in such case. + */ +#define NET_EVENT_IPV4_ACD_CONFLICT \ + (_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ACD_CONFLICT) + /** Event emitted when the system is considered to be connected. * The connected in this context means that the network interface is up, * and the interface has either IPv4 or IPv6 address assigned to it. @@ -289,6 +311,23 @@ enum net_event_l4_cmd { #define NET_EVENT_L4_DISCONNECTED \ (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_DISCONNECTED) + +/** Event raised when IPv4 network connectivity is available. */ +#define NET_EVENT_L4_IPV4_CONNECTED \ + (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_IPV4_CONNECTED) + +/** Event emitted when IPv4 network connectivity is lost. */ +#define NET_EVENT_L4_IPV4_DISCONNECTED \ + (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_IPV4_DISCONNECTED) + +/** Event emitted when IPv6 network connectivity is available. */ +#define NET_EVENT_L4_IPV6_CONNECTED \ + (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_IPV6_CONNECTED) + +/** Event emitted when IPv6 network connectivity is lost. */ +#define NET_EVENT_L4_IPV6_DISCONNECTED \ + (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_IPV6_DISCONNECTED) + /** Event emitted when a DNS server is added to the system. */ #define NET_EVENT_DNS_SERVER_ADD \ (_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_DNS_SERVER_ADD) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 0b69dde2fe70d0..05cdc7155f4a13 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -62,11 +62,6 @@ struct net_if_addr { struct net_timeout lifetime; #endif -#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6) - /** Duplicate address detection (DAD) timer */ - sys_snode_t dad_node; - uint32_t dad_start; -#endif /** How the IP address was set */ enum net_addr_type addr_type; @@ -90,14 +85,38 @@ struct net_if_addr { */ int32_t addr_timeout; #endif +#endif /* CONFIG_NET_NATIVE_IPV6 */ + union { #if defined(CONFIG_NET_IPV6_DAD) - /** How many times we have done DAD */ - uint8_t dad_count; - /* What interface the DAD is running */ + struct { + /** Duplicate address detection (DAD) timer */ + sys_snode_t dad_node; + uint32_t dad_start; + + /** How many times we have done DAD */ + uint8_t dad_count; + }; +#endif /* CONFIG_NET_IPV6_DAD */ +#if defined(CONFIG_NET_IPV4_ACD) + struct { + /** Address conflict detection (ACD) timer. */ + sys_snode_t acd_node; + k_timepoint_t acd_timeout; + + /** ACD probe/announcement counter. */ + uint8_t acd_count; + + /** ACD status. */ + uint8_t acd_state; + }; +#endif /* CONFIG_NET_IPV4_ACD */ + }; + +#if defined(CONFIG_NET_IPV6_DAD) || defined(CONFIG_NET_IPV4_ACD) + /** What interface the conflict detection is running */ uint8_t ifindex; #endif -#endif /* CONFIG_NET_NATIVE_IPV6 */ /** Is the IP address valid forever */ uint8_t is_infinite : 1; @@ -438,6 +457,11 @@ struct net_if_ipv4 { /** IPv4 time-to-live for multicast packets */ uint8_t mcast_ttl; + +#if defined(CONFIG_NET_IPV4_ACD) + /** IPv4 conflict count. */ + uint8_t conflict_cnt; +#endif }; #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4) @@ -495,36 +519,15 @@ struct net_if_dhcpv4 { #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4) struct net_if_ipv4_autoconf { - /** Used for timer lists */ - sys_snode_t node; - /** Backpointer to correct network interface */ struct net_if *iface; - /** Timer start */ - int64_t timer_start; - - /** Time for INIT, DISCOVER, REQUESTING, RENEWAL */ - uint32_t timer_timeout; - - /** Current IP addr */ - struct in_addr current_ip; - /** Requested IP addr */ struct in_addr requested_ip; /** IPV4 Autoconf state in the process of network address allocation. */ enum net_ipv4_autoconf_state state; - - /** Number of sent probe requests */ - uint8_t probe_cnt; - - /** Number of sent announcements */ - uint8_t announce_cnt; - - /** Incoming conflict count */ - uint8_t conflict_cnt; }; #endif /* CONFIG_NET_IPV4_AUTO */ diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 4c5b592fde4ab6..a2bf19eda49f05 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -167,8 +167,8 @@ struct net_pkt { /* bitfield byte alignment boundary */ -#if defined(CONFIG_NET_IPV4_AUTO) - uint8_t ipv4_auto_arp_msg : 1; /* Is this pkt IPv4 autoconf ARP +#if defined(CONFIG_NET_IPV4_ACD) + uint8_t ipv4_acd_arp_msg : 1; /* Is this pkt IPv4 conflict detection ARP * message. * Note: family needs to be * AF_INET. @@ -197,6 +197,10 @@ struct net_pkt { */ #if defined(CONFIG_NET_IP_FRAGMENT) uint8_t ip_reassembled : 1; /* Packet is a reassembled IP packet. */ +#endif +#if defined(CONFIG_NET_PKT_TIMESTAMP) + uint8_t tx_timestamping : 1; /** Timestamp transmitted packet */ + uint8_t rx_timestamping : 1; /** Timestamp received packet */ #endif /* bitfield byte alignment boundary */ @@ -389,6 +393,38 @@ static inline void net_pkt_set_ptp(struct net_pkt *pkt, bool is_ptp) pkt->ptp_pkt = is_ptp; } +static inline bool net_pkt_is_tx_timestamping(struct net_pkt *pkt) +{ +#if defined(CONFIG_NET_PKT_TIMESTAMP) + return !!(pkt->tx_timestamping); +#else + return false; +#endif +} + +static inline void net_pkt_set_tx_timestamping(struct net_pkt *pkt, bool is_timestamping) +{ +#if defined(CONFIG_NET_PKT_TIMESTAMP) + pkt->tx_timestamping = is_timestamping; +#endif +} + +static inline bool net_pkt_is_rx_timestamping(struct net_pkt *pkt) +{ +#if defined(CONFIG_NET_PKT_TIMESTAMP) + return !!(pkt->rx_timestamping); +#else + return false; +#endif +} + +static inline void net_pkt_set_rx_timestamping(struct net_pkt *pkt, bool is_timestamping) +{ +#if defined(CONFIG_NET_PKT_TIMESTAMP) + pkt->rx_timestamping = is_timestamping; +#endif +} + static inline bool net_pkt_is_captured(struct net_pkt *pkt) { return !!(pkt->captured); @@ -1206,32 +1242,32 @@ static inline void net_pkt_set_ll_proto_type(struct net_pkt *pkt, uint16_t type) pkt->ll_proto_type = type; } -#if defined(CONFIG_NET_IPV4_AUTO) -static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt) +#if defined(CONFIG_NET_IPV4_ACD) +static inline bool net_pkt_ipv4_acd(struct net_pkt *pkt) { - return !!(pkt->ipv4_auto_arp_msg); + return !!(pkt->ipv4_acd_arp_msg); } -static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt, - bool is_auto_arp_msg) +static inline void net_pkt_set_ipv4_acd(struct net_pkt *pkt, + bool is_acd_arp_msg) { - pkt->ipv4_auto_arp_msg = is_auto_arp_msg; + pkt->ipv4_acd_arp_msg = is_acd_arp_msg; } -#else /* CONFIG_NET_IPV4_AUTO */ -static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt) +#else /* CONFIG_NET_IPV4_ACD */ +static inline bool net_pkt_ipv4_acd(struct net_pkt *pkt) { ARG_UNUSED(pkt); return false; } -static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt, - bool is_auto_arp_msg) +static inline void net_pkt_set_ipv4_acd(struct net_pkt *pkt, + bool is_acd_arp_msg) { ARG_UNUSED(pkt); - ARG_UNUSED(is_auto_arp_msg); + ARG_UNUSED(is_acd_arp_msg); } -#endif /* CONFIG_NET_IPV4_AUTO */ +#endif /* CONFIG_NET_IPV4_ACD */ #if defined(CONFIG_NET_LLDP) static inline bool net_pkt_is_lldp(struct net_pkt *pkt) diff --git a/include/zephyr/net/ptp.h b/include/zephyr/net/ptp.h new file mode 100644 index 00000000000000..d57c47e7c6c391 --- /dev/null +++ b/include/zephyr/net/ptp.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 BayLibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public functions for the Precision Time Protocol. + * + * References are to version 2019 of IEEE 1588, ("PTP") + */ + +#ifndef ZEPHYR_INCLUDE_NET_PTP_H_ +#define ZEPHYR_INCLUDE_NET_PTP_H_ + +/** + * @brief Precision Time Protocol (PTP) support + * @defgroup ptp PTP support + * @ingroup networking + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PTP_MAJOR_VERSION 2 /**< Major PTP Version */ +#define PTP_MINOR_VERSION 1 /**< Minor PTP Version */ + +#define PTP_VERSION (PTP_MINOR_VERSION << 4 | PTP_MAJOR_VERSION) /**< PTP version IEEE-1588:2019 */ + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_PTP_H_ */ diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index d8983e082ef3ef..9af729faecd85a 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -1163,8 +1163,9 @@ struct ifreq { /** Socket accepts incoming connections (ignored, for compatibility) */ #define SO_ACCEPTCONN 30 -/** Timestamp TX packets */ +/** Timestamp TX RX or both packets. Supports multiple timestamp sources. */ #define SO_TIMESTAMPING 37 + /** Protocol used with the socket */ #define SO_PROTOCOL 38 @@ -1179,6 +1180,18 @@ struct ifreq { /** Socket TX time (same as SO_TXTIME) */ #define SCM_TXTIME SO_TXTIME +/** Timestamp generation flags */ + +/** Request RX timestamps generated by network adapter. */ +#define SOF_TIMESTAMPING_RX_HARDWARE BIT(0) +/** + * Request TX timestamps generated by network adapter. + * This can be enabled via socket option or control messages. + */ +#define SOF_TIMESTAMPING_TX_HARDWARE BIT(1) + +/** */ + /** @} */ /** diff --git a/include/zephyr/net/socket_select.h b/include/zephyr/net/socket_select.h index 23034d31d7903a..5fca2950d6a596 100644 --- a/include/zephyr/net/socket_select.h +++ b/include/zephyr/net/socket_select.h @@ -28,7 +28,7 @@ extern "C" { /** Socket file descriptor set. */ typedef struct zsock_fd_set { - uint32_t bitset[(CONFIG_POSIX_MAX_FDS + 31) / 32]; + uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32]; } zsock_fd_set; /** diff --git a/include/zephyr/pm/policy.h b/include/zephyr/pm/policy.h index e77004bbbe8fda..6fe91663bb6c71 100644 --- a/include/zephyr/pm/policy.h +++ b/include/zephyr/pm/policy.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -219,6 +220,32 @@ void pm_policy_event_update(struct pm_policy_event *evt, uint32_t time_us); */ void pm_policy_event_unregister(struct pm_policy_event *evt); +/** + * @brief Increase power state locks. + * + * Set power state locks in all power states that disable power in the given + * device. + * + * @param dev Device reference. + * + * @see pm_policy_device_power_lock_put() + * @see pm_policy_state_lock_get() + */ +void pm_policy_device_power_lock_get(const struct device *dev); + +/** + * @brief Decrease power state locks. + * + * Remove power state locks in all power states that disable power in the given + * device. + * + * @param dev Device reference. + * + * @see pm_policy_device_power_lock_get() + * @see pm_policy_state_lock_put() + */ +void pm_policy_device_power_lock_put(const struct device *dev); + #else static inline void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id) { @@ -278,6 +305,17 @@ static inline void pm_policy_event_unregister(struct pm_policy_event *evt) { ARG_UNUSED(evt); } + +static inline void pm_policy_device_power_lock_get(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static inline void pm_policy_device_power_lock_put(const struct device *dev) +{ + ARG_UNUSED(dev); +} + #endif /* CONFIG_PM */ /** diff --git a/include/zephyr/pm/state.h b/include/zephyr/pm/state.h index cc3878794113d4..87363ea27d2e90 100644 --- a/include/zephyr/pm/state.h +++ b/include/zephyr/pm/state.h @@ -134,12 +134,22 @@ struct pm_state_info { * substate-id = <2>; * min-residency-us = <20000>; * exit-latency-us = <200>; + * zephyr,pm-device-disabled; * }; * }; * @endcode */ uint8_t substate_id; + /** + * Whether or not this state triggers device power management. + * + * When this property is false the power management subsystem + * will suspend devices before entering this state and will + * properly resume them when leaving it. + */ + bool pm_device_disabled; + /** * Minimum residency duration in microseconds. It is the minimum * time for a given idle state to be worthwhile energywise. @@ -156,6 +166,24 @@ struct pm_state_info { uint32_t exit_latency_us; }; +/** + * Power state information needed to lock a power state. + */ +struct pm_state_constraint { + /** + * Power management state + * + * @see pm_state + **/ + enum pm_state state; + /** + * Power management sub-state + * + * @see pm_state + **/ + uint8_t substate_id; +}; + /** @cond INTERNAL_HIDDEN */ /** @@ -209,6 +237,7 @@ struct pm_state_info { .substate_id = DT_PROP_OR(node_id, substate_id, 0), \ .min_residency_us = DT_PROP_OR(node_id, min_residency_us, 0), \ .exit_latency_us = DT_PROP_OR(node_id, exit_latency_us, 0), \ + .pm_device_disabled = DT_PROP(node_id, zephyr_pm_device_disabled), \ } /** @@ -260,6 +289,7 @@ struct pm_state_info { * power-state-name = "suspend-to-ram"; * min-residency-us = <50000>; * exit-latency-us = <500>; + * zephyr,pm-device-disabled; * }; * }; * }; diff --git a/include/zephyr/posix/dirent.h b/include/zephyr/posix/dirent.h index 43c68983ebb73e..12f5d44380d9b0 100644 --- a/include/zephyr/posix/dirent.h +++ b/include/zephyr/posix/dirent.h @@ -9,7 +9,7 @@ #include #include "posix_types.h" -#ifdef CONFIG_POSIX_FS +#ifdef CONFIG_POSIX_FILE_SYSTEM #include #ifdef __cplusplus @@ -32,6 +32,6 @@ struct dirent *readdir(DIR *dirp); } #endif -#endif /* CONFIG_POSIX_FS */ +#endif /* CONFIG_POSIX_FILE_SYSTEM */ #endif /* ZEPHYR_INCLUDE_POSIX_DIRENT_H_ */ diff --git a/include/zephyr/posix/mqueue.h b/include/zephyr/posix/mqueue.h index dbaa6d42a537d5..aac03426da442e 100644 --- a/include/zephyr/posix/mqueue.h +++ b/include/zephyr/posix/mqueue.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_POSIX_MQUEUE_H_ -#define ZEPHYR_INCLUDE_POSIX_MQUEUE_H_ +#ifndef ZEPHYR_INCLUDE_POSIX_MESSAGE_PASSING_H_ +#define ZEPHYR_INCLUDE_POSIX_MESSAGE_PASSING_H_ #include #include @@ -47,4 +47,4 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification); } #endif -#endif /* ZEPHYR_INCLUDE_POSIX_MQUEUE_H_ */ +#endif /* ZEPHYR_INCLUDE_POSIX_MESSAGE_PASSING_H_ */ diff --git a/include/zephyr/posix/posix_features.h b/include/zephyr/posix/posix_features.h new file mode 100644 index 00000000000000..5faadb66c05db1 --- /dev/null +++ b/include/zephyr/posix/posix_features.h @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2024 BayLibre SAS + * Copyright (c) 2024 Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef INCLUDE_ZEPHYR_POSIX_POSIX_FEATURES_H_ +#define INCLUDE_ZEPHYR_POSIX_POSIX_FEATURES_H_ + +#include /* CONFIG_* */ +#include /* COND_CODE_1() */ + +/* + * POSIX Application Environment Profiles (AEP - IEEE Std 1003.13-2003) + */ + +#ifdef CONFIG_POSIX_AEP_REALTIME_MINIMAL +#define _POSIX_AEP_REALTIME_MINIMAL 200312L +#endif + +#ifdef CONFIG_POSIX_AEP_REALTIME_CONTROLLER +#define _POSIX_AEP_REALTIME_CONTROLLER 200312L +#endif + +#ifdef CONFIG_POSIX_AEP_REALTIME_DEDICATED +#define _POSIX_AEP_REALTIME_DEDICATED 200312L +#endif + +/* + * POSIX System Interfaces + */ + +#define _POSIX_VERSION 200809L + +#define _POSIX_CHOWN_RESTRICTED (0) +#define _POSIX_NO_TRUNC (0) +#define _POSIX_VDISABLE ('\0') + +/* #define _POSIX_ADVISORY_INFO (-1L) */ + +#ifdef CONFIG_POSIX_ASYNCHRONOUS_IO +#define _POSIX_ASYNCHRONOUS_IO _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_BARRIERS +#define _POSIX_BARRIERS _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_CLOCK_SELECTION +#define _POSIX_CLOCK_SELECTION _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_CPUTIME +#define _POSIX_CPUTIME _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_FSYNC +#define _POSIX_FSYNC _POSIX_VERSION +#endif + +#ifdef CONFIG_NET_IPV6 +#define _POSIX_IPV6 _POSIX_VERSION +#endif + +/* #define _POSIX_JOB_CONTROL (-1L) */ +/* #define _POSIX_MAPPED_FILES (-1L) */ +/* #define _POSIX_MEMLOCK (-1L) */ +/* #define _POSIX_MEMLOCK_RANGE (-1L) */ +/* #define _POSIX_MEMORY_PROTECTION (-1L) */ + +#ifdef CONFIG_POSIX_MESSAGE_PASSING +#define _POSIX_MESSAGE_PASSING _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_MONOTONIC_CLOCK +#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION +#endif + +/* #define _POSIX_PRIORITIZED_IO (-1L) */ + +#ifdef CONFIG_POSIX_PRIORITY_SCHEDULING +#define _POSIX_PRIORITY_SCHEDULING _POSIX_VERSION +#endif + +#ifdef CONFIG_NET_SOCKETS_PACKET +#define _POSIX_RAW_SOCKETS _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION +#endif + +/* #define _POSIX_REALTIME_SIGNALS (-1L) */ +/* #define _POSIX_REGEXP (-1L) */ +/* #define _POSIX_SAVED_IDS (-1L) */ + +#ifdef CONFIG_POSIX_SEMAPHORES +#define _POSIX_SEMAPHORES _POSIX_VERSION +#endif + +/* #define _POSIX_SHARED_MEMORY_OBJECTS (-1L) */ +/* #define _POSIX_SHELL (-1L) */ +/* #define _POSIX_SPAWN (-1L) */ + +#ifdef CONFIG_POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS _POSIX_VERSION +#endif + +/* #define _POSIX_SPORADIC_SERVER (-1L) */ +/* #define _POSIX_SYNCHRONIZED_IO (-1L) */ + +#ifdef CONFIG_POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_THREAD_CPUTIME +#define _POSIX_THREAD_CPUTIME _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION +#endif + +/* #define _POSIX_THREAD_PROCESS_SHARED (-1L) */ +/* #define _POSIX_THREAD_ROBUST_PRIO_INHERIT (-1L) */ +/* #define _POSIX_THREAD_ROBUST_PRIO_PROTECT (-1L) */ + +#ifdef CONFIG_POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION +#endif + +/* #define _POSIX_THREAD_SPORADIC_SERVER (-1L) */ + +#ifdef CONFIG_POSIX_THREADS +#ifndef _POSIX_THREADS +#define _POSIX_THREADS _POSIX_VERSION +#endif +#endif + +#ifdef CONFIG_POSIX_TIMEOUTS +#define _POSIX_TIMEOUTS _POSIX_VERSION +#endif + +#ifdef CONFIG_POSIX_TIMERS +#define _POSIX_TIMERS _POSIX_VERSION +#endif + +/* #define _POSIX_TRACE (-1L) */ +/* #define _POSIX_TRACE_EVENT_FILTER (-1L) */ +/* #define _POSIX_TRACE_INHERIT (-1L) */ +/* #define _POSIX_TRACE_LOG (-1L) */ +/* #define _POSIX_TYPED_MEMORY_OBJECTS (-1L) */ + +/* + * POSIX v6 Options + */ +/* #define _POSIX_V6_ILP32_OFF32 (-1L) */ +/* #define _POSIX_V6_ILP32_OFFBIG (-1L) */ +/* #define _POSIX_V6_LP64_OFF64 (-1L) */ +/* #define _POSIX_V6_LPBIG_OFFBIG (-1L) */ + +/* + * POSIX v7 Options + */ +/* #define _POSIX_V7_ILP32_OFF32 (-1L) */ +/* #define _POSIX_V7_ILP32_OFFBIG (-1L) */ +/* #define _POSIX_V7_LP64_OFF64 (-1L) */ +/* #define _POSIX_V7_LPBIG_OFFBIG (-1L) */ + +/* + * POSIX2 Options + */ +#define _POSIX2_VERSION _POSIX_VERSION +#define _POSIX2_C_BIND _POSIX2_VERSION +#define _POSIX2_C_DEV _POSIX2_VERSION +/* #define _POSIX2_CHAR_TERM (-1L) */ +/* #define _POSIX2_FORT_DEV (-1L) */ +/* #define _POSIX2_FORT_RUN (-1L) */ +/* #define _POSIX2_LOCALEDEF (-1L) */ +/* #define _POSIX2_PBS (-1L) */ +/* #define _POSIX2_PBS_ACCOUNTING (-1L) */ +/* #define _POSIX2_PBS_CHECKPOINT (-1L) */ +/* #define _POSIX2_PBS_LOCATE (-1L) */ +/* #define _POSIX2_PBS_MESSAGE (-1L) */ +/* #define _POSIX2_PBS_TRACK (-1L) */ +/* #define _POSIX2_SW_DEV (-1L) */ +/* #define _POSIX2_UPE (-1L) */ + +/* + * X/Open System Interfaces + */ +#define _XOPEN_VERSION 700 +/* #define _XOPEN_CRYPT (-1L) */ +/* #define _XOPEN_ENH_I18N (-1L) */ +/* #define _XOPEN_REALTIME (-1L) */ +/* #define _XOPEN_REALTIME_THREADS (-1L) */ +/* #define _XOPEN_SHM (-1L) */ + +#ifdef CONFIG_XOPEN_STREAMS +#define _XOPEN_STREAMS _XOPEN_VERSION +#endif + +/* #define _XOPEN_UNIX (-1L) */ +/* #define _XOPEN_UUCP (-1L) */ + +/* Maximum values */ +#define _POSIX_CLOCKRES_MIN (20000000L) + +/* Minimum values */ +#define _POSIX_AIO_LISTIO_MAX (2) +#define _POSIX_AIO_MAX (1) +#define _POSIX_ARG_MAX (4096) +#define _POSIX_CHILD_MAX (25) +#define _POSIX_DELAYTIMER_MAX \ + COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_DELAYTIMER_MAX), (0)) +#define _POSIX_HOST_NAME_MAX \ + COND_CODE_1(CONFIG_POSIX_NETWORKING, (CONFIG_POSIX_HOST_NAME_MAX), (0)) +#define _POSIX_LINK_MAX (8) +#define _POSIX_LOGIN_NAME_MAX (9) +#define _POSIX_MAX_CANON (255) +#define _POSIX_MAX_INPUT (255) +#define _POSIX_MQ_OPEN_MAX \ + COND_CODE_1(CONFIG_POSIX_MESSAGE_PASSING, (CONFIG_POSIX_MQ_OPEN_MAX), (0)) +#define _POSIX_MQ_PRIO_MAX (32) +#define _POSIX_NAME_MAX (14) +#define _POSIX_NGROUPS_MAX (8) +#define _POSIX_OPEN_MAX CONFIG_POSIX_OPEN_MAX +#define _POSIX_PATH_MAX (256) +#define _POSIX_PIPE_BUF (512) +#define _POSIX_RE_DUP_MAX (255) +#define _POSIX_RTSIG_MAX \ + COND_CODE_1(CONFIG_POSIX_REALTIME_SIGNALS, (CONFIG_POSIX_RTSIG_MAX), (0)) +#define _POSIX_SEM_NSEMS_MAX \ + COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_NSEMS_MAX), (0)) +#define _POSIX_SEM_VALUE_MAX \ + COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (CONFIG_POSIX_SEM_VALUE_MAX), (0)) +#define _POSIX_SIGQUEUE_MAX (32) +#define _POSIX_SSIZE_MAX (32767) +#define _POSIX_SS_REPL_MAX (4) +#define _POSIX_STREAM_MAX (8) +#define _POSIX_SYMLINK_MAX (255) +#define _POSIX_SYMLOOP_MAX (8) +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS (4) +#define _POSIX_THREAD_KEYS_MAX \ + COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_KEYS_MAX), (0)) +#define _POSIX_THREAD_THREADS_MAX \ + COND_CODE_1(CONFIG_POSIX_THREADS, (CONFIG_POSIX_THREAD_THREADS_MAX), (0)) +#define _POSIX_TIMER_MAX \ + COND_CODE_1(CONFIG_POSIX_TIMERS, (CONFIG_POSIX_TIMER_MAX), (0)) +#define _POSIX_TRACE_EVENT_NAME_MAX (30) +#define _POSIX_TRACE_NAME_MAX (8) +#define _POSIX_TRACE_SYS_MAX (8) +#define _POSIX_TRACE_USER_EVENT_MAX (32) +#define _POSIX_TTY_NAME_MAX (9) +#define _POSIX_TZNAME_MAX (6) +#define _POSIX2_BC_BASE_MAX (99) +#define _POSIX2_BC_DIM_MAX (2048) +#define _POSIX2_BC_SCALE_MAX (99) +#define _POSIX2_BC_STRING_MAX (1000) +#define _POSIX2_CHARCLASS_NAME_MAX (14) +#define _POSIX2_COLL_WEIGHTS_MAX (2) +#define _POSIX2_EXPR_NEST_MAX (32) +#define _POSIX2_LINE_MAX (2048) +#define _XOPEN_IOV_MAX (16) +#define _XOPEN_NAME_MAX (255) +#define _XOPEN_PATH_MAX (1024) + +/* Other invariant values */ +#define NL_LANGMAX (14) +#define NL_MSGMAX (32767) +#define NL_SETMAX (255) +#define NL_TEXTMAX (_POSIX2_LINE_MAX) +#define NZERO (20) + +/* Runtime invariant values */ +#define AIO_LISTIO_MAX _POSIX_AIO_LISTIO_MAX +#define AIO_MAX _POSIX_AIO_MAX +#define AIO_PRIO_DELTA_MAX (0) +#define DELAYTIMER_MAX _POSIX_DELAYTIMER_MAX +#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX +#define MQ_OPEN_MAX _POSIX_MQ_OPEN_MAX +#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX + +#ifndef ATEXIT_MAX +#define ATEXIT_MAX 8 +#endif + +#ifndef PAGE_SIZE +#define PAGE_SIZE BIT(CONFIG_POSIX_PAGE_SIZE_BITS) +#endif + +#ifndef PAGESIZE +#define PAGESIZE PAGE_SIZE +#endif + +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX +#define PTHREAD_THREADS_MAX _POSIX_THREAD_THREADS_MAX +#define RTSIG_MAX _POSIX_RTSIG_MAX +#define SEM_NSEMS_MAX _POSIX_SEM_NSEMS_MAX +#define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX +#define SIGQUEUE_MAX _POSIX_SIGQUEUE_MAX +#define STREAM_MAX _POSIX_STREAM_MAX +#define SYMLOOP_MAX _POSIX_SYMLOOP_MAX +#define TIMER_MAX _POSIX_TIMER_MAX +#define TTY_NAME_MAX _POSIX_TTY_NAME_MAX +#define TZNAME_MAX _POSIX_TZNAME_MAX + +/* Pathname variable values */ +#define FILESIZEBITS (32) +#define POSIX_ALLOC_SIZE_MIN (256) +#define POSIX_REC_INCR_XFER_SIZE (1024) +#define POSIX_REC_MAX_XFER_SIZE (32767) +#define POSIX_REC_MIN_XFER_SIZE (1) +#define POSIX_REC_XFER_ALIGN (4) +#define SYMLINK_MAX _POSIX_SYMLINK_MAX + +#endif /* INCLUDE_ZEPHYR_POSIX_POSIX_FEATURES_H_ */ diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 7cd0f7e1160921..f2723d68d76a69 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -417,7 +417,7 @@ int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope); int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope); int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); -#ifdef CONFIG_PTHREAD_IPC +#ifdef CONFIG_POSIX_THREADS int pthread_once(pthread_once_t *once, void (*initFunc)(void)); #endif FUNC_NORETURN void pthread_exit(void *retval); @@ -502,7 +502,7 @@ int pthread_setname_np(pthread_t thread, const char *name); */ int pthread_getname_np(pthread_t thread, char *name, size_t len); -#ifdef CONFIG_PTHREAD_IPC +#ifdef CONFIG_POSIX_THREADS /** * @brief Destroy a pthread_spinlock_t. diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index 3bbdee7317aca7..165050f2ded928 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -7,6 +7,7 @@ #define ZEPHYR_INCLUDE_POSIX_SIGNAL_H_ #include "posix_types.h" +#include "posix_features.h" #ifdef __cplusplus extern "C" { @@ -44,7 +45,6 @@ extern "C" { /* 30 not used */ #define SIGSYS 31 /**< Bad system call */ -#define RTSIG_MAX CONFIG_POSIX_RTSIG_MAX #define SIGRTMIN 32 #define SIGRTMAX (SIGRTMIN + RTSIG_MAX) #define _NSIG (SIGRTMAX + 1) @@ -92,7 +92,6 @@ struct sigevent { int sigev_signo; }; -#ifdef CONFIG_POSIX_SIGNAL char *strsignal(int signum); int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); @@ -102,7 +101,6 @@ int sigismember(const sigset_t *set, int signo); int sigprocmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); int pthread_sigmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT oset); -#endif /* CONFIG_POSIX_SIGNAL */ #ifdef __cplusplus } diff --git a/include/zephyr/posix/sys/eventfd.h b/include/zephyr/posix/sys/eventfd.h index 8f1443d7a9aac8..35bef86d87e8ca 100644 --- a/include/zephyr/posix/sys/eventfd.h +++ b/include/zephyr/posix/sys/eventfd.h @@ -7,21 +7,16 @@ #ifndef ZEPHYR_INCLUDE_POSIX_SYS_EVENTFD_H_ #define ZEPHYR_INCLUDE_POSIX_SYS_EVENTFD_H_ -#include - -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -#define EFD_IN_USE 0x1 __DEPRECATED_MACRO -#define EFD_SEMAPHORE 0x2 -#define EFD_NONBLOCK O_NONBLOCK -#define EFD_FLAGS_SET (EFD_SEMAPHORE | EFD_NONBLOCK) __DEPRECATED_MACRO +#define EFD_SEMAPHORE ZVFS_EFD_SEMAPHORE +#define EFD_NONBLOCK ZVFS_EFD_NONBLOCK -typedef uint64_t eventfd_t; +typedef zvfs_eventfd_t eventfd_t; /** * @brief Create a file descriptor for event notification diff --git a/include/zephyr/posix/sys/sysconf.h b/include/zephyr/posix/sys/sysconf.h index a88f16493e187b..f53d598ac0ba63 100644 --- a/include/zephyr/posix/sys/sysconf.h +++ b/include/zephyr/posix/sys/sysconf.h @@ -1,17 +1,18 @@ /* * Copyright (c) 2024, Meta + * Copyright (c) 2024, Tenstorrent AI ULC * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_POSIX_SYS_SYSCONF_H_ #define ZEPHYR_INCLUDE_POSIX_SYS_SYSCONF_H_ +#include + #ifdef __cplusplus extern "C" { #endif -#ifdef CONFIG_POSIX_SYSCONF - enum { _SC_ADVISORY_INFO, _SC_ASYNCHRONOUS_IO, @@ -21,7 +22,7 @@ enum { _SC_FSYNC, _SC_IPV6, _SC_JOB_CONTROL, - _SC_MAPPED_FILE, + _SC_MAPPED_FILES, _SC_MEMLOCK, _SC_MEMLOCK_RANGE, _SC_MEMORY_PROTECTION, @@ -140,100 +141,120 @@ enum { _SC_TZNAME_MAX, }; -#ifdef CONFIG_POSIX_SYSCONF_IMPL_MACRO -#define __z_posix_sysconf_SC_ADVISORY_INFO _POSIX_ADVISORY_INFO -#define __z_posix_sysconf_SC_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO -#define __z_posix_sysconf_SC_BARRIERS _POSIX_BARRIERS -#define __z_posix_sysconf_SC_CLOCK_SELECTION _POSIX_CLOCK_SELECTION -#define __z_posix_sysconf_SC_CPUTIME _POSIX_CPUTIME -#define __z_posix_sysconf_SC_FSYNC _POSIX_FSYNC -#define __z_posix_sysconf_SC_IPV6 _POSIX_IPV6 -#define __z_posix_sysconf_SC_JOB_CONTROL _POSIX_JOB_CONTROL -#define __z_posix_sysconf_SC_MAPPED_FILE _POSIX_MAPPED_FILES -#define __z_posix_sysconf_SC_MEMLOCK _POSIX_MEMLOCK -#define __z_posix_sysconf_SC_MEMLOCK_RANGE _POSIX_MEMLOCK_RANGE -#define __z_posix_sysconf_SC_MEMORY_PROTECTION _POSIX_MEMORY_PROTECTION -#define __z_posix_sysconf_SC_MESSAGE_PASSING _POSIX_MESSAGE_PASSING -#define __z_posix_sysconf_SC_MONOTONIC_CLOCK _POSIX_MONOTONIC_CLOCK -#define __z_posix_sysconf_SC_PRIORITIZED_IO _POSIX_PRIORITIZED_IO -#define __z_posix_sysconf_SC_PRIORITY_SCHEDULING _POSIX_PRIORITY_SCHEDULING -#define __z_posix_sysconf_SC_RAW_SOCKETS _POSIX_RAW_SOCKETS -#define __z_posix_sysconf_SC_RE_DUP_MAX _POSIX_RE_DUP_MAX -#define __z_posix_sysconf_SC_READER_WRITER_LOCKS _POSIX_READER_WRITER_LOCKS -#define __z_posix_sysconf_SC_REALTIME_SIGNALS _POSIX_REALTIME_SIGNALS -#define __z_posix_sysconf_SC_REGEXP _POSIX_REGEXP -#define __z_posix_sysconf_SC_SAVED_IDS _POSIX_SAVED_IDS -#define __z_posix_sysconf_SC_SEMAPHORES _POSIX_SEMAPHORES -#define __z_posix_sysconf_SC_SHARED_MEMORY_OBJECTS _POSIX_SHARED_MEMORY_OBJECTS -#define __z_posix_sysconf_SC_SHELL _POSIX_SHELL -#define __z_posix_sysconf_SC_SPAWN _POSIX_SPAWN -#define __z_posix_sysconf_SC_SPIN_LOCKS _POSIX_SPIN_LOCKS -#define __z_posix_sysconf_SC_SPORADIC_SERVER _POSIX_SPORADIC_SERVER -#define __z_posix_sysconf_SC_SS_REPL_MAX _POSIX_SS_REPL_MAX -#define __z_posix_sysconf_SC_SYNCHRONIZED_IO _POSIX_SYNCHRONIZED_IO -#define __z_posix_sysconf_SC_THREAD_ATTR_STACKADDR _POSIX_THREAD_ATTR_STACKADDR -#define __z_posix_sysconf_SC_THREAD_ATTR_STACKSIZE _POSIX_THREAD_ATTR_STACKSIZE -#define __z_posix_sysconf_SC_THREAD_CPUTIME _POSIX_THREAD_CPUTIME -#define __z_posix_sysconf_SC_THREAD_PRIO_INHERIT _POSIX_THREAD_PRIO_INHERIT -#define __z_posix_sysconf_SC_THREAD_PRIO_PROTECT _POSIX_THREAD_PRIO_PROTECT -#define __z_posix_sysconf_SC_THREAD_PRIORITY_SCHEDULING _POSIX_THREAD_PRIORITY_SCHEDULING -#define __z_posix_sysconf_SC_THREAD_PROCESS_SHARED _POSIX_THREAD_PROCESS_SHARED -#define __z_posix_sysconf_SC_THREAD_ROBUST_PRIO_INHERIT _POSIX_THREAD_ROBUST_PRIO_INHERIT -#define __z_posix_sysconf_SC_THREAD_ROBUST_PRIO_PROTECT _POSIX_THREAD_ROBUST_PRIO_PROTECT -#define __z_posix_sysconf_SC_THREAD_SAFE_FUNCTIONS _POSIX_THREAD_SAFE_FUNCTIONS -#define __z_posix_sysconf_SC_THREAD_SPORADIC_SERVER _POSIX_THREAD_SPORADIC_SERVER -#define __z_posix_sysconf_SC_THREADS _POSIX_THREADS -#define __z_posix_sysconf_SC_TIMEOUTS _POSIX_TIMEOUTS -#define __z_posix_sysconf_SC_TIMERS _POSIX_TIMERS -#define __z_posix_sysconf_SC_TRACE _POSIX_TRACE -#define __z_posix_sysconf_SC_TRACE_EVENT_FILTER _POSIX_TRACE_EVENT_FILTER -#define __z_posix_sysconf_SC_TRACE_EVENT_NAME_MAX _POSIX_TRACE_EVENT_NAME_MAX -#define __z_posix_sysconf_SC_TRACE_INHERIT _POSIX_TRACE_INHERIT -#define __z_posix_sysconf_SC_TRACE_LOG _POSIX_TRACE_LOG +#define __z_posix_sysconf_SC_ADVISORY_INFO (-1L) +#define __z_posix_sysconf_SC_ASYNCHRONOUS_IO \ + COND_CODE_1(CONFIG_POSIX_ASYNCHRONOUS_IO, (_POSIX_ASYNCHRONOUS_IO), (-1L)) +#define __z_posix_sysconf_SC_BARRIERS COND_CODE_1(CONFIG_POSIX_BARRIERS, (_POSIX_BARRIERS), (-1L)) +#define __z_posix_sysconf_SC_CLOCK_SELECTION \ + COND_CODE_1(CONFIG_POSIX_CLOCK_SELECTION, (_POSIX_CLOCK_SELECTION), (-1L)) +#define __z_posix_sysconf_SC_CPUTIME \ + COND_CODE_1(CONFIG_POSIX_CPUTIME, (_POSIX_CPUTIME), (-1L)) +#define __z_posix_sysconf_SC_FSYNC \ + COND_CODE_1(CONFIG_POSIX_FSYNC, (_POSIX_FSYNC), (-1L)) +#define __z_posix_sysconf_SC_IPV6 COND_CODE_1(CONFIG_NET_IPV6, (_POSIX_IPV6), (-1L)) +#define __z_posix_sysconf_SC_JOB_CONTROL (-1L) +#define __z_posix_sysconf_SC_MAPPED_FILES (-1L) +#define __z_posix_sysconf_SC_MEMLOCK (-1L) +#define __z_posix_sysconf_SC_MEMLOCK_RANGE (-1L) +#define __z_posix_sysconf_SC_MEMORY_PROTECTION (-1L) +#define __z_posix_sysconf_SC_MESSAGE_PASSING \ + COND_CODE_1(CONFIG_POSIX_MESSAGE_PASSING, (_POSIX_MESSAGE_PASSING), (-1L)) +#define __z_posix_sysconf_SC_MONOTONIC_CLOCK \ + COND_CODE_1(CONFIG_POSIX_MONOTONIC_CLOCK, (_POSIX_MONOTONIC_CLOCK), (-1L)) +#define __z_posix_sysconf_SC_PRIORITIZED_IO (-1L) +#define __z_posix_sysconf_SC_PRIORITY_SCHEDULING \ + COND_CODE_1(CONFIG_POSIX_PRIORITY_SCHEDULING, (_POSIX_PRIORITY_SCHEDULING), (-1L)) +#define __z_posix_sysconf_SC_RAW_SOCKETS \ + COND_CODE_1(CONFIG_NET_SOCKETS_PACKET, (_POSIX_RAW_SOCKETS), (-1L)) +#define __z_posix_sysconf_SC_RE_DUP_MAX _POSIX_RE_DUP_MAX +#define __z_posix_sysconf_SC_READER_WRITER_LOCKS \ + COND_CODE_1(CONFIG_POSIX_READER_WRITER_LOCKS, (_POSIX_READER_WRITER_LOCKS), (-1L)) +#define __z_posix_sysconf_SC_REALTIME_SIGNALS (-1L) +#define __z_posix_sysconf_SC_REGEXP (-1L) +#define __z_posix_sysconf_SC_SAVED_IDS (-1L) +#define __z_posix_sysconf_SC_SEMAPHORES \ + COND_CODE_1(CONFIG_POSIX_SEMAPHORES, (_POSIX_SEMAPHORES), (-1L)) +#define __z_posix_sysconf_SC_SHARED_MEMORY_OBJECTS (-1L) +#define __z_posix_sysconf_SC_SHELL (-1L) +#define __z_posix_sysconf_SC_SPAWN (-1L) +#define __z_posix_sysconf_SC_SPIN_LOCKS \ + COND_CODE_1(CONFIG_POSIX_SPIN_LOCKS, (_POSIX_SPIN_LOCKS), (-1L)) +#define __z_posix_sysconf_SC_SPORADIC_SERVER (-1L) +#define __z_posix_sysconf_SC_SS_REPL_MAX _POSIX_SS_REPL_MAX +#define __z_posix_sysconf_SC_SYNCHRONIZED_IO (-1L) +#define __z_posix_sysconf_SC_THREAD_ATTR_STACKADDR \ + COND_CODE_1(CONFIG_POSIX_THREAD_ATTR_STACKADDR, (_POSIX_THREAD_ATTR_STACKADDR), (-1)) +#define __z_posix_sysconf_SC_THREAD_ATTR_STACKSIZE \ + COND_CODE_1(CONFIG_POSIX_THREAD_ATTR_STACKSIZE, (_POSIX_THREAD_ATTR_STACKSIZE), (-1L)) +#define __z_posix_sysconf_SC_THREAD_CPUTIME (-1L) +#define __z_posix_sysconf_SC_THREAD_PRIO_INHERIT \ + COND_CODE_1(CONFIG_POSIX_THREAD_PRIO_INHERIT, (_POSIX_THREAD_PRIO_INHERIT), (-1L)) +#define __z_posix_sysconf_SC_THREAD_PRIO_PROTECT (-1L) +#define __z_posix_sysconf_SC_THREAD_PRIORITY_SCHEDULING \ + COND_CODE_1(CONFIG_POSIX_THREAD_PRIORITY_SCHEDULING, (_POSIX_THREAD_PRIORITY_SCHEDULING), \ + (-1L)) +#define __z_posix_sysconf_SC_THREAD_PROCESS_SHARED (-1L) +#define __z_posix_sysconf_SC_THREAD_ROBUST_PRIO_INHERIT (-1L) +#define __z_posix_sysconf_SC_THREAD_ROBUST_PRIO_PROTECT (-1L) +#define __z_posix_sysconf_SC_THREAD_SAFE_FUNCTIONS \ + COND_CODE_1(CONFIG_POSIX_THREAD_SAFE_FUNCTIONS, (_POSIX_THREAD_SAFE_FUNCTIONS), (-1L)) +#define __z_posix_sysconf_SC_THREAD_SPORADIC_SERVER (-1L) +#define __z_posix_sysconf_SC_THREADS \ + COND_CODE_1(CONFIG_POSIX_THREADS, (_POSIX_THREADS), (-1L)) +#define __z_posix_sysconf_SC_TIMEOUTS \ + COND_CODE_1(CONFIG_POSIX_TIMEOUTS, (_POSIX_TIMEOUTS), (-1L)) +#define __z_posix_sysconf_SC_TIMERS \ + COND_CODE_1(CONFIG_POSIX_TIMEOUTS, (_POSIX_TIMERS), (-1)) +#define __z_posix_sysconf_SC_TRACE (-1L) +#define __z_posix_sysconf_SC_TRACE_EVENT_FILTER (-1L) +#define __z_posix_sysconf_SC_TRACE_EVENT_NAME_MAX _POSIX_TRACE_NAME_MAX +#define __z_posix_sysconf_SC_TRACE_INHERIT (-1L) +#define __z_posix_sysconf_SC_TRACE_LOG (-1L) #define __z_posix_sysconf_SC_TRACE_NAME_MAX _POSIX_TRACE_NAME_MAX #define __z_posix_sysconf_SC_TRACE_SYS_MAX _POSIX_TRACE_SYS_MAX #define __z_posix_sysconf_SC_TRACE_USER_EVENT_MAX _POSIX_TRACE_USER_EVENT_MAX -#define __z_posix_sysconf_SC_TYPED_MEMORY_OBJECTS _POSIX_TYPED_MEMORY_OBJECTS +#define __z_posix_sysconf_SC_TYPED_MEMORY_OBJECTS (-1L) #define __z_posix_sysconf_SC_VERSION _POSIX_VERSION -#define __z_posix_sysconf_SC_V7_ILP32_OFF32 _POSIX_V7_ILP32_OFF32 -#define __z_posix_sysconf_SC_V7_ILP32_OFFBIG _POSIX_V7_ILP32_OFFBIG -#define __z_posix_sysconf_SC_V7_LP64_OFF64 _POSIX_V7_LP64_OFF64 -#define __z_posix_sysconf_SC_V7_LPBIG_OFFBIG _POSIX_V7_LPBIG_OFFBIG -#define __z_posix_sysconf_SC_V6_ILP32_OFF32 _POSIX_V6_ILP32_OFF32 -#define __z_posix_sysconf_SC_V6_ILP32_OFFBIG _POSIX_V6_ILP32_OFFBIG -#define __z_posix_sysconf_SC_V6_LP64_OFF64 _POSIX_V6_LP64_OFF64 -#define __z_posix_sysconf_SC_V6_LPBIG_OFFBIG _POSIX_V6_LPBIG_OFFBIG +#define __z_posix_sysconf_SC_V6_ILP32_OFF32 (-1L) +#define __z_posix_sysconf_SC_V6_ILP32_OFFBIG (-1L) +#define __z_posix_sysconf_SC_V6_LP64_OFF64 (-1L) +#define __z_posix_sysconf_SC_V6_LPBIG_OFFBIG (-1L) +#define __z_posix_sysconf_SC_V7_ILP32_OFF32 (-1L) +#define __z_posix_sysconf_SC_V7_ILP32_OFFBIG (-1L) +#define __z_posix_sysconf_SC_V7_LP64_OFF64 (-1L) +#define __z_posix_sysconf_SC_V7_LPBIG_OFFBIG (-1L) #define __z_posix_sysconf_SC_BC_BASE_MAX _POSIX2_BC_BASE_MAX #define __z_posix_sysconf_SC_BC_DIM_MAX _POSIX2_BC_DIM_MAX #define __z_posix_sysconf_SC_BC_SCALE_MAX _POSIX2_BC_SCALE_MAX #define __z_posix_sysconf_SC_BC_STRING_MAX _POSIX2_BC_STRING_MAX #define __z_posix_sysconf_SC_2_C_BIND _POSIX2_C_BIND #define __z_posix_sysconf_SC_2_C_DEV _POSIX2_C_DEV -#define __z_posix_sysconf_SC_2_CHAR_TERM _POSIX2_CHAR_TERM +#define __z_posix_sysconf_SC_2_CHAR_TERM (-1L) #define __z_posix_sysconf_SC_COLL_WEIGHTS_MAX _POSIX2_COLL_WEIGHTS_MAX -#define __z_posix_sysconf_SC_DELAYTIMER_MAX _POSIX2_DELAYTIMER_MAX +#define __z_posix_sysconf_SC_DELAYTIMER_MAX _POSIX_DELAYTIMER_MAX #define __z_posix_sysconf_SC_EXPR_NEST_MAX _POSIX2_EXPR_NEST_MAX -#define __z_posix_sysconf_SC_2_FORT_DEV _POSIX2_FORT_DEV -#define __z_posix_sysconf_SC_2_FORT_RUN _POSIX2_FORT_RUN -#define __z_posix_sysconf_SC_LINE_MAX _POSIX2_LINE_MAX -#define __z_posix_sysconf_SC_2_LOCALEDEF _POSIX2_LOCALEDEF -#define __z_posix_sysconf_SC_2_PBS _POSIX2_PBS -#define __z_posix_sysconf_SC_2_PBS_ACCOUNTING _POSIX2_PBS_ACCOUNTING -#define __z_posix_sysconf_SC_2_PBS_CHECKPOINT _POSIX2_PBS_CHECKPOINT -#define __z_posix_sysconf_SC_2_PBS_LOCATE _POSIX2_PBS_LOCATE -#define __z_posix_sysconf_SC_2_PBS_MESSAGE _POSIX2_PBS_MESSAGE -#define __z_posix_sysconf_SC_2_PBS_TRACK _POSIX2_PBS_TRACK -#define __z_posix_sysconf_SC_2_SW_DEV _POSIX2_SW_DEV -#define __z_posix_sysconf_SC_2_UPE _POSIX2_UPE +#define __z_posix_sysconf_SC_2_FORT_DEV (-1L) +#define __z_posix_sysconf_SC_2_FORT_RUN (-1L) +#define __z_posix_sysconf_SC_LINE_MAX (-1L) +#define __z_posix_sysconf_SC_2_LOCALEDEF (-1L) +#define __z_posix_sysconf_SC_2_PBS (-1L) +#define __z_posix_sysconf_SC_2_PBS_ACCOUNTING (-1L) +#define __z_posix_sysconf_SC_2_PBS_CHECKPOINT (-1L) +#define __z_posix_sysconf_SC_2_PBS_LOCATE (-1L) +#define __z_posix_sysconf_SC_2_PBS_MESSAGE (-1L) +#define __z_posix_sysconf_SC_2_PBS_TRACK (-1L) +#define __z_posix_sysconf_SC_2_SW_DEV (-1L) +#define __z_posix_sysconf_SC_2_UPE (-1L) #define __z_posix_sysconf_SC_2_VERSION _POSIX2_VERSION -#define __z_posix_sysconf_SC_XOPEN_CRYPT _XOPEN_CRYPT -#define __z_posix_sysconf_SC_XOPEN_ENH_I18N _XOPEN_ENH_I18N -#define __z_posix_sysconf_SC_XOPEN_REALTIME _XOPEN_REALTIME -#define __z_posix_sysconf_SC_XOPEN_REALTIME_THREADS _XOPEN_REALTIME_THREADS -#define __z_posix_sysconf_SC_XOPEN_SHM _XOPEN_SHM -#define __z_posix_sysconf_SC_XOPEN_STREAMS _XOPEN_STREAMS -#define __z_posix_sysconf_SC_XOPEN_UNIX _XOPEN_UNIX -#define __z_posix_sysconf_SC_XOPEN_UUCP _XOPEN_UUCP +#define __z_posix_sysconf_SC_XOPEN_CRYPT (-1L) +#define __z_posix_sysconf_SC_XOPEN_ENH_I18N (-1L) +#define __z_posix_sysconf_SC_XOPEN_REALTIME (-1L) +#define __z_posix_sysconf_SC_XOPEN_REALTIME_THREADS (-1L) +#define __z_posix_sysconf_SC_XOPEN_SHM (-1L) +#define __z_posix_sysconf_SC_XOPEN_STREAMS \ + COND_CODE_1(CONFIG_XOPEN_STREAMS, (_POSIX_XOPEN_STREAMS), (-1)) +#define __z_posix_sysconf_SC_XOPEN_UNIX (-1L) +#define __z_posix_sysconf_SC_XOPEN_UUCP (-1L) #define __z_posix_sysconf_SC_XOPEN_VERSION _XOPEN_VERSION #define __z_posix_sysconf_SC_CLK_TCK (100L) #define __z_posix_sysconf_SC_GETGR_R_SIZE_MAX (0L) @@ -250,7 +271,7 @@ enum { #define __z_posix_sysconf_SC_NGROUPS_MAX _POSIX_NGROUPS_MAX #define __z_posix_sysconf_SC_MQ_OPEN_MAX MQ_OPEN_MAX #define __z_posix_sysconf_SC_MQ_PRIO_MAX MQ_PRIO_MAX -#define __z_posix_sysconf_SC_OPEN_MAX CONFIG_POSIX_MAX_FDS +#define __z_posix_sysconf_SC_OPEN_MAX CONFIG_ZVFS_OPEN_MAX #define __z_posix_sysconf_SC_PAGE_SIZE PAGE_SIZE #define __z_posix_sysconf_SC_PAGESIZE PAGESIZE #define __z_posix_sysconf_SC_THREAD_DESTRUCTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS @@ -267,11 +288,10 @@ enum { #define __z_posix_sysconf_SC_TTY_NAME_MAX TTY_NAME_MAX #define __z_posix_sysconf_SC_TZNAME_MAX TZNAME_MAX +#ifdef CONFIG_POSIX_SYSCONF_IMPL_MACRO #define sysconf(x) (long)CONCAT(__z_posix_sysconf, x) #endif -#endif - #ifdef __cplusplus } #endif diff --git a/include/zephyr/posix/sys/utsname.h b/include/zephyr/posix/sys/utsname.h index 32046f431d89d1..542215076a4004 100644 --- a/include/zephyr/posix/sys/utsname.h +++ b/include/zephyr/posix/sys/utsname.h @@ -6,15 +6,23 @@ #ifndef ZEPHYR_INCLUDE_POSIX_SYS_UTSNAME_H_ #define ZEPHYR_INCLUDE_POSIX_SYS_UTSNAME_H_ +#include + #ifdef __cplusplus extern "C" { #endif +/* These are for compatibility / practicality */ +#define _UTSNAME_NODENAME_LENGTH \ + COND_CODE_1(CONFIG_POSIX_SINGLE_PROCESS, (CONFIG_POSIX_UNAME_VERSION_LEN), (0)) +#define _UTSNAME_VERSION_LENGTH \ + COND_CODE_1(CONFIG_POSIX_SINGLE_PROCESS, (CONFIG_POSIX_UNAME_VERSION_LEN), (0)) + struct utsname { char sysname[sizeof("Zephyr")]; - char nodename[CONFIG_POSIX_UNAME_NODENAME_LEN + 1]; + char nodename[_UTSNAME_NODENAME_LENGTH + 1]; char release[sizeof("99.99.99-rc1")]; - char version[CONFIG_POSIX_UNAME_VERSION_LEN + 1]; + char version[_UTSNAME_VERSION_LENGTH + 1]; char machine[sizeof(CONFIG_ARCH)]; }; diff --git a/include/zephyr/posix/time.h b/include/zephyr/posix/time.h index 8038e783030f07..f0ca07284bc843 100644 --- a/include/zephyr/posix/time.h +++ b/include/zephyr/posix/time.h @@ -73,6 +73,10 @@ extern "C" { #define CLOCK_PROCESS_CPUTIME_ID 2 #endif +#ifndef CLOCK_THREAD_CPUTIME_ID +#define CLOCK_THREAD_CPUTIME_ID 3 +#endif + #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 4 #endif @@ -83,7 +87,7 @@ extern "C" { static inline int32_t _ts_to_ms(const struct timespec *to) { - return (to->tv_sec * MSEC_PER_SEC) + (to->tv_nsec / NSEC_PER_MSEC); + return (int32_t)(to->tv_sec * MSEC_PER_SEC) + (int32_t)(to->tv_nsec / NSEC_PER_MSEC); } int clock_gettime(clockid_t clock_id, struct timespec *ts); diff --git a/include/zephyr/posix/unistd.h b/include/zephyr/posix/unistd.h index f829ebac235139..194b2bffe6f503 100644 --- a/include/zephyr/posix/unistd.h +++ b/include/zephyr/posix/unistd.h @@ -16,221 +16,16 @@ #include #include #endif -#ifdef CONFIG_POSIX_SYSCONF -#include -#endif #include #include #include +#include "posix_features.h" + #ifdef __cplusplus extern "C" { #endif -/* Version test macros */ -#define _POSIX_VERSION 200809L -#define _POSIX2_VERSION (-1L) -#define _XOPEN_VERSION (-1L) - -/* Internal helper macro to set constant if required Kconfig symbol is enabled */ -#define Z_SC_VAL_IFDEF(_def, _val) COND_CODE_1(_def, (_val), (-1L)) - -/* Constants for Options and Option Groups */ -#define _POSIX_ADVISORY_INFO (-1L) -#define _POSIX_ASYNCHRONOUS_IO Z_SC_VAL_IFDEF(CONFIG_POSIX_ASYNCHRONOUS_IO, _POSIX_VERSION) -#define _POSIX_BARRIERS Z_SC_VAL_IFDEF(CONFIG_PTHREAD_BARRIER, _POSIX_VERSION) -#define _POSIX_CHOWN_RESTRICTED (0) -#define _POSIX_CLOCK_SELECTION Z_SC_VAL_IFDEF(CONFIG_POSIX_CLOCK, _POSIX_VERSION) -#define _POSIX_CPUTIME (-1L) -#define _POSIX_FSYNC Z_SC_VAL_IFDEF(CONFIG_POSIX_FSYNC, _POSIX_VERSION) -#define _POSIX_IPV6 Z_SC_VAL_IFDEF(CONFIG_NET_IPV6, _POSIX_VERSION) -#define _POSIX_JOB_CONTROL (-1L) -#define _POSIX_MAPPED_FILES (-1L) -#define _POSIX_MEMLOCK (-1L) -#define _POSIX_MEMLOCK_RANGE (-1L) -#define _POSIX_MEMORY_PROTECTION (-1L) -#define _POSIX_MESSAGE_PASSING Z_SC_VAL_IFDEF(CONFIG_POSIX_MQUEUE, _POSIX_VERSION) -#define _POSIX_MONOTONIC_CLOCK Z_SC_VAL_IFDEF(CONFIG_POSIX_CLOCK, _POSIX_VERSION) -#define _POSIX_NO_TRUNC (0) -#define _POSIX_PRIORITIZED_IO (-1L) -#define _POSIX_PRIORITY_SCHEDULING Z_SC_VAL_IFDEF(CONFIG_POSIX_PRIORITY_SCHEDULING, _POSIX_VERSION) -#define _POSIX_RAW_SOCKETS Z_SC_VAL_IFDEF(CONFIG_NET_SOCKETS_PACKET, _POSIX_VERSION) -#define _POSIX_READER_WRITER_LOCKS Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_REALTIME_SIGNALS (-1L) -#define _POSIX_REGEXP (-1L) -#define _POSIX_SAVED_IDS (-1L) -#define _POSIX_SEMAPHORES Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_SHARED_MEMORY_OBJECTS (-1L) -#define _POSIX_SHELL (-1L) -#define _POSIX_SPAWN (-1L) -#define _POSIX_SPIN_LOCKS Z_SC_VAL_IFDEF(CONFIG_PTHREAD_SPINLOCK, _POSIX_VERSION) -#define _POSIX_SPORADIC_SERVER (-1L) -#define _POSIX_SYNCHRONIZED_IO (-1L) -#define _POSIX_THREAD_ATTR_STACKADDR Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_THREAD_ATTR_STACKSIZE Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_THREAD_CPUTIME (-1L) -#define _POSIX_THREAD_PRIO_INHERIT _POSIX_VERSION -#define _POSIX_THREAD_PRIO_PROTECT (-1L) -#define _POSIX_THREAD_PRIORITY_SCHEDULING Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_THREAD_PROCESS_SHARED (-1L) -#define _POSIX_THREAD_ROBUST_PRIO_INHERIT (-1L) -#define _POSIX_THREAD_ROBUST_PRIO_PROTECT (-1L) -#define _POSIX_THREAD_SAFE_FUNCTIONS Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#define _POSIX_THREAD_SPORADIC_SERVER (-1L) - -#ifndef _POSIX_THREADS -#define _POSIX_THREADS Z_SC_VAL_IFDEF(CONFIG_PTHREAD_IPC, _POSIX_VERSION) -#endif - -#define _POSIX_TIMEOUTS Z_SC_VAL_IFDEF(CONFIG_POSIX_CLOCK, _POSIX_VERSION) -#define _POSIX_TIMERS Z_SC_VAL_IFDEF(CONFIG_POSIX_CLOCK, _POSIX_VERSION) -#define _POSIX_TRACE (-1L) -#define _POSIX_TRACE_EVENT_FILTER (-1L) -#define _POSIX_TRACE_INHERIT (-1L) -#define _POSIX_TRACE_LOG (-1L) -#define _POSIX_TYPED_MEMORY_OBJECTS (-1L) -#define _POSIX_V6_ILP32_OFF32 (-1L) -#define _POSIX_V6_ILP32_OFFBIG (-1L) -#define _POSIX_V6_LP64_OFF64 (-1L) -#define _POSIX_V6_LPBIG_OFFBIG (-1L) -#define _POSIX_V7_ILP32_OFF32 (-1L) -#define _POSIX_V7_ILP32_OFFBIG (-1L) -#define _POSIX_V7_LP64_OFF64 (-1L) -#define _POSIX_V7_LPBIG_OFFBIG (-1L) -#define _POSIX2_C_BIND _POSIX_VERSION -#define _POSIX2_C_DEV (-1L) -#define _POSIX2_CHAR_TERM (-1L) -#define _POSIX2_DELAYTIMER_MAX (-1L) -#define _POSIX2_FORT_DEV (-1L) -#define _POSIX2_FORT_RUN (-1L) -#define _POSIX2_LOCALEDEF (-1L) -#define _POSIX2_PBS (-1L) -#define _POSIX2_PBS_ACCOUNTING (-1L) -#define _POSIX2_PBS_CHECKPOINT (-1L) -#define _POSIX2_PBS_LOCATE (-1L) -#define _POSIX2_PBS_MESSAGE (-1L) -#define _POSIX2_PBS_TRACK (-1L) -#define _POSIX2_SW_DEV (-1L) -#define _POSIX2_UPE (-1L) -#define _XOPEN_CRYPT (-1L) -#define _XOPEN_ENH_I18N (-1L) -#define _XOPEN_REALTIME (-1L) -#define _XOPEN_REALTIME_THREADS (-1L) -#define _XOPEN_SHM (-1L) -#define _XOPEN_STREAMS (-1L) -#define _XOPEN_UNIX (-1L) -#define _XOPEN_UUCP (-1L) - -/* Maximum values */ -#define _POSIX_CLOCKRES_MIN (20000000L) - -/* Minimum values */ -#define _POSIX_AIO_LISTIO_MAX (2) -#define _POSIX_AIO_MAX (1) -#define _POSIX_ARG_MAX (4096) -#define _POSIX_CHILD_MAX (25) -#define _POSIX_DELAYTIMER_MAX (32) -#define _POSIX_HOST_NAME_MAX (255) -#define _POSIX_LINK_MAX (8) -#define _POSIX_LOGIN_NAME_MAX (9) -#define _POSIX_MAX_CANON (255) -#define _POSIX_MAX_INPUT (255) -#define _POSIX_MQ_OPEN_MAX Z_SC_VAL_IFDEF(CONFIG_POSIX_MQUEUE, \ - CONFIG_MSG_COUNT_MAX) -#define _POSIX_MQ_PRIO_MAX (32) -#define _POSIX_NAME_MAX (14) -#define _POSIX_NGROUPS_MAX (8) -#define _POSIX_OPEN_MAX CONFIG_POSIX_MAX_FDS -#define _POSIX_PATH_MAX (256) -#define _POSIX_PIPE_BUF (512) -#define _POSIX_RE_DUP_MAX (255) -#define _POSIX_RTSIG_MAX CONFIG_POSIX_RTSIG_MAX -#define _POSIX_SEM_NSEMS_MAX CONFIG_SEM_NAMELEN_MAX -#define _POSIX_SEM_VALUE_MAX CONFIG_SEM_VALUE_MAX -#define _POSIX_SIGQUEUE_MAX (32) -#define _POSIX_SSIZE_MAX (32767) -#define _POSIX_SS_REPL_MAX (4) -#define _POSIX_STREAM_MAX (8) -#define _POSIX_SYMLINK_MAX (255) -#define _POSIX_SYMLOOP_MAX (8) -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS (4) -#define _POSIX_THREAD_KEYS_MAX (128) -#define _POSIX_THREAD_THREADS_MAX (64) -#define _POSIX_TIMER_MAX (32) -#define _POSIX_TRACE_EVENT_NAME_MAX (30) -#define _POSIX_TRACE_NAME_MAX (8) -#define _POSIX_TRACE_SYS_MAX (8) -#define _POSIX_TRACE_USER_EVENT_MAX (32) -#define _POSIX_TTY_NAME_MAX (9) -#define _POSIX_TZNAME_MAX (6) -#define _POSIX2_BC_BASE_MAX (99) -#define _POSIX2_BC_DIM_MAX (2048) -#define _POSIX2_BC_SCALE_MAX (99) -#define _POSIX2_BC_STRING_MAX (1000) -#define _POSIX2_CHARCLASS_NAME_MAX (14) -#define _POSIX2_COLL_WEIGHTS_MAX (2) -#define _POSIX2_EXPR_NEST_MAX (32) -#define _POSIX2_LINE_MAX (2048) -#define _XOPEN_IOV_MAX (16) -#define _XOPEN_NAME_MAX (255) -#define _XOPEN_PATH_MAX (1024) - -/* Other invariant values */ -#define NL_LANGMAX (14) -#define NL_MSGMAX (32767) -#define NL_SETMAX (255) -#define NL_TEXTMAX (_POSIX2_LINE_MAX) -#define NZERO (20) - -/* Runtime invariant values */ -#define AIO_LISTIO_MAX _POSIX_AIO_LISTIO_MAX -#define AIO_MAX _POSIX_AIO_MAX -#define AIO_PRIO_DELTA_MAX (0) -#define DELAYTIMER_MAX _POSIX_DELAYTIMER_MAX -#define HOST_NAME_MAX COND_CODE_1(CONFIG_NETWORKING, \ - (NET_HOSTNAME_MAX_LEN), \ - (_POSIX_HOST_NAME_MAX)) -#define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX -#define MQ_OPEN_MAX _POSIX_MQ_OPEN_MAX -#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX - -#ifndef ATEXIT_MAX -#define ATEXIT_MAX 8 -#endif - -#ifndef PAGE_SIZE -#define PAGE_SIZE BIT(CONFIG_POSIX_PAGE_SIZE_BITS) -#endif - -#ifndef PAGESIZE -#define PAGESIZE PAGE_SIZE -#endif - -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_KEYS_MAX COND_CODE_1(CONFIG_PTHREAD_IPC, \ - (CONFIG_MAX_PTHREAD_KEY_COUNT), \ - (_POSIX_THREAD_KEYS_MAX)) -#define PTHREAD_THREADS_MAX COND_CODE_1(CONFIG_PTHREAD_IPC, \ - (CONFIG_MAX_PTHREAD_COUNT), \ - (0)) -#define SEM_NSEMS_MAX _POSIX_SEM_NSEMS_MAX -#define SEM_VALUE_MAX CONFIG_SEM_VALUE_MAX -#define SIGQUEUE_MAX _POSIX_SIGQUEUE_MAX -#define STREAM_MAX _POSIX_STREAM_MAX -#define SYMLOOP_MAX _POSIX_SYMLOOP_MAX -#define TIMER_MAX Z_SC_VAL_IFDEF(CONFIG_TIMER, CONFIG_MAX_TIMER_COUNT) -#define TTY_NAME_MAX _POSIX_TTY_NAME_MAX -#define TZNAME_MAX _POSIX_TZNAME_MAX - -/* Pathname variable values */ -#define FILESIZEBITS (32) -#define POSIX_ALLOC_SIZE_MIN (256) -#define POSIX_REC_INCR_XFER_SIZE (1024) -#define POSIX_REC_MAX_XFER_SIZE (32767) -#define POSIX_REC_MIN_XFER_SIZE (1) -#define POSIX_REC_XFER_ALIGN (4) -#define SYMLINK_MAX _POSIX_SYMLINK_MAX - #ifdef CONFIG_POSIX_API /* File related operations */ int close(int file); @@ -257,7 +52,7 @@ static inline int gethostname(char *buf, size_t len) #endif /* CONFIG_POSIX_API */ -#ifdef CONFIG_GETOPT +#ifdef CONFIG_POSIX_C_LIB_EXT int getopt(int argc, char *const argv[], const char *optstring); extern char *optarg; extern int opterr, optind, optopt; @@ -267,13 +62,16 @@ int getentropy(void *buffer, size_t length); pid_t getpid(void); unsigned sleep(unsigned int seconds); int usleep(useconds_t useconds); -#ifdef CONFIG_POSIX_SYSCONF_IMPL_FULL -long sysconf(int opt); -#endif #if _POSIX_C_SOURCE >= 2 size_t confstr(int name, char *buf, size_t len); #endif +#ifdef CONFIG_POSIX_SYSCONF_IMPL_MACRO +#define sysconf(x) (long)CONCAT(__z_posix_sysconf, x) +#else +long sysconf(int opt); +#endif /* CONFIG_POSIX_SYSCONF_IMPL_FULL */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 75ab879f9499df..a53e939b0accf4 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -31,12 +31,12 @@ #include #include #include -#include #include #include #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -292,7 +292,7 @@ BUILD_ASSERT(sizeof(struct rtio_sqe) <= 64); * @brief A completion queue event */ struct rtio_cqe { - struct rtio_mpsc_node q; + struct mpsc_node q; int32_t result; /**< Result from operation */ void *userdata; /**< Associated userdata with operation */ @@ -300,14 +300,14 @@ struct rtio_cqe { }; struct rtio_sqe_pool { - struct rtio_mpsc free_q; + struct mpsc free_q; const uint16_t pool_size; uint16_t pool_free; struct rtio_iodev_sqe *pool; }; struct rtio_cqe_pool { - struct rtio_mpsc free_q; + struct mpsc free_q; const uint16_t pool_size; uint16_t pool_free; struct rtio_cqe *pool; @@ -362,10 +362,10 @@ struct rtio { #endif /* Submission queue */ - struct rtio_mpsc sq; + struct mpsc sq; /* Completion queue */ - struct rtio_mpsc cq; + struct mpsc cq; }; /** The memory partition associated with all RTIO context information */ @@ -422,7 +422,7 @@ static inline uint16_t __rtio_compute_mempool_block_index(const struct rtio *r, */ struct rtio_iodev_sqe { struct rtio_sqe sqe; - struct rtio_mpsc_node q; + struct mpsc_node q; struct rtio_iodev_sqe *next; struct rtio *r; }; @@ -449,9 +449,6 @@ struct rtio_iodev { /* Function pointer table */ const struct rtio_iodev_api *api; - /* Queue of RTIO contexts with requests */ - struct rtio_mpsc iodev_sq; - /* Data associated with this iodev */ void *data; }; @@ -625,7 +622,7 @@ static inline void rtio_sqe_prep_transceive(struct rtio_sqe *sqe, static inline struct rtio_iodev_sqe *rtio_sqe_pool_alloc(struct rtio_sqe_pool *pool) { - struct rtio_mpsc_node *node = rtio_mpsc_pop(&pool->free_q); + struct mpsc_node *node = mpsc_pop(&pool->free_q); if (node == NULL) { return NULL; @@ -640,14 +637,14 @@ static inline struct rtio_iodev_sqe *rtio_sqe_pool_alloc(struct rtio_sqe_pool *p static inline void rtio_sqe_pool_free(struct rtio_sqe_pool *pool, struct rtio_iodev_sqe *iodev_sqe) { - rtio_mpsc_push(&pool->free_q, &iodev_sqe->q); + mpsc_push(&pool->free_q, &iodev_sqe->q); pool->pool_free++; } static inline struct rtio_cqe *rtio_cqe_pool_alloc(struct rtio_cqe_pool *pool) { - struct rtio_mpsc_node *node = rtio_mpsc_pop(&pool->free_q); + struct mpsc_node *node = mpsc_pop(&pool->free_q); if (node == NULL) { return NULL; @@ -664,7 +661,7 @@ static inline struct rtio_cqe *rtio_cqe_pool_alloc(struct rtio_cqe_pool *pool) static inline void rtio_cqe_pool_free(struct rtio_cqe_pool *pool, struct rtio_cqe *cqe) { - rtio_mpsc_push(&pool->free_q, &cqe->q); + mpsc_push(&pool->free_q, &cqe->q); pool->pool_free++; } @@ -732,14 +729,13 @@ static inline void rtio_block_pool_free(struct rtio *r, void *buf, uint32_t buf_ #define RTIO_IODEV_DEFINE(name, iodev_api, iodev_data) \ STRUCT_SECTION_ITERABLE(rtio_iodev, name) = { \ .api = (iodev_api), \ - .iodev_sq = RTIO_MPSC_INIT((name.iodev_sq)), \ .data = (iodev_data), \ } #define Z_RTIO_SQE_POOL_DEFINE(name, sz) \ static struct rtio_iodev_sqe CONCAT(_sqe_pool_, name)[sz]; \ STRUCT_SECTION_ITERABLE(rtio_sqe_pool, name) = { \ - .free_q = RTIO_MPSC_INIT((name.free_q)), \ + .free_q = MPSC_INIT((name.free_q)), \ .pool_size = sz, \ .pool_free = sz, \ .pool = CONCAT(_sqe_pool_, name), \ @@ -749,7 +745,7 @@ static inline void rtio_block_pool_free(struct rtio *r, void *buf, uint32_t buf_ #define Z_RTIO_CQE_POOL_DEFINE(name, sz) \ static struct rtio_cqe CONCAT(_cqe_pool_, name)[sz]; \ STRUCT_SECTION_ITERABLE(rtio_cqe_pool, name) = { \ - .free_q = RTIO_MPSC_INIT((name.free_q)), \ + .free_q = MPSC_INIT((name.free_q)), \ .pool_size = sz, \ .pool_free = sz, \ .pool = CONCAT(_cqe_pool_, name), \ @@ -797,8 +793,8 @@ static inline void rtio_block_pool_free(struct rtio *r, void *buf, uint32_t buf_ .sqe_pool = _sqe_pool, \ .cqe_pool = _cqe_pool, \ IF_ENABLED(CONFIG_RTIO_SYS_MEM_BLOCKS, (.block_pool = _block_pool,)) \ - .sq = RTIO_MPSC_INIT((name.sq)), \ - .cq = RTIO_MPSC_INIT((name.cq)), \ + .sq = MPSC_INIT((name.sq)), \ + .cq = MPSC_INIT((name.cq)), \ } /** @@ -910,7 +906,7 @@ static inline struct rtio_sqe *rtio_sqe_acquire(struct rtio *r) return NULL; } - rtio_mpsc_push(&r->sq, &iodev_sqe->q); + mpsc_push(&r->sq, &iodev_sqe->q); return &iodev_sqe->sqe; } @@ -923,12 +919,12 @@ static inline struct rtio_sqe *rtio_sqe_acquire(struct rtio *r) static inline void rtio_sqe_drop_all(struct rtio *r) { struct rtio_iodev_sqe *iodev_sqe; - struct rtio_mpsc_node *node = rtio_mpsc_pop(&r->sq); + struct mpsc_node *node = mpsc_pop(&r->sq); while (node != NULL) { iodev_sqe = CONTAINER_OF(node, struct rtio_iodev_sqe, q); rtio_sqe_pool_free(r->sqe_pool, iodev_sqe); - node = rtio_mpsc_pop(&r->sq); + node = mpsc_pop(&r->sq); } } @@ -953,7 +949,7 @@ static inline struct rtio_cqe *rtio_cqe_acquire(struct rtio *r) */ static inline void rtio_cqe_produce(struct rtio *r, struct rtio_cqe *cqe) { - rtio_mpsc_push(&r->cq, &cqe->q); + mpsc_push(&r->cq, &cqe->q); } /** @@ -969,7 +965,7 @@ static inline void rtio_cqe_produce(struct rtio *r, struct rtio_cqe *cqe) */ static inline struct rtio_cqe *rtio_cqe_consume(struct rtio *r) { - struct rtio_mpsc_node *node; + struct mpsc_node *node; struct rtio_cqe *cqe = NULL; #ifdef CONFIG_RTIO_CONSUME_SEM @@ -978,7 +974,7 @@ static inline struct rtio_cqe *rtio_cqe_consume(struct rtio *r) } #endif - node = rtio_mpsc_pop(&r->cq); + node = mpsc_pop(&r->cq); if (node == NULL) { return NULL; } @@ -999,16 +995,16 @@ static inline struct rtio_cqe *rtio_cqe_consume(struct rtio *r) */ static inline struct rtio_cqe *rtio_cqe_consume_block(struct rtio *r) { - struct rtio_mpsc_node *node; + struct mpsc_node *node; struct rtio_cqe *cqe; #ifdef CONFIG_RTIO_CONSUME_SEM k_sem_take(r->consume_sem, K_FOREVER); #endif - node = rtio_mpsc_pop(&r->cq); + node = mpsc_pop(&r->cq); while (node == NULL) { Z_SPIN_DELAY(1); - node = rtio_mpsc_pop(&r->cq); + node = mpsc_pop(&r->cq); } cqe = CONTAINER_OF(node, struct rtio_cqe, q); @@ -1128,24 +1124,6 @@ static inline void rtio_iodev_sqe_err(struct rtio_iodev_sqe *iodev_sqe, int resu rtio_executor_err(iodev_sqe, result); } -/** - * @brief Cancel all requests that are pending for the iodev - * - * @param iodev IODev to cancel all requests for - */ -static inline void rtio_iodev_cancel_all(struct rtio_iodev *iodev) -{ - /* Clear pending requests as -ENODATA */ - struct rtio_mpsc_node *node = rtio_mpsc_pop(&iodev->iodev_sq); - - while (node != NULL) { - struct rtio_iodev_sqe *iodev_sqe = CONTAINER_OF(node, struct rtio_iodev_sqe, q); - - rtio_iodev_sqe_err(iodev_sqe, -ECANCELED); - node = rtio_mpsc_pop(&iodev->iodev_sq); - } -} - /** * Submit a completion queue event with a given result and userdata * diff --git a/include/zephyr/shell/shell_adsp_memory_window.h b/include/zephyr/shell/shell_adsp_memory_window.h index 5ccc4d280ca7b5..f6277fd2996d56 100644 --- a/include/zephyr/shell/shell_adsp_memory_window.h +++ b/include/zephyr/shell/shell_adsp_memory_window.h @@ -42,7 +42,7 @@ struct shell_adsp_memory_window { static struct shell_adsp_memory_window _name##_shell_adsp_memory_window;\ struct shell_transport _name = { \ .api = &shell_adsp_memory_window_transport_api, \ - .ctx = (struct shell_memwindow *)&_name##_shell_adsp_memory_window, \ + .ctx = &_name##_shell_adsp_memory_window, \ } /** diff --git a/include/zephyr/shell/shell_mqtt.h b/include/zephyr/shell/shell_mqtt.h index 03cd64fbdcdba4..72e597e6d53b2d 100644 --- a/include/zephyr/shell/shell_mqtt.h +++ b/include/zephyr/shell/shell_mqtt.h @@ -120,7 +120,7 @@ struct shell_mqtt { const struct shell *shell_backend_mqtt_get_ptr(void); /** - * @brief Function to define the device ID (devid) for which the shell mqtt backend uses as a + * @brief Function to define the device ID (devid) for which the shell mqtt backend uses as a * client ID when it connects to the broker. It will publish its output to devid_tx and subscribe * to devid_rx for input . * diff --git a/include/zephyr/spinlock.h b/include/zephyr/spinlock.h index 51c160b0f8599d..451e91cbd54756 100644 --- a/include/zephyr/spinlock.h +++ b/include/zephyr/spinlock.h @@ -316,7 +316,7 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, #ifdef CONFIG_SMP #ifdef CONFIG_TICKET_SPINLOCKS /* Give the spinlock to the next CPU in a FIFO */ - atomic_inc(&l->owner); + (void)atomic_inc(&l->owner); #else /* Strictly we don't need atomic_clear() here (which is an * exchange operation that returns the old value). We are always @@ -325,7 +325,7 @@ static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, * a memory barrier when used like this, and we don't have a * Zephyr framework for that. */ - atomic_clear(&l->locked); + (void)atomic_clear(&l->locked); #endif /* CONFIG_TICKET_SPINLOCKS */ #endif /* CONFIG_SMP */ arch_irq_unlock(key.key); @@ -364,9 +364,9 @@ static ALWAYS_INLINE void k_spin_release(struct k_spinlock *l) #endif #ifdef CONFIG_SMP #ifdef CONFIG_TICKET_SPINLOCKS - atomic_inc(&l->owner); + (void)atomic_inc(&l->owner); #else - atomic_clear(&l->locked); + (void)atomic_clear(&l->locked); #endif /* CONFIG_TICKET_SPINLOCKS */ #endif /* CONFIG_SMP */ } @@ -437,7 +437,7 @@ static ALWAYS_INLINE void z_spin_onexit(__maybe_unused k_spinlock_key_t *k) */ #define K_SPINLOCK(lck) \ for (k_spinlock_key_t __i K_SPINLOCK_ONEXIT = {}, __key = k_spin_lock(lck); !__i.key; \ - k_spin_unlock(lck, __key), __i.key = 1) + k_spin_unlock((lck), __key), __i.key = 1) /** @} */ diff --git a/include/zephyr/storage/disk_access.h b/include/zephyr/storage/disk_access.h index 53774e7666edc4..a5ce72dd5bfb38 100644 --- a/include/zephyr/storage/disk_access.h +++ b/include/zephyr/storage/disk_access.h @@ -39,7 +39,13 @@ extern "C" { * @brief perform any initialization * * This call is made by the consumer before doing any IO calls so that the - * disk or the backing device can do any initialization. + * disk or the backing device can do any initialization. Although still + * supported for legacy compatibility, users should instead call + * @ref disk_access_ioctl with the IOCTL @ref DISK_IOCTL_CTRL_INIT. + * + * Disk initialization is reference counted, so only the first successful call + * to initialize a uninitialized (or previously de-initialized) disk will + * actually initialize the disk * * @param[in] pdrv Disk name * diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index b03628afc93ec3..937e242830ae39 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -187,6 +187,29 @@ int flash_area_write(const struct flash_area *fa, off_t off, const void *src, */ int flash_area_erase(const struct flash_area *fa, off_t off, size_t len); +/** + * @brief Erase flash area or fill with erase-value + * + * On program-erase devices this function behaves exactly like flash_area_erase. + * On RAM non-volatile device it will call erase, if driver provides such + * callback, or will fill given range with erase-value defined by driver. + * This function should be only used by code that has not been written + * to directly support devices that do not require erase and rely on + * device being erased prior to some operations. + * Note that emulated erase, on devices that do not require, is done + * via write, which affects endurance of device. + * + * @see flash_area_erase() + * @see flash_flatten() + * + * @param[in] fa Flash area + * @param[in] off Offset relative from beginning of flash area. + * @param[in] len Number of bytes to be erase + * + * @return 0 on success, negative errno code on fail. + */ +int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len); + /** * @brief Get write block size of the flash area * diff --git a/include/zephyr/sys/device_mmio.h b/include/zephyr/sys/device_mmio.h index c50a12782eef22..e500e2afb3e61c 100644 --- a/include/zephyr/sys/device_mmio.h +++ b/include/zephyr/sys/device_mmio.h @@ -101,8 +101,8 @@ static inline void device_map(mm_reg_t *virt_addr, uintptr_t phys_addr, /* Pass along flags and add that we want supervisor mode * read-write access. */ - z_phys_map((uint8_t **)virt_addr, phys_addr, size, - flags | K_MEM_PERM_RW); + k_mem_map_phys_bare((uint8_t **)virt_addr, phys_addr, size, + flags | K_MEM_PERM_RW); #else ARG_UNUSED(size); ARG_UNUSED(flags); diff --git a/include/zephyr/rtio/rtio_mpsc.h b/include/zephyr/sys/mpsc_lockfree.h similarity index 69% rename from include/zephyr/rtio/rtio_mpsc.h rename to include/zephyr/sys/mpsc_lockfree.h index 9551d1c5cc4120..3e6c89d99a051a 100644 --- a/include/zephyr/rtio/rtio_mpsc.h +++ b/include/zephyr/sys/mpsc_lockfree.h @@ -1,12 +1,12 @@ /* * Copyright (c) 2010-2011 Dmitry Vyukov - * Copyright (c) 2022 Intel Corporation + * Copyright (c) 2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_RTIO_MPSC_H_ -#define ZEPHYR_RTIO_MPSC_H_ +#ifndef ZEPHYR_SYS_MPSC_LOCKFREE_H_ +#define ZEPHYR_SYS_MPSC_LOCKFREE_H_ #include #include @@ -18,12 +18,28 @@ extern "C" { #endif /** - * @brief RTIO Multiple Producer Single Consumer (MPSC) Queue API - * @defgroup rtio_mpsc RTIO MPSC API - * @ingroup rtio + * @brief Multiple Producer Single Consumer (MPSC) Lockfree Queue API + * @defgroup mpsc_lockfree MPSC Lockfree Queue API + * @ingroup datastructure_apis * @{ */ +/** + * @file mpsc_lockfree.h + * + * @brief A wait-free intrusive multi producer single consumer (MPSC) queue using + * a singly linked list. Ordering is First-In-First-Out. + * + * Based on the well known and widely used wait-free MPSC queue described by + * Dmitry Vyukov with some slight changes to account for needs of an + * RTOS on a variety of archs. Both consumer and producer are wait free. No CAS + * loop or lock is needed. + * + * An MPSC queue is safe to produce or consume in an ISR with O(1) push/pop. + * + * @warning MPSC is *not* safe to consume in multiple execution contexts. + */ + /* * On single core systems atomics are unnecessary * and cause a lot of unnecessary cache invalidation @@ -32,20 +48,19 @@ extern "C" { * by the compiler generated op codes is enough. * * On SMP atomics *must* be used to ensure the pointers - * are updated in the correct order and the values are - * updated core caches correctly. + * are updated in the correct order. */ -#if defined(CONFIG_SMP) +#if IS_ENABLED(CONFIG_SMP) typedef atomic_ptr_t mpsc_ptr_t; -#define mpsc_ptr_get(ptr) atomic_ptr_get(&(ptr)) -#define mpsc_ptr_set(ptr, val) atomic_ptr_set(&(ptr), val) +#define mpsc_ptr_get(ptr) atomic_ptr_get(&(ptr)) +#define mpsc_ptr_set(ptr, val) atomic_ptr_set(&(ptr), val) #define mpsc_ptr_set_get(ptr, val) atomic_ptr_set(&(ptr), val) -#else +#else /* IS_ENABLED(CONFIG_SMP) */ -typedef struct rtio_mpsc_node *mpsc_ptr_t; +typedef struct mpsc_node *mpsc_ptr_t; #define mpsc_ptr_get(ptr) ptr #define mpsc_ptr_set(ptr, val) ptr = val @@ -56,38 +71,22 @@ typedef struct rtio_mpsc_node *mpsc_ptr_t; tmp; \ }) -#endif - -/** - * @file rtio_mpsc.h - * - * @brief A wait-free intrusive multi producer single consumer (MPSC) queue using - * a singly linked list. Ordering is First-In-First-Out. - * - * Based on the well known and widely used wait-free MPSC queue described by - * Dmitry Vyukov with some slight changes to account for needs of an - * RTOS on a variety of archs. Both consumer and producer are wait free. No CAS - * loop or lock is needed. - * - * An MPSC queue is safe to produce or consume in an ISR with O(1) push/pop. - * - * @warning MPSC is *not* safe to consume in multiple execution contexts. - */ +#endif /* IS_ENABLED(CONFIG_SMP) */ /** * @brief Queue member */ -struct rtio_mpsc_node { +struct mpsc_node { mpsc_ptr_t next; }; /** * @brief MPSC Queue */ -struct rtio_mpsc { +struct mpsc { mpsc_ptr_t head; - struct rtio_mpsc_node *tail; - struct rtio_mpsc_node stub; + struct mpsc_node *tail; + struct mpsc_node stub; }; /** @@ -97,10 +96,10 @@ struct rtio_mpsc { * * @param symbol name of the queue */ -#define RTIO_MPSC_INIT(symbol) \ +#define MPSC_INIT(symbol) \ { \ - .head = (struct rtio_mpsc_node *)&symbol.stub, \ - .tail = (struct rtio_mpsc_node *)&symbol.stub, \ + .head = (struct mpsc_node *)&symbol.stub, \ + .tail = (struct mpsc_node *)&symbol.stub, \ .stub = { \ .next = NULL, \ }, \ @@ -111,7 +110,7 @@ struct rtio_mpsc { * * @param q Queue to initialize or reset */ -static inline void rtio_mpsc_init(struct rtio_mpsc *q) +static inline void mpsc_init(struct mpsc *q) { mpsc_ptr_set(q->head, &q->stub); q->tail = &q->stub; @@ -124,15 +123,15 @@ static inline void rtio_mpsc_init(struct rtio_mpsc *q) * @param q Queue to push the node to * @param n Node to push into the queue */ -static ALWAYS_INLINE void rtio_mpsc_push(struct rtio_mpsc *q, struct rtio_mpsc_node *n) +static ALWAYS_INLINE void mpsc_push(struct mpsc *q, struct mpsc_node *n) { - struct rtio_mpsc_node *prev; + struct mpsc_node *prev; int key; mpsc_ptr_set(n->next, NULL); key = arch_irq_lock(); - prev = (struct rtio_mpsc_node *)mpsc_ptr_set_get(q->head, n); + prev = (struct mpsc_node *)mpsc_ptr_set_get(q->head, n); mpsc_ptr_set(prev->next, n); arch_irq_unlock(key); } @@ -143,11 +142,11 @@ static ALWAYS_INLINE void rtio_mpsc_push(struct rtio_mpsc *q, struct rtio_mpsc_n * @retval NULL When no node is available * @retval node When node is available */ -static inline struct rtio_mpsc_node *rtio_mpsc_pop(struct rtio_mpsc *q) +static inline struct mpsc_node *mpsc_pop(struct mpsc *q) { - struct rtio_mpsc_node *head; - struct rtio_mpsc_node *tail = q->tail; - struct rtio_mpsc_node *next = (struct rtio_mpsc_node *)mpsc_ptr_get(tail->next); + struct mpsc_node *head; + struct mpsc_node *tail = q->tail; + struct mpsc_node *next = (struct mpsc_node *)mpsc_ptr_get(tail->next); /* Skip over the stub/sentinel */ if (tail == &q->stub) { @@ -157,7 +156,7 @@ static inline struct rtio_mpsc_node *rtio_mpsc_pop(struct rtio_mpsc *q) q->tail = next; tail = next; - next = (struct rtio_mpsc_node *)mpsc_ptr_get(next->next); + next = (struct mpsc_node *)mpsc_ptr_get(next->next); } /* If next is non-NULL then a valid node is found, return it */ @@ -166,7 +165,7 @@ static inline struct rtio_mpsc_node *rtio_mpsc_pop(struct rtio_mpsc *q) return tail; } - head = (struct rtio_mpsc_node *)mpsc_ptr_get(q->head); + head = (struct mpsc_node *)mpsc_ptr_get(q->head); /* If next is NULL, and the tail != HEAD then the queue has pending * updates that can't yet be accessed. @@ -175,9 +174,9 @@ static inline struct rtio_mpsc_node *rtio_mpsc_pop(struct rtio_mpsc *q) return NULL; } - rtio_mpsc_push(q, &q->stub); + mpsc_push(q, &q->stub); - next = (struct rtio_mpsc_node *)mpsc_ptr_get(tail->next); + next = (struct mpsc_node *)mpsc_ptr_get(tail->next); if (next != NULL) { q->tail = next; @@ -195,4 +194,4 @@ static inline struct rtio_mpsc_node *rtio_mpsc_pop(struct rtio_mpsc *q) } #endif -#endif /* ZEPHYR_RTIO_MPSC_H_ */ +#endif /* ZEPHYR_SYS_MPSC_LOCKFREE_H_ */ diff --git a/include/zephyr/rtio/rtio_spsc.h b/include/zephyr/sys/spsc_lockfree.h similarity index 66% rename from include/zephyr/rtio/rtio_spsc.h rename to include/zephyr/sys/spsc_lockfree.h index 07872e7d4b020c..3f769bfbd16894 100644 --- a/include/zephyr/rtio/rtio_spsc.h +++ b/include/zephyr/sys/spsc_lockfree.h @@ -1,12 +1,11 @@ /* - * Copyright (c) 2022 Intel Corporation + * Copyright (c) 2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ - -#ifndef ZEPHYR_RTIO_SPSC_H_ -#define ZEPHYR_RTIO_SPSC_H_ +#ifndef ZEPHYR_SYS_SPSC_LOCKFREE_H_ +#define ZEPHYR_SYS_SPSC_LOCKFREE_H_ #include #include @@ -15,14 +14,14 @@ #include /** - * @brief RTIO Single Producer Single Consumer (SPSC) Queue API - * @defgroup rtio_spsc RTIO SPSC API - * @ingroup rtio + * @brief Single Producer Single Consumer (SPSC) Lockfree Queue API + * @defgroup spsc_lockfree SPSC API + * @ingroup datastructure_apis * @{ */ /** - * @file rtio_spsc.h + * @file spsc_lockfree.h * * @brief A lock-free and type safe power of 2 fixed sized single producer * single consumer (SPSC) queue using a ringbuffer and atomics to ensure @@ -57,7 +56,7 @@ * * @warning Not to be manipulated without the macros! */ -struct rtio_spsc { +struct spsc { /* private value only the producer thread should mutate */ unsigned long acquire; @@ -75,53 +74,54 @@ struct rtio_spsc { }; /** - * @brief Statically initialize an rtio_spsc + * @brief Statically initialize an spsc * * @param sz Size of the spsc, must be power of 2 (ex: 2, 4, 8) * @param buf Buffer pointer */ -#define RTIO_SPSC_INITIALIZER(sz, buf) \ - { \ - ._spsc = { \ - .acquire = 0, \ - .consume = 0, \ - .in = ATOMIC_INIT(0), \ - .out = ATOMIC_INIT(0), \ - .mask = sz - 1, \ - }, \ - .buffer = buf, \ +#define SPSC_INITIALIZER(sz, buf) \ + { \ + ._spsc = \ + { \ + .acquire = 0, \ + .consume = 0, \ + .in = ATOMIC_INIT(0), \ + .out = ATOMIC_INIT(0), \ + .mask = sz - 1, \ + }, \ + .buffer = buf, \ } /** - * @brief Declare an anonymous struct type for an rtio_spsc + * @brief Declare an anonymous struct type for an spsc * * @param name Name of the spsc symbol to be provided * @param type Type stored in the spsc */ -#define RTIO_SPSC_DECLARE(name, type) \ - static struct rtio_spsc_##name { \ - struct rtio_spsc _spsc; \ - type * const buffer; \ +#define SPSC_DECLARE(name, type) \ + static struct spsc_##name { \ + struct spsc _spsc; \ + type * const buffer; \ } /** - * @brief Define an rtio_spsc with a fixed size + * @brief Define an spsc with a fixed size * * @param name Name of the spsc symbol to be provided * @param type Type stored in the spsc * @param sz Size of the spsc, must be power of 2 (ex: 2, 4, 8) */ -#define RTIO_SPSC_DEFINE(name, type, sz) \ - BUILD_ASSERT(IS_POWER_OF_TWO(sz)); \ - static type __spsc_buf_##name[sz]; \ - RTIO_SPSC_DECLARE(name, type) name = RTIO_SPSC_INITIALIZER(sz, __spsc_buf_##name); +#define SPSC_DEFINE(name, type, sz) \ + BUILD_ASSERT(IS_POWER_OF_TWO(sz)); \ + static type __spsc_buf_##name[sz]; \ + SPSC_DECLARE(name, type) name = SPSC_INITIALIZER(sz, __spsc_buf_##name); /** * @brief Size of the SPSC queue * * @param spsc SPSC reference */ -#define rtio_spsc_size(spsc) ((spsc)->_spsc.mask + 1) +#define spsc_size(spsc) ((spsc)->_spsc.mask + 1) /** * @private @@ -130,20 +130,19 @@ struct rtio_spsc { * @param spsc SPSC reference * @param i Value to modulo to the size of the spsc */ -#define z_rtio_spsc_mask(spsc, i) ((i) & (spsc)->_spsc.mask) - +#define z_spsc_mask(spsc, i) ((i) & (spsc)->_spsc.mask) /** * @private * @brief Load the current "in" index from the spsc as an unsigned long */ -#define z_rtio_spsc_in(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.in) +#define z_spsc_in(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.in) /** * @private * @brief Load the current "out" index from the spsc as an unsigned long */ -#define z_rtio_spsc_out(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.out) +#define z_spsc_out(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.out) /** * @brief Initialize/reset a spsc such that its empty @@ -153,7 +152,7 @@ struct rtio_spsc { * * @param spsc SPSC to initialize/reset */ -#define rtio_spsc_reset(spsc) \ +#define spsc_reset(spsc) \ ({ \ (spsc)->_spsc.consume = 0; \ (spsc)->_spsc.acquire = 0; \ @@ -168,14 +167,14 @@ struct rtio_spsc { * * @return A pointer to the acquired element or null if the spsc is full */ -#define rtio_spsc_acquire(spsc) \ +#define spsc_acquire(spsc) \ ({ \ - unsigned long idx = z_rtio_spsc_in(spsc) + (spsc)->_spsc.acquire; \ - bool spsc_acq = (idx - z_rtio_spsc_out(spsc)) < rtio_spsc_size(spsc); \ + unsigned long idx = z_spsc_in(spsc) + (spsc)->_spsc.acquire; \ + bool spsc_acq = (idx - z_spsc_out(spsc)) < spsc_size(spsc); \ if (spsc_acq) { \ (spsc)->_spsc.acquire += 1; \ } \ - spsc_acq ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \ + spsc_acq ? &((spsc)->buffer[z_spsc_mask(spsc, idx)]) : NULL; \ }) /** @@ -185,7 +184,7 @@ struct rtio_spsc { * * @param spsc SPSC to produce the previously acquired element or do nothing */ -#define rtio_spsc_produce(spsc) \ +#define spsc_produce(spsc) \ ({ \ if ((spsc)->_spsc.acquire > 0) { \ (spsc)->_spsc.acquire -= 1; \ @@ -201,7 +200,7 @@ struct rtio_spsc { * * @param spsc SPSC to produce all previously acquired elements or do nothing */ -#define rtio_spsc_produce_all(spsc) \ +#define spsc_produce_all(spsc) \ ({ \ if ((spsc)->_spsc.acquire > 0) { \ unsigned long acquired = (spsc)->_spsc.acquire; \ @@ -217,9 +216,9 @@ struct rtio_spsc { * * @param spsc SPSC to drop all previously acquired elements or do nothing */ -#define rtio_spsc_drop_all(spsc) \ - do { \ - (spsc)->_spsc.acquire = 0; \ +#define spsc_drop_all(spsc) \ + do { \ + (spsc)->_spsc.acquire = 0; \ } while (false) /** @@ -229,14 +228,14 @@ struct rtio_spsc { * * @return Pointer to element or null if no consumable elements left */ -#define rtio_spsc_consume(spsc) \ +#define spsc_consume(spsc) \ ({ \ - unsigned long idx = z_rtio_spsc_out(spsc) + (spsc)->_spsc.consume; \ - bool has_consumable = (idx != z_rtio_spsc_in(spsc)); \ + unsigned long idx = z_spsc_out(spsc) + (spsc)->_spsc.consume; \ + bool has_consumable = (idx != z_spsc_in(spsc)); \ if (has_consumable) { \ (spsc)->_spsc.consume += 1; \ } \ - has_consumable ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \ + has_consumable ? &((spsc)->buffer[z_spsc_mask(spsc, idx)]) : NULL; \ }) /** @@ -244,7 +243,7 @@ struct rtio_spsc { * * @param spsc SPSC to release consumed element or do nothing */ -#define rtio_spsc_release(spsc) \ +#define spsc_release(spsc) \ ({ \ if ((spsc)->_spsc.consume > 0) { \ (spsc)->_spsc.consume -= 1; \ @@ -252,13 +251,12 @@ struct rtio_spsc { } \ }) - /** * @brief Release all consumed elements * * @param spsc SPSC to release consumed elements or do nothing */ -#define rtio_spsc_release_all(spsc) \ +#define spsc_release_all(spsc) \ ({ \ if ((spsc)->_spsc.consume > 0) { \ unsigned long consumed = (spsc)->_spsc.consume; \ @@ -272,19 +270,15 @@ struct rtio_spsc { * * @param spsc SPSC to get item count for */ -#define rtio_spsc_acquirable(spsc) \ - ({ \ - (((spsc)->_spsc.in + (spsc)->_spsc.acquire) - (spsc)->_spsc.out) - \ - rtio_spsc_size(spsc); \ - }) +#define spsc_acquirable(spsc) \ + ({ (((spsc)->_spsc.in + (spsc)->_spsc.acquire) - (spsc)->_spsc.out) - spsc_size(spsc); }) /** * @brief Count of consumables in spsc * * @param spsc SPSC to get item count for */ -#define rtio_spsc_consumable(spsc) \ - ({ (spsc)->_spsc.in - (spsc)->_spsc.out - (spsc)->_spsc.consume; }) +#define spsc_consumable(spsc) ({ (spsc)->_spsc.in - (spsc)->_spsc.out - (spsc)->_spsc.consume; }) /** * @brief Peek at the first available item in queue @@ -293,11 +287,11 @@ struct rtio_spsc { * * @return Pointer to element or null if no consumable elements left */ -#define rtio_spsc_peek(spsc) \ +#define spsc_peek(spsc) \ ({ \ - unsigned long idx = z_rtio_spsc_out(spsc) + (spsc)->_spsc.consume; \ - bool has_consumable = (idx != z_rtio_spsc_in(spsc)); \ - has_consumable ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \ + unsigned long idx = z_spsc_out(spsc) + (spsc)->_spsc.consume; \ + bool has_consumable = (idx != z_spsc_in(spsc)); \ + has_consumable ? &((spsc)->buffer[z_spsc_mask(spsc, idx)]) : NULL; \ }) /** @@ -309,12 +303,12 @@ struct rtio_spsc { * * @return Pointer to element or null if none left */ -#define rtio_spsc_next(spsc, item) \ +#define spsc_next(spsc, item) \ ({ \ unsigned long idx = ((item) - (spsc)->buffer); \ - bool has_next = z_rtio_spsc_mask(spsc, (idx + 1)) != \ - (z_rtio_spsc_mask(spsc, z_rtio_spsc_in(spsc))); \ - has_next ? &((spsc)->buffer[z_rtio_spsc_mask((spsc), idx + 1)]) : NULL; \ + bool has_next = \ + z_spsc_mask(spsc, (idx + 1)) != (z_spsc_mask(spsc, z_spsc_in(spsc))); \ + has_next ? &((spsc)->buffer[z_spsc_mask((spsc), idx + 1)]) : NULL; \ }) /** @@ -325,15 +319,15 @@ struct rtio_spsc { * * @return Pointer to element or null if none left */ -#define rtio_spsc_prev(spsc, item) \ +#define spsc_prev(spsc, item) \ ({ \ unsigned long idx = ((item) - &(spsc)->buffer[0]) / sizeof((spsc)->buffer[0]); \ - bool has_prev = idx != z_rtio_spsc_mask(spsc, z_rtio_spsc_out(spsc)); \ - has_prev ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx - 1)]) : NULL; \ + bool has_prev = idx != z_spsc_mask(spsc, z_spsc_out(spsc)); \ + has_prev ? &((spsc)->buffer[z_spsc_mask(spsc, idx - 1)]) : NULL; \ }) /** * @} */ -#endif /* ZEPHYR_RTIO_SPSC_H_ */ +#endif /* ZEPHYR_SYS_SPSC_LOCKFREE_H_ */ diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index b457862bb97704..fe04c058b1e4af 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -271,6 +271,16 @@ extern "C" { ((type *)(((char *)(ptr)) - offsetof(type, field))); \ }) +/** + * @brief Report the size of a struct field in bytes. + * + * @param type The structure containing the field of interest. + * @param member The field to return the size of. + * + * @return The field size. + */ +#define SIZEOF_FIELD(type, member) sizeof((((type *)0)->member)) + /** * @brief Concatenate input arguments * diff --git a/include/zephyr/tracing/tracing.h b/include/zephyr/tracing/tracing.h index dc14830288683a..d243c27de969e9 100644 --- a/include/zephyr/tracing/tracing.h +++ b/include/zephyr/tracing/tracing.h @@ -2026,6 +2026,304 @@ /** @} */ /* end of subsys_tracing_apis_pm_device_runtime */ +/** + * @brief Network Socket Tracing APIs + * @defgroup subsys_tracing_apis_socket Network Socket Tracing APIs + * @{ + */ + +/** + * @brief Trace init of network sockets + * @param socket Network socket is returned + * @param family Socket address family + * @param type Socket type + * @param proto Socket protocol + */ +#define sys_port_trace_socket_init(socket, family, type, proto) + +/** + * @brief Trace close of network sockets + * @param socket Socket object + */ +#define sys_port_trace_socket_close_enter(socket) + +/** + * @brief Trace network socket close attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_close_exit(socket, ret) + +/** + * @brief Trace shutdown of network sockets + * @param socket Socket object + * @param how Socket shutdown type + */ +#define sys_port_trace_socket_shutdown_enter(socket, how) + +/** + * @brief Trace network socket shutdown attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_shutdown_exit(socket, ret) + +/** + * @brief Trace bind of network sockets + * @param socket Socket object + * @param addr Network address to bind + * @param addrlen Address length + */ +#define sys_port_trace_socket_bind_enter(socket, addr, addrlen) + +/** + * @brief Trace network socket bind attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_bind_exit(socket, ret) + +/** + * @brief Trace connect of network sockets + * @param socket Socket object + * @param addr Network address to bind + * @param addrlen Address length + */ +#define sys_port_trace_socket_connect_enter(socket, addr, addrlen) + +/** + * @brief Trace network socket connect attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_connect_exit(socket, ret) + +/** + * @brief Trace listen of network sockets + * @param socket Socket object + * @param backlog Socket backlog length + */ +#define sys_port_trace_socket_listen_enter(socket, backlog) + +/** + * @brief Trace network socket listen attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_listen_exit(socket, ret) + +/** + * @brief Trace accept of network sockets + * @param socket Socket object + */ +#define sys_port_trace_socket_accept_enter(socket) + +/** + * @brief Trace network socket accept attempt + * @param socket Socket object + * @param addr Peer network address + * @param addrlen Network address length + * @param ret Return value + */ +#define sys_port_trace_socket_accept_exit(socket, addr, addrlen, ret) + +/** + * @brief Trace sendto of network sockets + * @param socket Socket object + * @param len Length of the data to send + * @param flags Flags for this send operation + * @param dest_addr Destination network address + * @param addrlen Network address length + */ +#define sys_port_trace_socket_sendto_enter(socket, len, flags, dest_addr, addrlen) + +/** + * @brief Trace network socket sendto attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_sendto_exit(socket, ret) + +/** + * @brief Trace sendmsg of network sockets + * @param socket Socket object + * @param msg Data to send + * @param flags Flags for this send operation + */ +#define sys_port_trace_socket_sendmsg_enter(socket, msg, flags) + +/** + * @brief Trace network socket sendmsg attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_sendmsg_exit(socket, ret) + +/** + * @brief Trace recvfrom of network sockets + * @param socket Socket object + * @param max_len Maximum length of the data we can receive + * @param flags Flags for this receive operation + * @param addr Remote network address + * @param addrlen Network address length + */ +#define sys_port_trace_socket_recvfrom_enter(socket, max_len, flags, addr, addrlen) + +/** + * @brief Trace network socket recvfrom attempt + * @param socket Socket object + * @param src_addr Peer network address that send the data + * @param addrlen Length of the network address + * @param ret Return value + */ +#define sys_port_trace_socket_recvfrom_exit(socket, src_addr, addrlen, ret) + +/** + * @brief Trace recvmsg of network sockets + * @param socket Socket object + * @param msg Message buffer to receive + * @param flags Flags for this receive operation + */ +#define sys_port_trace_socket_recvmsg_enter(socket, msg, flags) + +/** + * @brief Trace network socket recvmsg attempt + * @param socket Socket object + * @param msg Message buffer received + * @param ret Return value + */ +#define sys_port_trace_socket_recvmsg_exit(socket, msg, ret) + +/** + * @brief Trace fcntl of network sockets + * @param socket Socket object + * @param cmd Command to set for this socket + * @param flags Flags for this receive operation + */ +#define sys_port_trace_socket_fcntl_enter(socket, cmd, flags) + +/** + * @brief Trace network socket fcntl attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_fcntl_exit(socket, ret) + +/** + * @brief Trace ioctl of network sockets + * @param socket Socket object + * @param req Request to set for this socket + */ +#define sys_port_trace_socket_ioctl_enter(socket, req) + +/** + * @brief Trace network socket ioctl attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_ioctl_exit(socket, ret) + +/** + * @brief Trace polling of network sockets + * @param fds Set of socket object + * @param nfds Number of socket objects in the set + * @param timeout Timeout for the poll operation + */ +#define sys_port_trace_socket_poll_enter(fds, nfds, timeout) + +/** + * @brief Trace network socket poll attempt + * @param fds Set of socket object + * @param nfds Number of socket objects in the set + * @param ret Return value + */ +#define sys_port_trace_socket_poll_exit(fds, nfds, ret) + +/** + * @brief Trace getsockopt of network sockets + * @param socket Socket object + * @param level Option level + * @param optname Option name + */ +#define sys_port_trace_socket_getsockopt_enter(socket, level, optname) + +/** + * @brief Trace network socket getsockopt attempt + * @param socket Socket object + * @param level Option level + * @param optname Option name + * @param optval Option value + * @param optlen Option value length + * @param ret Return value + */ +#define sys_port_trace_socket_getsockopt_exit(socket, level, optname, optval, optlen, ret) + +/** + * @brief Trace setsockopt of network sockets + * @param socket Socket object + * @param level Option level + * @param optname Option name + * @param optval Option value + * @param optlen Option value length + */ +#define sys_port_trace_socket_setsockopt_enter(socket, level, optname, optval, optlen) + +/** + * @brief Trace network socket setsockopt attempt + * @param socket Socket object + * @param ret Return value + */ +#define sys_port_trace_socket_setsockopt_exit(socket, ret) + +/** + * @brief Trace getpeername of network sockets + * @param socket Socket object + */ +#define sys_port_trace_socket_getpeername_enter(socket) + +/** + * @brief Trace network socket getpeername attempt + * @param socket Socket object + * @param addr Peer socket network address + * @param addrlen Length of the network address + * @param ret Return value + */ +#define sys_port_trace_socket_getpeername_exit(socket, addr, addrlen, ret) + +/** + * @brief Trace getsockname of network sockets + * @param socket Socket object + */ +#define sys_port_trace_socket_getsockname_enter(socket) + +/** + * @brief Trace network socket getsockname attempt + * @param socket Socket object + * @param addr Local socket network address + * @param addrlen Length of the network address + * @param ret Return value + */ +#define sys_port_trace_socket_getsockname_exit(socket, addr, addrlen, ret) + +/** + * @brief Trace socketpair enter call + * @param family Network address family + * @param type Socket type + * @param proto Socket protocol + * @param sv Socketpair buffer + */ +#define sys_port_trace_socket_socketpair_enter(family, type, proto, sv) + +/** + * @brief Trace network socketpair open attempt + * @param socket_A Socketpair first socket object + * @param socket_B Socketpair second socket object + * @param ret Return value + */ +#define sys_port_trace_socket_socketpair_exit(socket_A, socket_B, ret) + +/** @} */ /* end of subsys_tracing_apis_socket */ + #if defined(CONFIG_PERCEPIO_TRACERECORDER) #include "tracing_tracerecorder.h" #else diff --git a/include/zephyr/tracing/tracing_macros.h b/include/zephyr/tracing/tracing_macros.h index 7ed990617d5ed2..80eed3d0f6d0f5 100644 --- a/include/zephyr/tracing/tracing_macros.h +++ b/include/zephyr/tracing/tracing_macros.h @@ -185,6 +185,12 @@ #define sys_port_trace_pm_is_disabled 1 #endif +#if defined(CONFIG_TRACING_NETWORKING) + #define sys_port_trace_type_mask_socket(trace_call) trace_call +#else + #define sys_port_trace_type_mask_socket(trace_call) +#endif + /* * We cannot positively enumerate all traced APIs, as applications may trace * arbitrary custom APIs we know nothing about. Therefore we demand that tracing diff --git a/include/zephyr/tracing/tracking.h b/include/zephyr/tracing/tracking.h index 8f63fbaffa45ee..bee43153191cce 100644 --- a/include/zephyr/tracing/tracking.h +++ b/include/zephyr/tracing/tracking.h @@ -95,6 +95,9 @@ extern struct k_event *_track_list_k_event; #define sys_port_track_k_event_init(event) \ sys_track_k_event_init(event); +#define sys_port_track_socket_init(sock, family, type, proto) \ + sys_track_socket_init(sock, family, type, proto); + void sys_track_k_timer_init(struct k_timer *timer); void sys_track_k_mem_slab_init(struct k_mem_slab *slab); void sys_track_k_sem_init(struct k_sem *sem); @@ -105,6 +108,7 @@ void sys_track_k_mbox_init(struct k_mbox *mbox); void sys_track_k_pipe_init(struct k_pipe *pipe); void sys_track_k_queue_init(struct k_queue *queue); void sys_track_k_event_init(struct k_event *event); +void sys_track_socket_init(int sock); /** @endcond */ @@ -142,6 +146,7 @@ void sys_track_k_event_init(struct k_event *event); #define sys_port_track_k_heap_free(h) #define sys_port_track_k_heap_init(h) #define sys_port_track_k_event_init(event) +#define sys_port_track_socket_init(sock, family, type, proto) #endif diff --git a/include/zephyr/usb/class/usbd_hid.h b/include/zephyr/usb/class/usbd_hid.h index 5dd6d0dad2354f..9798b081093dad 100644 --- a/include/zephyr/usb/class/usbd_hid.h +++ b/include/zephyr/usb/class/usbd_hid.h @@ -106,8 +106,10 @@ struct hid_device_ops { * feature, input, or output report, which is specified by the argument * type. If there is no report ID in the report descriptor, the id * argument is zero. The callback implementation must check the - * arguments, such as whether the report type is supported, and return - * a nonzero value to indicate an unsupported type or an error. + * arguments, such as whether the report type is supported and the + * report length, and return a negative value to indicate an + * unsupported type or an error, or return the length of the report + * written to the buffer. */ int (*get_report)(const struct device *dev, const uint8_t type, const uint8_t id, diff --git a/include/zephyr/usb/class/usbd_uac2.h b/include/zephyr/usb/class/usbd_uac2.h index 477f8465266fa3..bf76a21ce5338e 100644 --- a/include/zephyr/usb/class/usbd_uac2.h +++ b/include/zephyr/usb/class/usbd_uac2.h @@ -58,7 +58,7 @@ struct uac2_ops { * USB stack calls this function to obtain receive buffer address for * AudioStreaming interface. The buffer is owned by USB stack until * @ref data_recv_cb callback is called. The buffer must be sufficiently - * aligned for use by UDC driver. + * aligned and otherwise suitable for use by UDC driver. * * @param dev USB Audio 2 device * @param terminal Input Terminal ID linked to AudioStreaming interface @@ -126,6 +126,9 @@ void usbd_uac2_set_ops(const struct device *dev, /** * @brief Send audio data to output terminal * + * Data buffer must be sufficiently aligned and otherwise suitable for use by + * UDC driver. + * * @param dev USB Audio 2 device * @param terminal Output Terminal ID linked to AudioStreaming interface * @param data Buffer containing outgoing data diff --git a/include/zephyr/zvfs/eventfd.h b/include/zephyr/zvfs/eventfd.h new file mode 100644 index 00000000000000..a5e1ebfa286752 --- /dev/null +++ b/include/zephyr/zvfs/eventfd.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 Tobias Svehagen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_ZVFS_EVENTFD_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_ZVFS_EVENTFD_H_ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZVFS_EFD_SEMAPHORE 2 +#define ZVFS_EFD_NONBLOCK 0x4000 + +typedef uint64_t zvfs_eventfd_t; + +/** + * @brief Create a file descriptor for ZVFS event notification + * + * The returned file descriptor can be used with POSIX read/write calls or + * with the @ref zvfs_eventfd_read or @ref zvfs_eventfd_write functions. + * + * It also supports polling and by including an eventfd in a call to poll, + * it is possible to signal and wake the polling thread by simply writing to + * the eventfd. + * + * When using read() and write() on a ZVFS eventfd, the size must always be at + * least 8 bytes or the operation will fail with EINVAL. + * + * @return New ZVFS eventfd file descriptor on success, -1 on error + */ +int zvfs_eventfd(unsigned int initval, int flags); + +/** + * @brief Read from a ZVFS eventfd + * + * If call is successful, the value parameter will have the value 1 + * + * @param fd File descriptor + * @param value Pointer for storing the read value + * + * @return 0 on success, -1 on error + */ +int zvfs_eventfd_read(int fd, zvfs_eventfd_t *value); + +/** + * @brief Write to a ZVFS eventfd + * + * @param fd File descriptor + * @param value Value to write + * + * @return 0 on success, -1 on error + */ +int zvfs_eventfd_write(int fd, zvfs_eventfd_t value); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_ZEPHYR_ZVFS_EVENTFD_H_ */ diff --git a/kernel/Kconfig b/kernel/Kconfig index c65ec351fcb3e0..31658b90f3ba86 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -156,7 +156,7 @@ config SCHED_CPU_MASK_PIN_ONLY config MAIN_STACK_SIZE int "Size of stack for initialization and main thread" default 2048 if COVERAGE_GCOV - default 512 if ZTEST && !(RISCV || X86 || ARM || ARC) + default 512 if ZTEST && !(RISCV || X86 || ARM || ARC || NIOS2) default 1024 help When the initialization is complete, the thread executing it then @@ -704,6 +704,9 @@ config PIPES allows a thread to send a byte stream to another thread. Pipes can be used to synchronously transfer chunks of data in whole or in part. + Note that setting this option slightly increases the size of the + thread structure. + config KERNEL_MEM_POOL bool "Use Kernel Memory Pool" default y diff --git a/kernel/Kconfig.device b/kernel/Kconfig.device index f9718c4272d0e6..c0e8b490331eec 100644 --- a/kernel/Kconfig.device +++ b/kernel/Kconfig.device @@ -26,6 +26,13 @@ config DEVICE_MUTABLE Support mutable devices. Mutable devices are instantiated in SRAM instead of Flash and are runtime modifiable in kernel mode. +config DEVICE_DT_METADATA + bool "Store additional devicetree metadata for each device" + help + If enabled, additional data from the devicetree will be stored for + each device. This allows you to use device_get_by_dt_nodelabel(), + device_get_dt_metadata(), etc. + endmenu menu "Initialization Priorities" diff --git a/kernel/Kconfig.smp b/kernel/Kconfig.smp index 22279270b19f0c..da83d1624e060a 100644 --- a/kernel/Kconfig.smp +++ b/kernel/Kconfig.smp @@ -56,12 +56,11 @@ config MP_MAX_NUM_CPUS config SCHED_IPI_SUPPORTED bool help - True if the architecture supports a call to - arch_sched_ipi() to broadcast an interrupt that will call - z_sched_ipi() on other CPUs in the system. Required for - k_thread_abort() to operate with reasonable latency - (otherwise we might have to wait for the other thread to - take an interrupt, which can be arbitrarily far in the + True if the architecture supports a call to arch_sched_broadcast_ipi() + to broadcast an interrupt that will call z_sched_ipi() on other CPUs + in the system. Required for k_thread_abort() to operate with + reasonable latency (otherwise we might have to wait for the other + thread to take an interrupt, which can be arbitrarily far in the future). config TRACE_SCHED_IPI @@ -73,6 +72,24 @@ config TRACE_SCHED_IPI depends on SCHED_IPI_SUPPORTED depends on MP_MAX_NUM_CPUS>1 +config IPI_OPTIMIZE + bool "Optimize IPI delivery" + default n + depends on SCHED_IPI_SUPPORTED && MP_MAX_NUM_CPUS>1 + help + When selected, the kernel will attempt to determine the minimum + set of CPUs that need an IPI to trigger a reschedule in response to + a thread newly made ready for execution. This increases the + computation required at every scheduler operation by a value that is + O(N) in the number of CPUs, and in exchange reduces the number of + interrupts delivered. Which to choose is going to depend on + application behavior. If the architecture also supports directing + IPIs to specific CPUs then this has the potential to signficantly + reduce the number of IPIs (and consequently ISRs) processed by the + system as the number of CPUs increases. If not, the only benefit + would be to not issue any IPIs if the newly readied thread is of + lower priority than all the threads currently executing on other CPUs. + config KERNEL_COHERENCE bool "Place all shared data into coherent memory" depends on ARCH_HAS_COHERENCE diff --git a/kernel/Kconfig.vm b/kernel/Kconfig.vm index 97d6c1f424b3bd..4215df89930d2f 100644 --- a/kernel/Kconfig.vm +++ b/kernel/Kconfig.vm @@ -202,7 +202,7 @@ config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK bool help Use custom memory range check functions instead of the generic - checks in z_mem_phys_addr() and z_mem_virt_addr(). + checks in k_mem_phys_addr() and k_mem_virt_addr(). sys_mm_is_phys_addr_in_range() and sys_mm_is_virt_addr_in_range() must be implemented. diff --git a/kernel/banner.c b/kernel/banner.c index d2a431edd96798..1d95f2b18350c3 100644 --- a/kernel/banner.c +++ b/kernel/banner.c @@ -27,7 +27,9 @@ void boot_banner(void) { #if defined(CONFIG_BOOT_DELAY) && (CONFIG_BOOT_DELAY > 0) +#ifdef CONFIG_BOOT_BANNER printk("***** delaying boot " DELAY_STR "ms (per build configuration) *****\n"); +#endif /* CONFIG_BOOT_BANNER */ k_busy_wait(CONFIG_BOOT_DELAY * USEC_PER_MSEC); #endif /* defined(CONFIG_BOOT_DELAY) && (CONFIG_BOOT_DELAY > 0) */ diff --git a/kernel/device.c b/kernel/device.c index 37233f58372242..64d5a85e4503b8 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -77,6 +78,57 @@ static inline bool z_vrfy_device_is_ready(const struct device *dev) #include #endif /* CONFIG_USERSPACE */ +#ifdef CONFIG_DEVICE_DT_METADATA +const struct device *z_impl_device_get_by_dt_nodelabel(const char *nodelabel) +{ + /* For consistency with device_get_binding(). */ + if ((nodelabel == NULL) || (nodelabel[0] == '\0')) { + return NULL; + } + + /* Unlike device_get_binding(), which has a history of being + * used in application code, we don't expect + * device_get_by_dt_nodelabel() to be used outside of + * scenarios where a human is in the loop. The shell is the + * main expected use case. Therefore, nodelabel is probably + * not the same pointer as any of the entry->nodelabel + * elements. We therefore skip the pointer comparison that + * device_get_binding() does. + */ + STRUCT_SECTION_FOREACH(device, dev) { + const struct device_dt_nodelabels *nl = device_get_dt_nodelabels(dev); + + if (!z_impl_device_is_ready(dev)) { + continue; + } + + for (size_t i = 0; i < nl->num_nodelabels; i++) { + const char *dev_nodelabel = nl->nodelabels[i]; + + if (strcmp(nodelabel, dev_nodelabel) == 0) { + return dev; + } + } + } + + return NULL; +} + +#ifdef CONFIG_USERSPACE +static inline const struct device *z_vrfy_device_get_by_dt_nodelabel(const char *nodelabel) +{ + const char nl_copy[Z_DEVICE_MAX_NODELABEL_LEN]; + + if (k_usermode_string_copy(nl_copy, (char *)nodelabel, sizeof(nl_copy)) != 0) { + return NULL; + } + + return z_impl_device_get_by_dt_nodelabel(nl_copy); +} +#include +#endif /* CONFIG_USERSPACE */ +#endif /* CONFIG_DEVICE_DT_METADATA */ + size_t z_device_get_all_static(struct device const **devices) { size_t cnt; diff --git a/kernel/fatal.c b/kernel/fatal.c index caee224bf5f633..06966066e30205 100644 --- a/kernel/fatal.c +++ b/kernel/fatal.c @@ -35,7 +35,7 @@ FUNC_NORETURN __weak void arch_system_halt(unsigned int reason) /* LCOV_EXCL_START */ __weak void k_sys_fatal_error_handler(unsigned int reason, - const z_arch_esf_t *esf) + const struct arch_esf *esf) { ARG_UNUSED(esf); @@ -82,7 +82,7 @@ FUNC_NORETURN void k_fatal_halt(unsigned int reason) } /* LCOV_EXCL_STOP */ -void z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) +void z_fatal_error(unsigned int reason, const struct arch_esf *esf) { /* We can't allow this code to be preempted, but don't need to * synchronize between CPUs, so an arch-layer lock is diff --git a/kernel/include/gen_offset.h b/kernel/include/gen_offset.h index bdc9f785809a6e..46a651cf28da7b 100644 --- a/kernel/include/gen_offset.h +++ b/kernel/include/gen_offset.h @@ -84,7 +84,13 @@ #define GEN_OFFSET_SYM(S, M) \ GEN_ABSOLUTE_SYM(__##S##_##M##_##OFFSET, offsetof(S, M)) +#define GEN_OFFSET_STRUCT(S, M) \ + GEN_ABSOLUTE_SYM(__struct_##S##_##M##_##OFFSET, offsetof(struct S, M)) + #define GEN_NAMED_OFFSET_SYM(S, M, N) \ GEN_ABSOLUTE_SYM(__##S##_##N##_##OFFSET, offsetof(S, M)) +#define GEN_NAMED_OFFSET_STRUCT(S, M, N) \ + GEN_ABSOLUTE_SYM(__struct_##S##_##N##_##OFFSET, offsetof(struct S, M)) + #endif /* ZEPHYR_KERNEL_INCLUDE_GEN_OFFSET_H_ */ diff --git a/kernel/include/ipi.h b/kernel/include/ipi.h index 77105cac16834e..b353a676d4624d 100644 --- a/kernel/include/ipi.h +++ b/kernel/include/ipi.h @@ -7,13 +7,25 @@ #ifndef ZEPHYR_KERNEL_INCLUDE_IPI_H_ #define ZEPHYR_KERNEL_INCLUDE_IPI_H_ +#include +#include +#include + +#define IPI_ALL_CPUS_MASK ((1 << CONFIG_MP_MAX_NUM_CPUS) - 1) + +#define IPI_CPU_MASK(cpu_id) \ + (IS_ENABLED(CONFIG_IPI_OPTIMIZE) ? BIT(cpu_id) : IPI_ALL_CPUS_MASK) + + /* defined in ipi.c when CONFIG_SMP=y */ #ifdef CONFIG_SMP -void flag_ipi(void); +void flag_ipi(uint32_t ipi_mask); void signal_pending_ipi(void); +atomic_val_t ipi_mask_create(struct k_thread *thread); #else -#define flag_ipi() do { } while (false) +#define flag_ipi(ipi_mask) do { } while (false) #define signal_pending_ipi() do { } while (false) #endif /* CONFIG_SMP */ + #endif /* ZEPHYR_KERNEL_INCLUDE_IPI_H_ */ diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index 9860070542edf2..7ff269b69f5e8d 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -341,7 +341,7 @@ int arch_page_phys_get(void *virt, uintptr_t *phys); * example of this is reserved regions in the first megabyte on PC-like systems. * * Implementations of this function should mark all relevant entries in - * z_page_frames with K_PAGE_FRAME_RESERVED. This function is called at + * k_mem_page_frames with K_PAGE_FRAME_RESERVED. This function is called at * early system initialization with mm_lock held. */ void arch_reserved_pages_update(void); @@ -390,9 +390,9 @@ void arch_mem_page_in(void *addr, uintptr_t phys); * Update current page tables for a temporary mapping * * Map a physical page frame address to a special virtual address - * Z_SCRATCH_PAGE, with read/write access to supervisor mode, such that + * K_MEM_SCRATCH_PAGE, with read/write access to supervisor mode, such that * when this function returns, the calling context can read/write the page - * frame's contents from the Z_SCRATCH_PAGE address. + * frame's contents from the K_MEM_SCRATCH_PAGE address. * * This mapping only needs to be done on the current set of page tables, * as it is only used for a short period of time exclusively by the caller. @@ -583,7 +583,7 @@ static inline void arch_nop(void); * * @param esf Exception Stack Frame (arch-specific) */ -void arch_coredump_info_dump(const z_arch_esf_t *esf); +void arch_coredump_info_dump(const struct arch_esf *esf); /** * @brief Get the target code specified by the architecture. diff --git a/kernel/include/mmu.h b/kernel/include/mmu.h index ddfbdd2e16e1d8..e4a9f84d334ac3 100644 --- a/kernel/include/mmu.h +++ b/kernel/include/mmu.h @@ -15,69 +15,130 @@ #include #include -/* - * At present, page frame management is only done for main system RAM, - * and we generate paging structures based on CONFIG_SRAM_BASE_ADDRESS - * and CONFIG_SRAM_SIZE. +/** Start address of physical memory. */ +#define K_MEM_PHYS_RAM_START ((uintptr_t)CONFIG_SRAM_BASE_ADDRESS) + +/** Size of physical memory. */ +#define K_MEM_PHYS_RAM_SIZE (KB(CONFIG_SRAM_SIZE)) + +/** End address (exclusive) of physical memory. */ +#define K_MEM_PHYS_RAM_END (K_MEM_PHYS_RAM_START + K_MEM_PHYS_RAM_SIZE) + +/** Start address of virtual memory. */ +#define K_MEM_VIRT_RAM_START ((uint8_t *)CONFIG_KERNEL_VM_BASE) + +/** Size of virtual memory. */ +#define K_MEM_VIRT_RAM_SIZE ((size_t)CONFIG_KERNEL_VM_SIZE) + +/** End address (exclusive) of virtual memory. */ +#define K_MEM_VIRT_RAM_END (K_MEM_VIRT_RAM_START + K_MEM_VIRT_RAM_SIZE) + +/** Boot-time virtual start address of the kernel image. */ +#define K_MEM_KERNEL_VIRT_START ((uint8_t *)&z_mapped_start[0]) + +/** Boot-time virtual end address of the kernel image. */ +#define K_MEM_KERNEL_VIRT_END ((uint8_t *)&z_mapped_end[0]) + +/** Boot-time virtual address space size of the kernel image. */ +#define K_MEM_KERNEL_VIRT_SIZE (K_MEM_KERNEL_VIRT_END - K_MEM_KERNEL_VIRT_START) + +/** + * @brief Offset for translating between static physical and virtual addresses. * - * If we have other RAM regions (DCCM, etc) these typically have special - * properties and shouldn't be used generically for demand paging or - * anonymous mappings. We don't currently maintain an ontology of these in the - * core kernel. + * @note Do not use directly unless you know exactly what you are going. */ -#define Z_PHYS_RAM_START ((uintptr_t)CONFIG_SRAM_BASE_ADDRESS) -#define Z_PHYS_RAM_SIZE (KB(CONFIG_SRAM_SIZE)) -#define Z_PHYS_RAM_END (Z_PHYS_RAM_START + Z_PHYS_RAM_SIZE) -#define Z_NUM_PAGE_FRAMES (Z_PHYS_RAM_SIZE / (size_t)CONFIG_MMU_PAGE_SIZE) - -/** End virtual address of virtual address space */ -#define Z_VIRT_RAM_START ((uint8_t *)CONFIG_KERNEL_VM_BASE) -#define Z_VIRT_RAM_SIZE ((size_t)CONFIG_KERNEL_VM_SIZE) -#define Z_VIRT_RAM_END (Z_VIRT_RAM_START + Z_VIRT_RAM_SIZE) - -/* Boot-time virtual location of the kernel image. */ -#define Z_KERNEL_VIRT_START ((uint8_t *)&z_mapped_start[0]) -#define Z_KERNEL_VIRT_END ((uint8_t *)&z_mapped_end[0]) -#define Z_KERNEL_VIRT_SIZE (Z_KERNEL_VIRT_END - Z_KERNEL_VIRT_START) - -#define Z_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ - (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) - -/* Only applies to boot RAM mappings within the Zephyr image that have never - * been remapped or paged out. Never use this unless you know exactly what you - * are doing. +#define K_MEM_VM_OFFSET \ + ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \ + (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET)) + +/** + * @brief Get physical address from virtual address for boot RAM mappings. + * + * @note Only applies to boot RAM mappings within the Zephyr image that have never + * been remapped or paged out. Never use this unless you know exactly what you + * are doing. + * + * @param virt Virtual address. + * + * @return Physical address. */ -#define Z_BOOT_VIRT_TO_PHYS(virt) ((uintptr_t)(((uint8_t *)virt) - Z_VM_OFFSET)) -#define Z_BOOT_PHYS_TO_VIRT(phys) ((uint8_t *)(((uintptr_t)phys) + Z_VM_OFFSET)) +#define K_MEM_BOOT_VIRT_TO_PHYS(virt) ((uintptr_t)(((uint8_t *)(virt)) - K_MEM_VM_OFFSET)) +/** + * @brief Get virtual address from physical address for boot RAM mappings. + * + * @note Only applies to boot RAM mappings within the Zephyr image that have never + * been remapped or paged out. Never use this unless you know exactly what you + * are doing. + * + * @param phys Physical address. + * + * @return Virtual address. + */ +#define K_MEM_BOOT_PHYS_TO_VIRT(phys) ((uint8_t *)(((uintptr_t)(phys)) + K_MEM_VM_OFFSET)) + +/** + * @def K_MEM_VM_FREE_START + * @brief Start address of unused, available virtual addresses. + * + * This is the start address of the virtual memory region where + * addresses can be allocated for memory mapping. This depends on whether + * CONFIG_ARCH_MAPS_ALL_RAM is enabled: + * + * - If it is enabled, which means all physical memory are mapped in virtual + * memory address space, and it is the same as + * (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE). + * + * - If it is disabled, K_MEM_VM_FREE_START is the same K_MEM_KERNEL_VIRT_END which + * is the end of the kernel image. + * + */ #ifdef CONFIG_ARCH_MAPS_ALL_RAM -#define Z_FREE_VM_START Z_BOOT_PHYS_TO_VIRT(Z_PHYS_RAM_END) +#define K_MEM_VM_FREE_START K_MEM_BOOT_PHYS_TO_VIRT(K_MEM_PHYS_RAM_END) #else -#define Z_FREE_VM_START Z_KERNEL_VIRT_END +#define K_MEM_VM_FREE_START K_MEM_KERNEL_VIRT_END #endif /* CONFIG_ARCH_MAPS_ALL_RAM */ -/* +/** + * @defgroup kernel_mm_page_frame_apis Kernel Memory Page Frame Management APIs + * @ingroup kernel_mm_internal_apis + * @{ + * * Macros and data structures for physical page frame accounting, * APIs for use by eviction and backing store algorithms. This code * is otherwise not application-facing. */ +/** + * @brief Number of page frames. + * + * At present, page frame management is only done for main system RAM, + * and we generate paging structures based on CONFIG_SRAM_BASE_ADDRESS + * and CONFIG_SRAM_SIZE. + * + * If we have other RAM regions (DCCM, etc) these typically have special + * properties and shouldn't be used generically for demand paging or + * anonymous mappings. We don't currently maintain an ontology of these in the + * core kernel. + */ +#define K_MEM_NUM_PAGE_FRAMES (K_MEM_PHYS_RAM_SIZE / (size_t)CONFIG_MMU_PAGE_SIZE) + /* - * z_page_frame flags bits + * k_mem_page_frame flags bits * * Requirements: - * - Z_PAGE_FRAME_FREE must be one of the possible sfnode flag bits + * - K_MEM_PAGE_FRAME_FREE must be one of the possible sfnode flag bits * - All bit values must be lower than CONFIG_MMU_PAGE_SIZE */ /** This physical page is free and part of the free list */ -#define Z_PAGE_FRAME_FREE BIT(0) +#define K_MEM_PAGE_FRAME_FREE BIT(0) /** This physical page is reserved by hardware; we will never use it */ -#define Z_PAGE_FRAME_RESERVED BIT(1) +#define K_MEM_PAGE_FRAME_RESERVED BIT(1) /** This page contains critical kernel data and will never be swapped */ -#define Z_PAGE_FRAME_PINNED BIT(2) +#define K_MEM_PAGE_FRAME_PINNED BIT(2) /** * This physical page is mapped to some virtual memory address @@ -85,17 +146,17 @@ * Currently, we just support one mapping per page frame. If a page frame * is mapped to multiple virtual pages then it must be pinned. */ -#define Z_PAGE_FRAME_MAPPED BIT(3) +#define K_MEM_PAGE_FRAME_MAPPED BIT(3) /** * This page frame is currently involved in a page-in/out operation */ -#define Z_PAGE_FRAME_BUSY BIT(4) +#define K_MEM_PAGE_FRAME_BUSY BIT(4) /** * This page frame has a clean copy in the backing store */ -#define Z_PAGE_FRAME_BACKED BIT(5) +#define K_MEM_PAGE_FRAME_BACKED BIT(5) /** * Data structure for physical page frames @@ -103,17 +164,17 @@ * An array of these is instantiated, one element per physical RAM page. * Hence it's necessary to constrain its size as much as possible. */ -struct z_page_frame { +struct k_mem_page_frame { union { /* - * If mapped, Z_PAGE_FRAME_* flags and virtual address + * If mapped, K_MEM_PAGE_FRAME_* flags and virtual address * this page is mapped to. */ uintptr_t va_and_flags; /* * If unmapped and available, free pages list membership - * with the Z_PAGE_FRAME_FREE flag. + * with the K_MEM_PAGE_FRAME_FREE flag. */ sys_sfnode_t node; }; @@ -121,68 +182,68 @@ struct z_page_frame { /* Backing store and eviction algorithms may both need to * require additional per-frame custom data for accounting purposes. * They should declare their own array with indices matching - * z_page_frames[] ones whenever possible. + * k_mem_page_frames[] ones whenever possible. * They may also want additional flags bits that could be stored here * and they shouldn't clobber each other. At all costs the total - * size of struct z_page_frame must be minimized. + * size of struct k_mem_page_frame must be minimized. */ }; /* Note: this must be false for the other flag bits to be valid */ -static inline bool z_page_frame_is_free(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_free(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_FREE) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_FREE) != 0U; } -static inline bool z_page_frame_is_pinned(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_pinned(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_PINNED) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_PINNED) != 0U; } -static inline bool z_page_frame_is_reserved(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_reserved(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_RESERVED) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_RESERVED) != 0U; } -static inline bool z_page_frame_is_mapped(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_mapped(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_MAPPED) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_MAPPED) != 0U; } -static inline bool z_page_frame_is_busy(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_busy(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_BUSY) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_BUSY) != 0U; } -static inline bool z_page_frame_is_backed(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_backed(struct k_mem_page_frame *pf) { - return (pf->va_and_flags & Z_PAGE_FRAME_BACKED) != 0U; + return (pf->va_and_flags & K_MEM_PAGE_FRAME_BACKED) != 0U; } -static inline bool z_page_frame_is_evictable(struct z_page_frame *pf) +static inline bool k_mem_page_frame_is_evictable(struct k_mem_page_frame *pf) { - return (!z_page_frame_is_free(pf) && - !z_page_frame_is_reserved(pf) && - z_page_frame_is_mapped(pf) && - !z_page_frame_is_pinned(pf) && - !z_page_frame_is_busy(pf)); + return (!k_mem_page_frame_is_free(pf) && + !k_mem_page_frame_is_reserved(pf) && + k_mem_page_frame_is_mapped(pf) && + !k_mem_page_frame_is_pinned(pf) && + !k_mem_page_frame_is_busy(pf)); } /* If true, page is not being used for anything, is not reserved, is not * a member of some free pages list, isn't busy, and is ready to be mapped * in memory */ -static inline bool z_page_frame_is_available(struct z_page_frame *page) +static inline bool k_mem_page_frame_is_available(struct k_mem_page_frame *page) { return page->va_and_flags == 0U; } -static inline void z_page_frame_set(struct z_page_frame *pf, uint8_t flags) +static inline void k_mem_page_frame_set(struct k_mem_page_frame *pf, uint8_t flags) { pf->va_and_flags |= flags; } -static inline void z_page_frame_clear(struct z_page_frame *pf, uint8_t flags) +static inline void k_mem_page_frame_clear(struct k_mem_page_frame *pf, uint8_t flags) { /* ensure bit inversion to follow is done on the proper type width */ uintptr_t wide_flags = flags; @@ -190,46 +251,46 @@ static inline void z_page_frame_clear(struct z_page_frame *pf, uint8_t flags) pf->va_and_flags &= ~wide_flags; } -static inline void z_assert_phys_aligned(uintptr_t phys) +static inline void k_mem_assert_phys_aligned(uintptr_t phys) { __ASSERT(phys % CONFIG_MMU_PAGE_SIZE == 0U, "physical address 0x%lx is not page-aligned", phys); (void)phys; } -extern struct z_page_frame z_page_frames[Z_NUM_PAGE_FRAMES]; +extern struct k_mem_page_frame k_mem_page_frames[K_MEM_NUM_PAGE_FRAMES]; -static inline uintptr_t z_page_frame_to_phys(struct z_page_frame *pf) +static inline uintptr_t k_mem_page_frame_to_phys(struct k_mem_page_frame *pf) { - return (uintptr_t)((pf - z_page_frames) * CONFIG_MMU_PAGE_SIZE) + - Z_PHYS_RAM_START; + return (uintptr_t)((pf - k_mem_page_frames) * CONFIG_MMU_PAGE_SIZE) + + K_MEM_PHYS_RAM_START; } /* Presumes there is but one mapping in the virtual address space */ -static inline void *z_page_frame_to_virt(struct z_page_frame *pf) +static inline void *k_mem_page_frame_to_virt(struct k_mem_page_frame *pf) { uintptr_t flags_mask = CONFIG_MMU_PAGE_SIZE - 1; return (void *)(pf->va_and_flags & ~flags_mask); } -static inline bool z_is_page_frame(uintptr_t phys) +static inline bool k_mem_is_page_frame(uintptr_t phys) { - z_assert_phys_aligned(phys); - return IN_RANGE(phys, (uintptr_t)Z_PHYS_RAM_START, - (uintptr_t)(Z_PHYS_RAM_END - 1)); + k_mem_assert_phys_aligned(phys); + return IN_RANGE(phys, (uintptr_t)K_MEM_PHYS_RAM_START, + (uintptr_t)(K_MEM_PHYS_RAM_END - 1)); } -static inline struct z_page_frame *z_phys_to_page_frame(uintptr_t phys) +static inline struct k_mem_page_frame *k_mem_phys_to_page_frame(uintptr_t phys) { - __ASSERT(z_is_page_frame(phys), + __ASSERT(k_mem_is_page_frame(phys), "0x%lx not an SRAM physical address", phys); - return &z_page_frames[(phys - Z_PHYS_RAM_START) / - CONFIG_MMU_PAGE_SIZE]; + return &k_mem_page_frames[(phys - K_MEM_PHYS_RAM_START) / + CONFIG_MMU_PAGE_SIZE]; } -static inline void z_mem_assert_virtual_region(uint8_t *addr, size_t size) +static inline void k_mem_assert_virtual_region(uint8_t *addr, size_t size) { __ASSERT((uintptr_t)addr % CONFIG_MMU_PAGE_SIZE == 0U, "unaligned addr %p", addr); @@ -238,35 +299,48 @@ static inline void z_mem_assert_virtual_region(uint8_t *addr, size_t size) __ASSERT(!Z_DETECT_POINTER_OVERFLOW(addr, size), "region %p size %zu zero or wraps around", addr, size); __ASSERT(IN_RANGE((uintptr_t)addr, - (uintptr_t)Z_VIRT_RAM_START, - ((uintptr_t)Z_VIRT_RAM_END - 1)) && + (uintptr_t)K_MEM_VIRT_RAM_START, + ((uintptr_t)K_MEM_VIRT_RAM_END - 1)) && IN_RANGE(((uintptr_t)addr + size - 1), - (uintptr_t)Z_VIRT_RAM_START, - ((uintptr_t)Z_VIRT_RAM_END - 1)), + (uintptr_t)K_MEM_VIRT_RAM_START, + ((uintptr_t)K_MEM_VIRT_RAM_END - 1)), "invalid virtual address region %p (%zu)", addr, size); } -/* Debug function, pretty-print page frame information for all frames +/** + * @brief Pretty-print page frame information for all page frames. + * + * Debug function, pretty-print page frame information for all frames * concisely to printk. */ -void z_page_frames_dump(void); +void k_mem_page_frames_dump(void); /* Convenience macro for iterating over all page frames */ -#define Z_PAGE_FRAME_FOREACH(_phys, _pageframe) \ - for (_phys = Z_PHYS_RAM_START, _pageframe = z_page_frames; \ - _phys < Z_PHYS_RAM_END; \ - _phys += CONFIG_MMU_PAGE_SIZE, _pageframe++) +#define K_MEM_PAGE_FRAME_FOREACH(_phys, _pageframe) \ + for ((_phys) = K_MEM_PHYS_RAM_START, (_pageframe) = k_mem_page_frames; \ + (_phys) < K_MEM_PHYS_RAM_END; \ + (_phys) += CONFIG_MMU_PAGE_SIZE, (_pageframe)++) +/** @} */ + +/** + * @def K_MEM_VM_RESERVED + * @brief Reserve space at the end of virtual memory. + */ #ifdef CONFIG_DEMAND_PAGING /* We reserve a virtual page as a scratch area for page-ins/outs at the end * of the address space */ -#define Z_VM_RESERVED CONFIG_MMU_PAGE_SIZE -#define Z_SCRATCH_PAGE ((void *)((uintptr_t)CONFIG_KERNEL_VM_BASE + \ - (uintptr_t)CONFIG_KERNEL_VM_SIZE - \ - CONFIG_MMU_PAGE_SIZE)) +#define K_MEM_VM_RESERVED CONFIG_MMU_PAGE_SIZE + +/** + * @brief Location of the scratch page used for demand paging. + */ +#define K_MEM_SCRATCH_PAGE ((void *)((uintptr_t)CONFIG_KERNEL_VM_BASE + \ + (uintptr_t)CONFIG_KERNEL_VM_SIZE - \ + CONFIG_MMU_PAGE_SIZE)) #else -#define Z_VM_RESERVED 0 +#define K_MEM_VM_RESERVED 0 #endif /* CONFIG_DEMAND_PAGING */ #ifdef CONFIG_DEMAND_PAGING @@ -282,7 +356,7 @@ void z_page_frames_dump(void); * * @return Number of successful page faults */ -unsigned long z_num_pagefaults_get(void); +unsigned long k_mem_num_pagefaults_get(void); /** * Free a page frame physical address by evicting its contents @@ -301,7 +375,7 @@ unsigned long z_num_pagefaults_get(void); * @retval 0 Success * @retval -ENOMEM Insufficient backing store space */ -int z_page_frame_evict(uintptr_t phys); +int k_mem_page_frame_evict(uintptr_t phys); /** * Handle a page fault for a virtual data page @@ -330,7 +404,8 @@ int z_page_frame_evict(uintptr_t phys); * @retval false This page fault was from an un-mapped page, should * be treated as an error, and not re-tried. */ -bool z_page_fault(void *addr); +bool k_mem_page_fault(void *addr); + #endif /* CONFIG_DEMAND_PAGING */ #endif /* CONFIG_MMU */ #endif /* KERNEL_INCLUDE_MMU_H */ diff --git a/kernel/init.c b/kernel/init.c index 998cb938f1622e..cff9750567dd2a 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -417,8 +417,8 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3) #ifdef CONFIG_MMU /* Invoked here such that backing store or eviction algorithms may * initialize kernel objects, and that all POST_KERNEL and later tasks - * may perform memory management tasks (except for z_phys_map() which - * is allowed at any time) + * may perform memory management tasks (except for + * k_mem_map_phys_bare() which is allowed at any time) */ z_mem_manage_init(); #endif /* CONFIG_MMU */ @@ -474,6 +474,7 @@ static void init_idle_thread(int i) { struct k_thread *thread = &z_idle_threads[i]; k_thread_stack_t *stack = z_idle_stacks[i]; + size_t stack_size = K_KERNEL_STACK_SIZEOF(z_idle_stacks[i]); #ifdef CONFIG_THREAD_NAME @@ -489,7 +490,7 @@ static void init_idle_thread(int i) #endif /* CONFIG_THREAD_NAME */ z_setup_new_thread(thread, stack, - CONFIG_IDLE_STACK_SIZE, idle, &_kernel.cpus[i], + stack_size, idle, &_kernel.cpus[i], NULL, NULL, K_IDLE_PRIO, K_ESSENTIAL, tname); z_mark_thread_as_started(thread); @@ -564,7 +565,8 @@ static char *prepare_multithreading(void) _kernel.ready_q.cache = &z_main_thread; #endif /* CONFIG_SMP */ stack_ptr = z_setup_new_thread(&z_main_thread, z_main_stack, - CONFIG_MAIN_STACK_SIZE, bg_thread_main, + K_THREAD_STACK_SIZEOF(z_main_stack), + bg_thread_main, NULL, NULL, NULL, CONFIG_MAIN_THREAD_PRIORITY, K_ESSENTIAL, "main"); @@ -660,6 +662,9 @@ FUNC_NORETURN void z_cstart(void) /* perform basic hardware initialization */ z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_1); +#if defined(CONFIG_SMP) + arch_smp_init(); +#endif z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2); #ifdef CONFIG_STACK_CANARIES diff --git a/kernel/ipi.c b/kernel/ipi.c index 99693c0ecbfcfb..ee01c4594251ca 100644 --- a/kernel/ipi.c +++ b/kernel/ipi.c @@ -13,15 +13,58 @@ extern void z_trace_sched_ipi(void); #endif -void flag_ipi(void) +void flag_ipi(uint32_t ipi_mask) { #if defined(CONFIG_SCHED_IPI_SUPPORTED) if (arch_num_cpus() > 1) { - _kernel.pending_ipi = true; + atomic_or(&_kernel.pending_ipi, (atomic_val_t)ipi_mask); } #endif /* CONFIG_SCHED_IPI_SUPPORTED */ } +/* Create a bitmask of CPUs that need an IPI. Note: sched_spinlock is held. */ +atomic_val_t ipi_mask_create(struct k_thread *thread) +{ + if (!IS_ENABLED(CONFIG_IPI_OPTIMIZE)) { + return (CONFIG_MP_MAX_NUM_CPUS > 1) ? IPI_ALL_CPUS_MASK : 0; + } + + uint32_t ipi_mask = 0; + uint32_t num_cpus = (uint32_t)arch_num_cpus(); + uint32_t id = _current_cpu->id; + struct k_thread *cpu_thread; + bool executable_on_cpu = true; + + for (uint32_t i = 0; i < num_cpus; i++) { + if (id == i) { + continue; + } + + /* + * An IPI absolutely does not need to be sent if ... + * 1. the CPU is not active, or + * 2. can not execute on the target CPU + * ... and might not need to be sent if ... + * 3. the target CPU's active thread is not preemptible, or + * 4. the target CPU's active thread has a higher priority + * (Items 3 & 4 may be overridden by a metaIRQ thread) + */ + +#if defined(CONFIG_SCHED_CPU_MASK) + executable_on_cpu = ((thread->base.cpu_mask & BIT(i)) != 0); +#endif + + cpu_thread = _kernel.cpus[i].current; + if ((cpu_thread != NULL) && + (((z_sched_prio_cmp(cpu_thread, thread) < 0) && + (thread_is_preemptible(cpu_thread))) || + thread_is_metairq(thread)) && executable_on_cpu) { + ipi_mask |= BIT(i); + } + } + + return (atomic_val_t)ipi_mask; +} void signal_pending_ipi(void) { @@ -34,9 +77,15 @@ void signal_pending_ipi(void) */ #if defined(CONFIG_SCHED_IPI_SUPPORTED) if (arch_num_cpus() > 1) { - if (_kernel.pending_ipi) { - _kernel.pending_ipi = false; - arch_sched_ipi(); + uint32_t cpu_bitmap; + + cpu_bitmap = (uint32_t)atomic_clear(&_kernel.pending_ipi); + if (cpu_bitmap != 0) { +#ifdef CONFIG_ARCH_HAS_DIRECTED_IPIS + arch_sched_directed_ipi(cpu_bitmap); +#else + arch_sched_broadcast_ipi(); +#endif } } #endif /* CONFIG_SCHED_IPI_SUPPORTED */ diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index 9482f0e88c50a2..86aebe38344746 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -103,7 +103,6 @@ static struct k_obj_core_stats_desc mem_slab_stats_desc = { */ static int create_free_list(struct k_mem_slab *slab) { - uint32_t j; char *p; /* blocks must be word aligned */ @@ -113,12 +112,12 @@ static int create_free_list(struct k_mem_slab *slab) } slab->free_list = NULL; - p = slab->buffer; + p = slab->buffer + slab->info.block_size * (slab->info.num_blocks - 1); - for (j = 0U; j < slab->info.num_blocks; j++) { + while (p >= slab->buffer) { *(char **)p = slab->free_list; slab->free_list = p; - p += slab->info.block_size; + p -= slab->info.block_size; } return 0; } @@ -205,6 +204,18 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, return rc; } +#if __ASSERT_ON +static bool slab_ptr_is_good(struct k_mem_slab *slab, const void *ptr) +{ + const char *p = ptr; + ptrdiff_t offset = p - slab->buffer; + + return (offset >= 0) && + (offset < (slab->info.block_size * slab->info.num_blocks)) && + ((offset % slab->info.block_size) == 0); +} +#endif + int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) { k_spinlock_key_t key = k_spin_lock(&slab->lock); @@ -217,6 +228,10 @@ int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) *mem = slab->free_list; slab->free_list = *(char **)(slab->free_list); slab->info.num_used++; + __ASSERT((slab->free_list == NULL && + slab->info.num_used == slab->info.num_blocks) || + slab_ptr_is_good(slab, slab->free_list), + "slab corruption detected"); #ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION slab->info.max_used = MAX(slab->info.num_used, @@ -254,11 +269,7 @@ void k_mem_slab_free(struct k_mem_slab *slab, void *mem) { k_spinlock_key_t key = k_spin_lock(&slab->lock); - __ASSERT(((char *)mem >= slab->buffer) && - ((((char *)mem - slab->buffer) % slab->info.block_size) == 0) && - ((char *)mem <= (slab->buffer + (slab->info.block_size * - (slab->info.num_blocks - 1)))), - "Invalid memory pointer provided"); + __ASSERT(slab_ptr_is_good(slab, mem), "Invalid memory pointer provided"); SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mem_slab, free, slab); if ((slab->free_list == NULL) && IS_ENABLED(CONFIG_MULTITHREADING)) { diff --git a/kernel/mmu.c b/kernel/mmu.c index f74b8c7cf44540..93b8464a329fda 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -31,7 +31,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); * - A page frame is a page-sized physical memory region in RAM. It is a * container where a data page may be placed. It is always referred to by * physical address. We have a convention of using uintptr_t for physical - * addresses. We instantiate a struct z_page_frame to store metadata for + * addresses. We instantiate a struct k_mem_page_frame to store metadata for * every page frame. * * - A data page is a page-sized region of data. It may exist in a page frame, @@ -51,10 +51,10 @@ struct k_spinlock z_mm_lock; */ /* Database of all RAM page frames */ -struct z_page_frame z_page_frames[Z_NUM_PAGE_FRAMES]; +struct k_mem_page_frame k_mem_page_frames[K_MEM_NUM_PAGE_FRAMES]; #if __ASSERT_ON -/* Indicator that z_page_frames has been initialized, many of these APIs do +/* Indicator that k_mem_page_frames has been initialized, many of these APIs do * not work before POST_KERNEL */ static bool page_frames_initialized; @@ -79,24 +79,24 @@ static bool page_frames_initialized; #endif /* COLOR_PAGE_FRAMES */ /* LCOV_EXCL_START */ -static void page_frame_dump(struct z_page_frame *pf) +static void page_frame_dump(struct k_mem_page_frame *pf) { - if (z_page_frame_is_free(pf)) { + if (k_mem_page_frame_is_free(pf)) { COLOR(GREY); printk("-"); - } else if (z_page_frame_is_reserved(pf)) { + } else if (k_mem_page_frame_is_reserved(pf)) { COLOR(CYAN); printk("R"); - } else if (z_page_frame_is_busy(pf)) { + } else if (k_mem_page_frame_is_busy(pf)) { COLOR(MAGENTA); printk("B"); - } else if (z_page_frame_is_pinned(pf)) { + } else if (k_mem_page_frame_is_pinned(pf)) { COLOR(YELLOW); printk("P"); - } else if (z_page_frame_is_available(pf)) { + } else if (k_mem_page_frame_is_available(pf)) { COLOR(GREY); printk("."); - } else if (z_page_frame_is_mapped(pf)) { + } else if (k_mem_page_frame_is_mapped(pf)) { COLOR(DEFAULT); printk("M"); } else { @@ -105,16 +105,16 @@ static void page_frame_dump(struct z_page_frame *pf) } } -void z_page_frames_dump(void) +void k_mem_page_frames_dump(void) { int column = 0; __ASSERT(page_frames_initialized, "%s called too early", __func__); printk("Physical memory from 0x%lx to 0x%lx\n", - Z_PHYS_RAM_START, Z_PHYS_RAM_END); + K_MEM_PHYS_RAM_START, K_MEM_PHYS_RAM_END); - for (int i = 0; i < Z_NUM_PAGE_FRAMES; i++) { - struct z_page_frame *pf = &z_page_frames[i]; + for (int i = 0; i < K_MEM_NUM_PAGE_FRAMES; i++) { + struct k_mem_page_frame *pf = &k_mem_page_frames[i]; page_frame_dump(pf); @@ -133,12 +133,12 @@ void z_page_frames_dump(void) /* LCOV_EXCL_STOP */ #define VIRT_FOREACH(_base, _size, _pos) \ - for (_pos = _base; \ - _pos < ((uint8_t *)_base + _size); _pos += CONFIG_MMU_PAGE_SIZE) + for ((_pos) = (_base); \ + (_pos) < ((uint8_t *)(_base) + (_size)); (_pos) += CONFIG_MMU_PAGE_SIZE) #define PHYS_FOREACH(_base, _size, _pos) \ - for (_pos = _base; \ - _pos < ((uintptr_t)_base + _size); _pos += CONFIG_MMU_PAGE_SIZE) + for ((_pos) = (_base); \ + (_pos) < ((uintptr_t)(_base) + (_size)); (_pos) += CONFIG_MMU_PAGE_SIZE) /* @@ -147,8 +147,8 @@ void z_page_frames_dump(void) * Call all of these functions with z_mm_lock held. * * Overall virtual memory map: When the kernel starts, it resides in - * virtual memory in the region Z_KERNEL_VIRT_START to - * Z_KERNEL_VIRT_END. Unused virtual memory past this, up to the limit + * virtual memory in the region K_MEM_KERNEL_VIRT_START to + * K_MEM_KERNEL_VIRT_END. Unused virtual memory past this, up to the limit * noted by CONFIG_KERNEL_VM_SIZE may be used for runtime memory mappings. * * If CONFIG_ARCH_MAPS_ALL_RAM is set, we do not just map the kernel image, @@ -157,15 +157,15 @@ void z_page_frames_dump(void) * the only guarantee is that such RAM mapping outside of the Zephyr image * won't be disturbed by subsequent memory mapping calls. * - * +--------------+ <- Z_VIRT_RAM_START + * +--------------+ <- K_MEM_VIRT_RAM_START * | Undefined VM | <- May contain ancillary regions like x86_64's locore - * +--------------+ <- Z_KERNEL_VIRT_START (often == Z_VIRT_RAM_START) + * +--------------+ <- K_MEM_KERNEL_VIRT_START (often == K_MEM_VIRT_RAM_START) * | Mapping for | * | main kernel | * | image | * | | * | | - * +--------------+ <- Z_FREE_VM_START + * +--------------+ <- K_MEM_VM_FREE_START * | | * | Unused, | * | Available VM | @@ -179,8 +179,8 @@ void z_page_frames_dump(void) * +--------------+ * | Mapping | * +--------------+ <- mappings start here - * | Reserved | <- special purpose virtual page(s) of size Z_VM_RESERVED - * +--------------+ <- Z_VIRT_RAM_END + * | Reserved | <- special purpose virtual page(s) of size K_MEM_VM_RESERVED + * +--------------+ <- K_MEM_VIRT_RAM_END */ /* Bitmap of virtual addresses where one bit corresponds to one page. @@ -195,18 +195,18 @@ SYS_BITARRAY_DEFINE_STATIC(virt_region_bitmap, static bool virt_region_inited; -#define Z_VIRT_REGION_START_ADDR Z_FREE_VM_START -#define Z_VIRT_REGION_END_ADDR (Z_VIRT_RAM_END - Z_VM_RESERVED) +#define Z_VIRT_REGION_START_ADDR K_MEM_VM_FREE_START +#define Z_VIRT_REGION_END_ADDR (K_MEM_VIRT_RAM_END - K_MEM_VM_RESERVED) static inline uintptr_t virt_from_bitmap_offset(size_t offset, size_t size) { - return POINTER_TO_UINT(Z_VIRT_RAM_END) + return POINTER_TO_UINT(K_MEM_VIRT_RAM_END) - (offset * CONFIG_MMU_PAGE_SIZE) - size; } static inline size_t virt_to_bitmap_offset(void *vaddr, size_t size) { - return (POINTER_TO_UINT(Z_VIRT_RAM_END) + return (POINTER_TO_UINT(K_MEM_VIRT_RAM_END) - POINTER_TO_UINT(vaddr) - size) / CONFIG_MMU_PAGE_SIZE; } @@ -215,21 +215,21 @@ static void virt_region_init(void) size_t offset, num_bits; /* There are regions where we should never map via - * k_mem_map() and z_phys_map(). Mark them as + * k_mem_map() and k_mem_map_phys_bare(). Mark them as * already allocated so they will never be used. */ - if (Z_VM_RESERVED > 0) { + if (K_MEM_VM_RESERVED > 0) { /* Mark reserved region at end of virtual address space */ - num_bits = Z_VM_RESERVED / CONFIG_MMU_PAGE_SIZE; + num_bits = K_MEM_VM_RESERVED / CONFIG_MMU_PAGE_SIZE; (void)sys_bitarray_set_region(&virt_region_bitmap, num_bits, 0); } /* Mark all bits up to Z_FREE_VM_START as allocated */ - num_bits = POINTER_TO_UINT(Z_FREE_VM_START) - - POINTER_TO_UINT(Z_VIRT_RAM_START); - offset = virt_to_bitmap_offset(Z_VIRT_RAM_START, num_bits); + num_bits = POINTER_TO_UINT(K_MEM_VM_FREE_START) + - POINTER_TO_UINT(K_MEM_VIRT_RAM_START); + offset = virt_to_bitmap_offset(K_MEM_VIRT_RAM_START, num_bits); num_bits /= CONFIG_MMU_PAGE_SIZE; (void)sys_bitarray_set_region(&virt_region_bitmap, num_bits, offset); @@ -319,15 +319,15 @@ static void *virt_region_alloc(size_t size, size_t align) /* Here is the memory organization when trying to get an aligned * virtual address: * - * +--------------+ <- Z_VIRT_RAM_START + * +--------------+ <- K_MEM_VIRT_RAM_START * | Undefined VM | - * +--------------+ <- Z_KERNEL_VIRT_START (often == Z_VIRT_RAM_START) + * +--------------+ <- K_MEM_KERNEL_VIRT_START (often == K_MEM_VIRT_RAM_START) * | Mapping for | * | main kernel | * | image | * | | * | | - * +--------------+ <- Z_FREE_VM_START + * +--------------+ <- K_MEM_VM_FREE_START * | ... | * +==============+ <- dest_addr * | Unused | @@ -338,13 +338,13 @@ static void *virt_region_alloc(size_t size, size_t align) * | | * |..............| <- aligned_dest_addr + size * | Unused | - * +==============+ <- offset from Z_VIRT_RAM_END == dest_addr + alloc_size + * +==============+ <- offset from K_MEM_VIRT_RAM_END == dest_addr + alloc_size * | ... | * +--------------+ * | Mapping | * +--------------+ * | Reserved | - * +--------------+ <- Z_VIRT_RAM_END + * +--------------+ <- K_MEM_VIRT_RAM_END */ /* Free the two unused regions */ @@ -392,20 +392,20 @@ static sys_sflist_t free_page_frame_list; static size_t z_free_page_count; #define PF_ASSERT(pf, expr, fmt, ...) \ - __ASSERT(expr, "page frame 0x%lx: " fmt, z_page_frame_to_phys(pf), \ + __ASSERT(expr, "page frame 0x%lx: " fmt, k_mem_page_frame_to_phys(pf), \ ##__VA_ARGS__) /* Get an unused page frame. don't care which one, or NULL if there are none */ -static struct z_page_frame *free_page_frame_list_get(void) +static struct k_mem_page_frame *free_page_frame_list_get(void) { sys_sfnode_t *node; - struct z_page_frame *pf = NULL; + struct k_mem_page_frame *pf = NULL; node = sys_sflist_get(&free_page_frame_list); if (node != NULL) { z_free_page_count--; - pf = CONTAINER_OF(node, struct z_page_frame, node); - PF_ASSERT(pf, z_page_frame_is_free(pf), + pf = CONTAINER_OF(node, struct k_mem_page_frame, node); + PF_ASSERT(pf, k_mem_page_frame_is_free(pf), "on free list but not free"); pf->va_and_flags = 0; } @@ -414,12 +414,12 @@ static struct z_page_frame *free_page_frame_list_get(void) } /* Release a page frame back into the list of free pages */ -static void free_page_frame_list_put(struct z_page_frame *pf) +static void free_page_frame_list_put(struct k_mem_page_frame *pf) { - PF_ASSERT(pf, z_page_frame_is_available(pf), + PF_ASSERT(pf, k_mem_page_frame_is_available(pf), "unavailable page put on free list"); - sys_sfnode_init(&pf->node, Z_PAGE_FRAME_FREE); + sys_sfnode_init(&pf->node, K_MEM_PAGE_FRAME_FREE); sys_sflist_append(&free_page_frame_list, &pf->node); z_free_page_count++; } @@ -429,7 +429,7 @@ static void free_page_frame_list_init(void) sys_sflist_init(&free_page_frame_list); } -static void page_frame_free_locked(struct z_page_frame *pf) +static void page_frame_free_locked(struct k_mem_page_frame *pf) { pf->va_and_flags = 0; free_page_frame_list_put(pf); @@ -442,11 +442,11 @@ static void page_frame_free_locked(struct z_page_frame *pf) /* Called after the frame is mapped in the arch layer, to update our * local ontology (and do some assertions while we're at it) */ -static void frame_mapped_set(struct z_page_frame *pf, void *addr) +static void frame_mapped_set(struct k_mem_page_frame *pf, void *addr) { - PF_ASSERT(pf, !z_page_frame_is_free(pf), + PF_ASSERT(pf, !k_mem_page_frame_is_free(pf), "attempted to map a page frame on the free list"); - PF_ASSERT(pf, !z_page_frame_is_reserved(pf), + PF_ASSERT(pf, !k_mem_page_frame_is_reserved(pf), "attempted to map a reserved page frame"); /* We do allow multiple mappings for pinned page frames @@ -454,15 +454,15 @@ static void frame_mapped_set(struct z_page_frame *pf, void *addr) * This is uncommon, use-cases are for things like the * Zephyr equivalent of VSDOs */ - PF_ASSERT(pf, !z_page_frame_is_mapped(pf) || z_page_frame_is_pinned(pf), + PF_ASSERT(pf, !k_mem_page_frame_is_mapped(pf) || k_mem_page_frame_is_pinned(pf), "non-pinned and already mapped to %p", - z_page_frame_to_virt(pf)); + k_mem_page_frame_to_virt(pf)); uintptr_t flags_mask = CONFIG_MMU_PAGE_SIZE - 1; uintptr_t va = (uintptr_t)addr & ~flags_mask; pf->va_and_flags &= flags_mask; - pf->va_and_flags |= va | Z_PAGE_FRAME_MAPPED; + pf->va_and_flags |= va | K_MEM_PAGE_FRAME_MAPPED; } /* LCOV_EXCL_START */ @@ -479,15 +479,15 @@ static void frame_mapped_set(struct z_page_frame *pf, void *addr) static int virt_to_page_frame(void *virt, uintptr_t *phys) { uintptr_t paddr; - struct z_page_frame *pf; + struct k_mem_page_frame *pf; int ret = -EFAULT; - Z_PAGE_FRAME_FOREACH(paddr, pf) { - if (z_page_frame_is_mapped(pf)) { - if (virt == z_page_frame_to_virt(pf)) { + K_MEM_PAGE_FRAME_FOREACH(paddr, pf) { + if (k_mem_page_frame_is_mapped(pf)) { + if (virt == k_mem_page_frame_to_virt(pf)) { ret = 0; if (phys != NULL) { - *phys = z_page_frame_to_phys(pf); + *phys = k_mem_page_frame_to_phys(pf); } break; } @@ -501,7 +501,7 @@ static int virt_to_page_frame(void *virt, uintptr_t *phys) __weak FUNC_ALIAS(virt_to_page_frame, arch_page_phys_get, int); #ifdef CONFIG_DEMAND_PAGING -static int page_frame_prepare_locked(struct z_page_frame *pf, bool *dirty_ptr, +static int page_frame_prepare_locked(struct k_mem_page_frame *pf, bool *dirty_ptr, bool page_in, uintptr_t *location_ptr); static inline void do_backing_store_page_in(uintptr_t location); @@ -519,7 +519,7 @@ static inline void do_backing_store_page_out(uintptr_t location); */ static int map_anon_page(void *addr, uint32_t flags) { - struct z_page_frame *pf; + struct k_mem_page_frame *pf; uintptr_t phys; bool lock = (flags & K_MEM_MAP_LOCK) != 0U; @@ -533,8 +533,8 @@ static int map_anon_page(void *addr, uint32_t flags) pf = k_mem_paging_eviction_select(&dirty); __ASSERT(pf != NULL, "failed to get a page frame"); LOG_DBG("evicting %p at 0x%lx", - z_page_frame_to_virt(pf), - z_page_frame_to_phys(pf)); + k_mem_page_frame_to_virt(pf), + k_mem_page_frame_to_phys(pf)); ret = page_frame_prepare_locked(pf, &dirty, false, &location); if (ret != 0) { return -ENOMEM; @@ -548,11 +548,11 @@ static int map_anon_page(void *addr, uint32_t flags) #endif /* CONFIG_DEMAND_PAGING */ } - phys = z_page_frame_to_phys(pf); + phys = k_mem_page_frame_to_phys(pf); arch_mem_map(addr, phys, CONFIG_MMU_PAGE_SIZE, flags | K_MEM_CACHE_WB); if (lock) { - z_page_frame_set(pf, Z_PAGE_FRAME_PINNED); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED); } frame_mapped_set(pf, addr); @@ -561,7 +561,7 @@ static int map_anon_page(void *addr, uint32_t flags) return 0; } -void *k_mem_map_impl(uintptr_t phys, size_t size, uint32_t flags, bool is_anon) +void *k_mem_map_phys_guard(uintptr_t phys, size_t size, uint32_t flags, bool is_anon) { uint8_t *dst; size_t total_size; @@ -645,11 +645,11 @@ void *k_mem_map_impl(uintptr_t phys, size_t size, uint32_t flags, bool is_anon) return dst; } -void k_mem_unmap_impl(void *addr, size_t size, bool is_anon) +void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon) { uintptr_t phys; uint8_t *pos; - struct z_page_frame *pf; + struct k_mem_page_frame *pf; k_spinlock_key_t key; size_t total_size; int ret; @@ -661,7 +661,7 @@ void k_mem_unmap_impl(void *addr, size_t size, bool is_anon) * for two guard pages. */ pos = (uint8_t *)addr - CONFIG_MMU_PAGE_SIZE; - z_mem_assert_virtual_region(pos, size + (CONFIG_MMU_PAGE_SIZE * 2)); + k_mem_assert_virtual_region(pos, size + (CONFIG_MMU_PAGE_SIZE * 2)); key = k_spin_lock(&z_mm_lock); @@ -689,8 +689,39 @@ void k_mem_unmap_impl(void *addr, size_t size, bool is_anon) if (is_anon) { /* Unmapping anonymous memory */ VIRT_FOREACH(addr, size, pos) { +#ifdef CONFIG_DEMAND_PAGING + enum arch_page_location status; + uintptr_t location; + + status = arch_page_location_get(pos, &location); + switch (status) { + case ARCH_PAGE_LOCATION_PAGED_OUT: + /* + * No pf is associated with this mapping. + * Simply get rid of the MMU entry and free + * corresponding backing store. + */ + arch_mem_unmap(pos, CONFIG_MMU_PAGE_SIZE); + k_mem_paging_backing_store_location_free(location); + continue; + case ARCH_PAGE_LOCATION_PAGED_IN: + /* + * The page is in memory but it may not be + * accessible in order to manage tracking + * of the ARCH_DATA_PAGE_ACCESSED flag + * meaning arch_page_phys_get() could fail. + * Still, we know the actual phys address. + */ + phys = location; + ret = 0; + break; + default: + ret = arch_page_phys_get(pos, &phys); + break; + } +#else ret = arch_page_phys_get(pos, &phys); - +#endif __ASSERT(ret == 0, "%s: cannot unmap an unmapped address %p", __func__, pos); @@ -699,9 +730,9 @@ void k_mem_unmap_impl(void *addr, size_t size, bool is_anon) goto out; } - __ASSERT(z_is_page_frame(phys), + __ASSERT(k_mem_is_page_frame(phys), "%s: 0x%lx is not a page frame", __func__, phys); - if (!z_is_page_frame(phys)) { + if (!k_mem_is_page_frame(phys)) { /* Physical address has no corresponding page frame * description in the page frame array. * This should not happen. Do not continue. @@ -710,11 +741,11 @@ void k_mem_unmap_impl(void *addr, size_t size, bool is_anon) } /* Grab the corresponding page frame from physical address */ - pf = z_phys_to_page_frame(phys); + pf = k_mem_phys_to_page_frame(phys); - __ASSERT(z_page_frame_is_mapped(pf), + __ASSERT(k_mem_page_frame_is_mapped(pf), "%s: 0x%lx is not a mapped page frame", __func__, phys); - if (!z_page_frame_is_mapped(pf)) { + if (!k_mem_page_frame_is_mapped(pf)) { /* Page frame is not marked mapped. * This should not happen. Do not continue. */ @@ -791,7 +822,7 @@ __weak FUNC_ALIAS(virt_region_align, arch_virt_region_align, size_t); * Data will be copied and BSS zeroed, but this must not rely on any * initialization functions being called prior to work correctly. */ -void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags) +void k_mem_map_phys_bare(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags) { uintptr_t aligned_phys, addr_offset; size_t aligned_size, align_boundary; @@ -827,14 +858,14 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags) */ if (IN_RANGE(aligned_phys, - (uintptr_t)Z_VIRT_RAM_START, - (uintptr_t)(Z_VIRT_RAM_END - 1)) || + (uintptr_t)K_MEM_VIRT_RAM_START, + (uintptr_t)(K_MEM_VIRT_RAM_END - 1)) || IN_RANGE(aligned_phys + aligned_size - 1, - (uintptr_t)Z_VIRT_RAM_START, - (uintptr_t)(Z_VIRT_RAM_END - 1))) { - uint8_t *adjusted_start = MAX(dest_addr, Z_VIRT_RAM_START); + (uintptr_t)K_MEM_VIRT_RAM_START, + (uintptr_t)(K_MEM_VIRT_RAM_END - 1))) { + uint8_t *adjusted_start = MAX(dest_addr, K_MEM_VIRT_RAM_START); uint8_t *adjusted_end = MIN(dest_addr + aligned_size, - Z_VIRT_RAM_END); + K_MEM_VIRT_RAM_END); size_t adjusted_sz = adjusted_end - adjusted_start; num_bits = adjusted_sz / CONFIG_MMU_PAGE_SIZE; @@ -878,7 +909,7 @@ void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags) k_panic(); } -void z_phys_unmap(uint8_t *virt, size_t size) +void k_mem_unmap_phys_bare(uint8_t *virt, size_t size) { uintptr_t aligned_virt, addr_offset; size_t aligned_size; @@ -925,7 +956,7 @@ size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size, static void mark_linker_section_pinned(void *start_addr, void *end_addr, bool pin) { - struct z_page_frame *pf; + struct k_mem_page_frame *pf; uint8_t *addr; uintptr_t pinned_start = ROUND_DOWN(POINTER_TO_UINT(start_addr), @@ -936,13 +967,13 @@ static void mark_linker_section_pinned(void *start_addr, void *end_addr, VIRT_FOREACH(UINT_TO_POINTER(pinned_start), pinned_size, addr) { - pf = z_phys_to_page_frame(Z_BOOT_VIRT_TO_PHYS(addr)); + pf = k_mem_phys_to_page_frame(K_MEM_BOOT_VIRT_TO_PHYS(addr)); frame_mapped_set(pf, addr); if (pin) { - z_page_frame_set(pf, Z_PAGE_FRAME_PINNED); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED); } else { - z_page_frame_clear(pf, Z_PAGE_FRAME_PINNED); + k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_PINNED); } } } @@ -952,7 +983,7 @@ void z_mem_manage_init(void) { uintptr_t phys; uint8_t *addr; - struct z_page_frame *pf; + struct k_mem_page_frame *pf; k_spinlock_key_t key = k_spin_lock(&z_mm_lock); free_page_frame_list_init(); @@ -961,7 +992,7 @@ void z_mem_manage_init(void) #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES /* If some page frames are unavailable for use as memory, arch - * code will mark Z_PAGE_FRAME_RESERVED in their flags + * code will mark K_MEM_PAGE_FRAME_RESERVED in their flags */ arch_reserved_pages_update(); #endif /* CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES */ @@ -970,9 +1001,9 @@ void z_mem_manage_init(void) /* All pages composing the Zephyr image are mapped at boot in a * predictable way. This can change at runtime. */ - VIRT_FOREACH(Z_KERNEL_VIRT_START, Z_KERNEL_VIRT_SIZE, addr) + VIRT_FOREACH(K_MEM_KERNEL_VIRT_START, K_MEM_KERNEL_VIRT_SIZE, addr) { - pf = z_phys_to_page_frame(Z_BOOT_VIRT_TO_PHYS(addr)); + pf = k_mem_phys_to_page_frame(K_MEM_BOOT_VIRT_TO_PHYS(addr)); frame_mapped_set(pf, addr); /* TODO: for now we pin the whole Zephyr image. Demand paging @@ -985,7 +1016,7 @@ void z_mem_manage_init(void) * structures, and any code used to perform page fault * handling, page-ins, etc. */ - z_page_frame_set(pf, Z_PAGE_FRAME_PINNED); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED); } #endif /* CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT */ @@ -1004,8 +1035,8 @@ void z_mem_manage_init(void) /* Any remaining pages that aren't mapped, reserved, or pinned get * added to the free pages list */ - Z_PAGE_FRAME_FOREACH(phys, pf) { - if (z_page_frame_is_available(pf)) { + K_MEM_PAGE_FRAME_FOREACH(phys, pf) { + if (k_mem_page_frame_is_available(pf)) { free_page_frame_list_put(pf); } } @@ -1127,7 +1158,7 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_SMP)); static void virt_region_foreach(void *addr, size_t size, void (*func)(void *)) { - z_mem_assert_virtual_region(addr, size); + k_mem_assert_virtual_region(addr, size); for (size_t offset = 0; offset < size; offset += CONFIG_MMU_PAGE_SIZE) { func((uint8_t *)addr + offset); @@ -1150,15 +1181,15 @@ static void virt_region_foreach(void *addr, size_t size, * * Returns -ENOMEM if the backing store is full */ -static int page_frame_prepare_locked(struct z_page_frame *pf, bool *dirty_ptr, +static int page_frame_prepare_locked(struct k_mem_page_frame *pf, bool *dirty_ptr, bool page_fault, uintptr_t *location_ptr) { uintptr_t phys; int ret; bool dirty = *dirty_ptr; - phys = z_page_frame_to_phys(pf); - __ASSERT(!z_page_frame_is_pinned(pf), "page frame 0x%lx is pinned", + phys = k_mem_page_frame_to_phys(pf); + __ASSERT(!k_mem_page_frame_is_pinned(pf), "page frame 0x%lx is pinned", phys); /* If the backing store doesn't have a copy of the page, even if it @@ -1172,31 +1203,31 @@ static int page_frame_prepare_locked(struct z_page_frame *pf, bool *dirty_ptr, * evicted from the backing store to make room for other evicted * pages. */ - if (z_page_frame_is_mapped(pf)) { - dirty = dirty || !z_page_frame_is_backed(pf); + if (k_mem_page_frame_is_mapped(pf)) { + dirty = dirty || !k_mem_page_frame_is_backed(pf); } if (dirty || page_fault) { arch_mem_scratch(phys); } - if (z_page_frame_is_mapped(pf)) { + if (k_mem_page_frame_is_mapped(pf)) { ret = k_mem_paging_backing_store_location_get(pf, location_ptr, page_fault); if (ret != 0) { LOG_ERR("out of backing store memory"); return -ENOMEM; } - arch_mem_page_out(z_page_frame_to_virt(pf), *location_ptr); + arch_mem_page_out(k_mem_page_frame_to_virt(pf), *location_ptr); } else { /* Shouldn't happen unless this function is mis-used */ __ASSERT(!dirty, "un-mapped page determined to be dirty"); } #ifdef CONFIG_DEMAND_PAGING_ALLOW_IRQ - /* Mark as busy so that z_page_frame_is_evictable() returns false */ - __ASSERT(!z_page_frame_is_busy(pf), "page frame 0x%lx is already busy", + /* Mark as busy so that k_mem_page_frame_is_evictable() returns false */ + __ASSERT(!k_mem_page_frame_is_busy(pf), "page frame 0x%lx is already busy", phys); - z_page_frame_set(pf, Z_PAGE_FRAME_BUSY); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_BUSY); #endif /* CONFIG_DEMAND_PAGING_ALLOW_IRQ */ /* Update dirty parameter, since we set to true if it wasn't backed * even if otherwise clean @@ -1209,7 +1240,7 @@ static int page_frame_prepare_locked(struct z_page_frame *pf, bool *dirty_ptr, static int do_mem_evict(void *addr) { bool dirty; - struct z_page_frame *pf; + struct k_mem_page_frame *pf; uintptr_t location; int key, ret; uintptr_t flags, phys; @@ -1231,8 +1262,8 @@ static int do_mem_evict(void *addr) } dirty = (flags & ARCH_DATA_PAGE_DIRTY) != 0; - pf = z_phys_to_page_frame(phys); - __ASSERT(z_page_frame_to_virt(pf) == addr, "page frame address mismatch"); + pf = k_mem_phys_to_page_frame(phys); + __ASSERT(k_mem_page_frame_to_virt(pf) == addr, "page frame address mismatch"); ret = page_frame_prepare_locked(pf, &dirty, false, &location); if (ret != 0) { goto out; @@ -1261,7 +1292,7 @@ int k_mem_page_out(void *addr, size_t size) { __ASSERT(page_frames_initialized, "%s called on %p too early", __func__, addr); - z_mem_assert_virtual_region(addr, size); + k_mem_assert_virtual_region(addr, size); for (size_t offset = 0; offset < size; offset += CONFIG_MMU_PAGE_SIZE) { void *pos = (uint8_t *)addr + offset; @@ -1276,10 +1307,10 @@ int k_mem_page_out(void *addr, size_t size) return 0; } -int z_page_frame_evict(uintptr_t phys) +int k_mem_page_frame_evict(uintptr_t phys) { int key, ret; - struct z_page_frame *pf; + struct k_mem_page_frame *pf; bool dirty; uintptr_t flags; uintptr_t location; @@ -1298,13 +1329,13 @@ int z_page_frame_evict(uintptr_t phys) k_sched_lock(); #endif /* CONFIG_DEMAND_PAGING_ALLOW_IRQ */ key = irq_lock(); - pf = z_phys_to_page_frame(phys); - if (!z_page_frame_is_mapped(pf)) { + pf = k_mem_phys_to_page_frame(phys); + if (!k_mem_page_frame_is_mapped(pf)) { /* Nothing to do, free page */ ret = 0; goto out; } - flags = arch_page_info_get(z_page_frame_to_virt(pf), NULL, false); + flags = arch_page_info_get(k_mem_page_frame_to_virt(pf), NULL, false); /* Shouldn't ever happen */ __ASSERT((flags & ARCH_DATA_PAGE_LOADED) != 0, "data page not loaded"); dirty = (flags & ARCH_DATA_PAGE_DIRTY) != 0; @@ -1390,9 +1421,9 @@ static inline void paging_stats_eviction_inc(struct k_thread *faulting_thread, #endif /* CONFIG_DEMAND_PAGING_STATS */ } -static inline struct z_page_frame *do_eviction_select(bool *dirty) +static inline struct k_mem_page_frame *do_eviction_select(bool *dirty) { - struct z_page_frame *pf; + struct k_mem_page_frame *pf; #ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM uint32_t time_diff; @@ -1426,7 +1457,7 @@ static inline struct z_page_frame *do_eviction_select(bool *dirty) static bool do_page_fault(void *addr, bool pin) { - struct z_page_frame *pf; + struct k_mem_page_frame *pf; int key, ret; uintptr_t page_in_location, page_out_location; enum arch_page_location status; @@ -1489,8 +1520,8 @@ static bool do_page_fault(void *addr, bool pin) /* It's a physical memory address */ uintptr_t phys = page_in_location; - pf = z_phys_to_page_frame(phys); - z_page_frame_set(pf, Z_PAGE_FRAME_PINNED); + pf = k_mem_phys_to_page_frame(phys); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED); } /* This if-block is to pin the page if it is @@ -1511,8 +1542,8 @@ static bool do_page_fault(void *addr, bool pin) pf = do_eviction_select(&dirty); __ASSERT(pf != NULL, "failed to get a page frame"); LOG_DBG("evicting %p at 0x%lx", - z_page_frame_to_virt(pf), - z_page_frame_to_phys(pf)); + k_mem_page_frame_to_virt(pf), + k_mem_page_frame_to_phys(pf)); paging_stats_eviction_inc(faulting_thread, dirty); } @@ -1533,15 +1564,15 @@ static bool do_page_fault(void *addr, bool pin) #ifdef CONFIG_DEMAND_PAGING_ALLOW_IRQ key = irq_lock(); - z_page_frame_clear(pf, Z_PAGE_FRAME_BUSY); + k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_BUSY); #endif /* CONFIG_DEMAND_PAGING_ALLOW_IRQ */ - z_page_frame_clear(pf, Z_PAGE_FRAME_MAPPED); + k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_MAPPED); frame_mapped_set(pf, addr); if (pin) { - z_page_frame_set(pf, Z_PAGE_FRAME_PINNED); + k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED); } - arch_mem_page_in(addr, z_page_frame_to_phys(pf)); + arch_mem_page_in(addr, k_mem_page_frame_to_phys(pf)); k_mem_paging_backing_store_page_finalize(pf, page_in_location); out: irq_unlock(key); @@ -1586,14 +1617,14 @@ void k_mem_pin(void *addr, size_t size) virt_region_foreach(addr, size, do_mem_pin); } -bool z_page_fault(void *addr) +bool k_mem_page_fault(void *addr) { return do_page_fault(addr, false); } static void do_mem_unpin(void *addr) { - struct z_page_frame *pf; + struct k_mem_page_frame *pf; unsigned int key; uintptr_t flags, phys; @@ -1602,8 +1633,8 @@ static void do_mem_unpin(void *addr) __ASSERT((flags & ARCH_DATA_PAGE_NOT_MAPPED) == 0, "invalid data page at %p", addr); if ((flags & ARCH_DATA_PAGE_LOADED) != 0) { - pf = z_phys_to_page_frame(phys); - z_page_frame_clear(pf, Z_PAGE_FRAME_PINNED); + pf = k_mem_phys_to_page_frame(phys); + k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_PINNED); } irq_unlock(key); } diff --git a/kernel/paging/statistics.c b/kernel/paging/statistics.c index c0617af47c0744..4752ca15022d0f 100644 --- a/kernel/paging/statistics.c +++ b/kernel/paging/statistics.c @@ -76,7 +76,7 @@ k_mem_paging_backing_store_histogram_bounds[ #endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */ #endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */ -unsigned long z_num_pagefaults_get(void) +unsigned long k_mem_num_pagefaults_get(void) { unsigned long ret; unsigned int key; diff --git a/kernel/sched.c b/kernel/sched.c index 506ad57a141b21..67e5645bc6f245 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -348,11 +348,11 @@ static void update_cache(int preempt_ok) #endif /* CONFIG_SMP */ } -static bool thread_active_elsewhere(struct k_thread *thread) +static struct _cpu *thread_active_elsewhere(struct k_thread *thread) { - /* True if the thread is currently running on another CPU. - * There are more scalable designs to answer this question in - * constant time, but this is fine for now. + /* Returns pointer to _cpu if the thread is currently running on + * another CPU. There are more scalable designs to answer this + * question in constant time, but this is fine for now. */ #ifdef CONFIG_SMP int currcpu = _current_cpu->id; @@ -362,12 +362,12 @@ static bool thread_active_elsewhere(struct k_thread *thread) for (int i = 0; i < num_cpus; i++) { if ((i != currcpu) && (_kernel.cpus[i].current == thread)) { - return true; + return &_kernel.cpus[i]; } } #endif /* CONFIG_SMP */ ARG_UNUSED(thread); - return false; + return NULL; } static void ready_thread(struct k_thread *thread) @@ -384,13 +384,14 @@ static void ready_thread(struct k_thread *thread) queue_thread(thread); update_cache(0); - flag_ipi(); + + flag_ipi(ipi_mask_create(thread)); } } void z_ready_thread_locked(struct k_thread *thread) { - if (!thread_active_elsewhere(thread)) { + if (thread_active_elsewhere(thread) == NULL) { ready_thread(thread); } } @@ -398,7 +399,7 @@ void z_ready_thread_locked(struct k_thread *thread) void z_ready_thread(struct k_thread *thread) { K_SPINLOCK(&_sched_spinlock) { - if (!thread_active_elsewhere(thread)) { + if (thread_active_elsewhere(thread) == NULL) { ready_thread(thread); } } @@ -466,11 +467,18 @@ static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key, * halt itself in the IPI. Otherwise it's unscheduled, so we * can clean it up directly. */ - if (thread_active_elsewhere(thread)) { + + struct _cpu *cpu = thread_active_elsewhere(thread); + + if (cpu != NULL) { thread->base.thread_state |= (terminate ? _THREAD_ABORTING : _THREAD_SUSPENDING); #if defined(CONFIG_SMP) && defined(CONFIG_SCHED_IPI_SUPPORTED) - arch_sched_ipi(); +#ifdef CONFIG_ARCH_HAS_DIRECTED_IPIS + arch_sched_directed_ipi(IPI_CPU_MASK(cpu->id)); +#else + arch_sched_broadcast_ipi(); +#endif #endif if (arch_is_in_isr()) { thread_halt_spin(thread, key); @@ -731,19 +739,38 @@ void z_unpend_thread(struct k_thread *thread) bool z_thread_prio_set(struct k_thread *thread, int prio) { bool need_sched = 0; + int old_prio = thread->base.prio; K_SPINLOCK(&_sched_spinlock) { need_sched = z_is_thread_ready(thread); if (need_sched) { - /* Don't requeue on SMP if it's the running thread */ if (!IS_ENABLED(CONFIG_SMP) || z_is_thread_queued(thread)) { dequeue_thread(thread); thread->base.prio = prio; queue_thread(thread); + + if (old_prio > prio) { + flag_ipi(ipi_mask_create(thread)); + } } else { + /* + * This is a running thread on SMP. Update its + * priority, but do not requeue it. An IPI is + * needed if the priority is both being lowered + * and it is running on another CPU. + */ + thread->base.prio = prio; + + struct _cpu *cpu; + + cpu = thread_active_elsewhere(thread); + if ((cpu != NULL) && (old_prio < prio)) { + flag_ipi(IPI_CPU_MASK(cpu->id)); + } } + update_cache(1); } else { thread->base.prio = prio; @@ -1006,8 +1033,8 @@ void z_impl_k_thread_priority_set(k_tid_t thread, int prio) bool need_sched = z_thread_prio_set((struct k_thread *)thread, prio); - flag_ipi(); - if (need_sched && (_current->base.sched_locked == 0U)) { + if ((need_sched) && (IS_ENABLED(CONFIG_SMP) || + (_current->base.sched_locked == 0U))) { z_reschedule_unlocked(); } } @@ -1219,7 +1246,7 @@ void z_impl_k_wakeup(k_tid_t thread) z_mark_thread_as_not_suspended(thread); - if (!thread_active_elsewhere(thread)) { + if (thread_active_elsewhere(thread) == NULL) { ready_thread(thread); } diff --git a/kernel/thread.c b/kernel/thread.c index 7b458d1f8bb2e2..e39ecd3d7c81a4 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -429,8 +429,9 @@ static char *setup_thread_stack(struct k_thread *new_thread, * stack. If CONFIG_INIT_STACKS is enabled, the stack will be * cleared below. */ - void *stack_mapped = k_mem_phys_map((uintptr_t)stack, stack_obj_size, - K_MEM_PERM_RW | K_MEM_CACHE_WB | K_MEM_MAP_UNINIT); + void *stack_mapped = k_mem_map_phys_guard((uintptr_t)stack, stack_obj_size, + K_MEM_PERM_RW | K_MEM_CACHE_WB | K_MEM_MAP_UNINIT, + false); __ASSERT_NO_MSG((uintptr_t)stack_mapped != 0); @@ -1051,8 +1052,8 @@ void do_thread_cleanup(struct k_thread *thread) #ifdef CONFIG_THREAD_STACK_MEM_MAPPED if (thread_cleanup_stack_addr != NULL) { - k_mem_phys_unmap(thread_cleanup_stack_addr, - thread_cleanup_stack_sz); + k_mem_unmap_phys_guard(thread_cleanup_stack_addr, + thread_cleanup_stack_sz, false); thread_cleanup_stack_addr = NULL; } diff --git a/kernel/timeslicing.c b/kernel/timeslicing.c index 07ae497c7f91e6..be91d9606f51e2 100644 --- a/kernel/timeslicing.c +++ b/kernel/timeslicing.c @@ -58,11 +58,10 @@ static void slice_timeout(struct _timeout *timeout) slice_expired[cpu] = true; /* We need an IPI if we just handled a timeslice expiration - * for a different CPU. Ideally this would be able to target - * the specific core, but that's not part of the API yet. + * for a different CPU. */ - if (IS_ENABLED(CONFIG_SMP) && cpu != _current_cpu->id) { - flag_ipi(); + if (cpu != _current_cpu->id) { + flag_ipi(IPI_CPU_MASK(cpu)); } } diff --git a/lib/crc/Kconfig b/lib/crc/Kconfig index f0745f0adedf24..0402df59d01fb1 100644 --- a/lib/crc/Kconfig +++ b/lib/crc/Kconfig @@ -10,7 +10,7 @@ if CRC config CRC_SHELL bool "CRC Shell" depends on SHELL - select GETOPT + select POSIX_C_LIB_EXT help Enable CRC checking for memory regions from the shell. endif # CRC diff --git a/lib/crc/crc7_sw.c b/lib/crc/crc7_sw.c index 97c370d44e7f42..970c5734c7ab3b 100644 --- a/lib/crc/crc7_sw.c +++ b/lib/crc/crc7_sw.c @@ -8,7 +8,7 @@ uint8_t crc7_be(uint8_t seed, const uint8_t *src, size_t len) { - while (len--) { + while (len-- != 0UL) { uint8_t e = seed ^ *src++; uint8_t f = e ^ (e >> 4) ^ (e >> 7); diff --git a/lib/crc/crc8_sw.c b/lib/crc/crc8_sw.c index 67043d27c501d1..06bbeea516bc7e 100644 --- a/lib/crc/crc8_sw.c +++ b/lib/crc/crc8_sw.c @@ -37,13 +37,13 @@ uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial for (j = 0; j < 8; j++) { if (reversed) { - if (crc & 0x01) { + if ((crc & 0x01) != 0) { crc = (crc >> 1) ^ polynomial; } else { crc >>= 1; } } else { - if (crc & 0x80) { + if ((crc & 0x80) != 0) { crc = (crc << 1) ^ polynomial; } else { crc <<= 1; diff --git a/lib/heap/heap.c b/lib/heap/heap.c index b23d160b726fe4..45d684128a2820 100644 --- a/lib/heap/heap.c +++ b/lib/heap/heap.c @@ -229,7 +229,7 @@ static chunkid_t alloc_chunk(struct z_heap *h, chunksz_t sz) * fragmentation waste of the order of the block allocated * only. */ - if (b->next) { + if (b->next != 0U) { chunkid_t first = b->next; int i = CONFIG_SYS_HEAP_ALLOC_LOOPS; do { diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 1dcc3dc729ac31..c04207017cf834 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -102,6 +102,13 @@ config NEWLIB_LIBC depends on !NATIVE_APPLICATION depends on NEWLIB_LIBC_SUPPORTED select NEED_LIBC_MEM_PARTITION + imply POSIX_DEVICE_IO_ALIAS_CLOSE + imply POSIX_DEVICE_IO_ALIAS_OPEN + imply POSIX_DEVICE_IO_ALIAS_READ + imply POSIX_DEVICE_IO_ALIAS_WRITE + imply POSIX_FD_MGMT_ALIAS_LSEEK + imply POSIX_FILE_SYSTEM_ALIAS_FSTAT + imply POSIX_MULTI_PROCESS_ALIAS_GETPID help Build with newlib library. The newlib library is expected to be part of the SDK in this case. diff --git a/lib/libc/minimal/Kconfig b/lib/libc/minimal/Kconfig index d7bc50c4157c2d..a55bf7a87b2683 100644 --- a/lib/libc/minimal/Kconfig +++ b/lib/libc/minimal/Kconfig @@ -78,13 +78,13 @@ config MINIMAL_LIBC_RAND config MINIMAL_LIBC_TIME bool "Time functions" - select COMMON_LIBC_TIME if POSIX_CLOCK + select COMMON_LIBC_TIME if POSIX_TIMERS select COMMON_LIBC_GMTIME_R default y help Enable time() and gmtime_r() for the minimal libc. - time() requires CONFIG_POSIX_CLOCK=y because it relies on the POSIX + time() requires CONFIG_POSIX_TIMERS=y because it relies on the POSIX clock_gettime() function. In order to make use of the non-reentrant gmtime(), it is necessary diff --git a/lib/libc/minimal/source/stdlib/strtol.c b/lib/libc/minimal/source/stdlib/strtol.c index 363ce7831a334b..fd36fbefd45590 100644 --- a/lib/libc/minimal/source/stdlib/strtol.c +++ b/lib/libc/minimal/source/stdlib/strtol.c @@ -117,7 +117,7 @@ long strtol(const char *nptr, char **endptr, register int base) if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; errno = ERANGE; - } else if (neg) { + } else if (neg != 0) { acc = -acc; } diff --git a/lib/libc/minimal/source/stdlib/strtoul.c b/lib/libc/minimal/source/stdlib/strtoul.c index 31e930ef53b6c2..193c96e83e3150 100644 --- a/lib/libc/minimal/source/stdlib/strtoul.c +++ b/lib/libc/minimal/source/stdlib/strtoul.c @@ -96,7 +96,7 @@ unsigned long strtoul(const char *nptr, char **endptr, register int base) if (any < 0) { acc = ULONG_MAX; errno = ERANGE; - } else if (neg) { + } else if (neg != 0) { acc = -acc; } if (endptr != NULL) { diff --git a/lib/libc/minimal/source/string/string.c b/lib/libc/minimal/source/string/string.c index a7590a598dd679..3582f5f5d75adc 100644 --- a/lib/libc/minimal/source/string/string.c +++ b/lib/libc/minimal/source/string/string.c @@ -92,7 +92,7 @@ char *strrchr(const char *s, int c) if (*s == (char)c) { match = (char *)s; } - } while (*s++); + } while (*s++ != '\0'); return match; } diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index 75a2859fb42a6f..3db4f2c885f036 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -23,6 +23,15 @@ #include #include +int _fstat(int fd, struct stat *st); +int _read(int fd, void *buf, int nbytes); +int _write(int fd, const void *buf, int nbytes); +int _open(const char *name, int mode); +int _close(int file); +int _lseek(int file, int ptr, int dir); +int _kill(int pid, int sig); +int _getpid(void); + #define LIBC_BSS K_APP_BMEM(z_libc_partition) #define LIBC_DATA K_APP_DMEM(z_libc_partition) @@ -210,8 +219,8 @@ static inline int z_vrfy_zephyr_write_stdout(const void *buf, int nbytes) #include #endif -#ifndef CONFIG_POSIX_API -int _read(int fd, char *buf, int nbytes) +#ifndef CONFIG_POSIX_DEVICE_IO +int _read(int fd, void *buf, int nbytes) { ARG_UNUSED(fd); @@ -238,16 +247,15 @@ int _close(int file) return -1; } __weak FUNC_ALIAS(_close, close, int); +#endif /* CONFIG_POSIX_DEVICE_IO */ +#ifndef CONFIG_POSIX_FD_MGMT int _lseek(int file, int ptr, int dir) { return 0; } __weak FUNC_ALIAS(_lseek, lseek, int); -#else -extern ssize_t write(int file, const char *buffer, size_t count); -#define _write write -#endif +#endif /* CONFIG_POSIX_FD_MGMT */ int _isatty(int file) { @@ -255,24 +263,31 @@ int _isatty(int file) } __weak FUNC_ALIAS(_isatty, isatty, int); +#ifndef CONFIG_POSIX_SIGNALS int _kill(int i, int j) { return 0; } __weak FUNC_ALIAS(_kill, kill, int); +#endif /* CONFIG_POSIX_SIGNALS */ -int _getpid(void) +#ifndef CONFIG_POSIX_FILE_SYSTEM +int _fstat(int file, struct stat *st) { + st->st_mode = S_IFCHR; return 0; } -__weak FUNC_ALIAS(_getpid, getpid, int); +__weak FUNC_ALIAS(_fstat, fstat, int); +#endif /* CONFIG_POSIX_FILE_SYSTEM */ -int _fstat(int file, struct stat *st) +#ifndef CONFIG_POSIX_MULTI_PROCESS +int _getpid(void) { - st->st_mode = S_IFCHR; return 0; } -__weak FUNC_ALIAS(_fstat, fstat, int); +__weak FUNC_ALIAS(_getpid, getpid, int); + +#endif /* CONFIG_POSIX_MULTI_PROCESS */ __weak void _exit(int status) { @@ -476,11 +491,6 @@ __weak FUNC_NORETURN void __chk_fail(void) } #if CONFIG_XTENSA -extern int _read(int fd, char *buf, int nbytes); -extern int _open(const char *name, int mode); -extern int _close(int file); -extern int _lseek(int file, int ptr, int dir); - /* The Newlib in xtensa toolchain has a few missing functions for the * reentrant versions of the syscalls. */ @@ -565,7 +575,7 @@ void *_sbrk_r(struct _reent *r, int count) int _gettimeofday(struct timeval *__tp, void *__tzp) { -#ifdef CONFIG_POSIX_CLOCK +#ifdef CONFIG_XSI_SINGLE_PROCESS return gettimeofday(__tp, __tzp); #else /* Non-posix systems should not call gettimeofday() here as it will diff --git a/lib/open-amp/resource_table.c b/lib/open-amp/resource_table.c index 53e38f185f0a36..a857c3ca05f44c 100644 --- a/lib/open-amp/resource_table.c +++ b/lib/open-amp/resource_table.c @@ -68,7 +68,7 @@ static struct fw_resource_table __resource resource_table = { #if defined(CONFIG_RAM_CONSOLE) .cm_trace = { RSC_TRACE, - (uint32_t)ram_console, CONFIG_RAM_CONSOLE_BUFFER_SIZE + 1, 0, + (uint32_t)ram_console, CONFIG_RAM_CONSOLE_BUFFER_SIZE, 0, "Zephyr_log", }, #endif diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 3a52bebab04b83..4ce50ad4182921 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -40,3 +40,5 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/${ARCH}/include ) + +add_subdirectory_ifdef(CONFIG_ZVFS zvfs) diff --git a/lib/os/Kconfig b/lib/os/Kconfig index 14b6241b72c935..fa52338e525f10 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -10,6 +10,15 @@ config FDTABLE for any I/O object implementing POSIX I/O semantics (i.e. read/write + aux operations). +config ZVFS_OPEN_MAX + int "Maximum number of open file descriptors" + default 16 if WIFI_NM_WPA_SUPPLICANT + default 16 if POSIX_API + default 4 + help + Maximum number of open file descriptors, this includes + files, sockets, special devices, etc. + config PRINTK_SYNC bool "Serialize printk() calls" default y if SMP && MP_MAX_NUM_CPUS > 1 && !(EFI_CONSOLE && LOG) @@ -114,5 +123,6 @@ config POWEROFF Enable support for system power off. rsource "Kconfig.cbprintf" +rsource "zvfs/Kconfig" endmenu diff --git a/lib/os/cbprintf_complete.c b/lib/os/cbprintf_complete.c index 812ebe0d575842..206288cb1bbb1c 100644 --- a/lib/os/cbprintf_complete.c +++ b/lib/os/cbprintf_complete.c @@ -979,7 +979,7 @@ static char *encode_float(double value, /* Round only if the bit that would round is * set. */ - if (fract & mask) { + if ((fract & mask) != 0ULL) { fract += mask; } } @@ -1160,7 +1160,7 @@ static char *encode_float(double value, /* Round the value to the last digit being printed. */ uint64_t round = BIT64(59); /* 0.5 */ - while (decimals--) { + while (decimals-- != 0) { _ldiv10(&round); } fract += round; @@ -1601,6 +1601,26 @@ int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fp, break; } + case 'p': + /* Implementation-defined: null is "(nil)", non-null + * has 0x prefix followed by significant address hex + * digits, no leading zeros. + */ + if (value->ptr != NULL) { + bps = encode_uint((uintptr_t)value->ptr, conv, + buf, bpe); + + /* Use 0x prefix */ + conv->altform_0c = true; + conv->specifier = 'x'; + + goto prec_int_pad0; + } + + bps = "(nil)"; + bpe = bps + 5; + + break; case 'c': bps = buf; buf[0] = CHAR_IS_SIGNED ? value->sint : value->uint; @@ -1653,26 +1673,6 @@ int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fp, } } - break; - case 'p': - /* Implementation-defined: null is "(nil)", non-null - * has 0x prefix followed by significant address hex - * digits, no leading zeros. - */ - if (value->ptr != NULL) { - bps = encode_uint((uintptr_t)value->ptr, conv, - buf, bpe); - - /* Use 0x prefix */ - conv->altform_0c = true; - conv->specifier = 'x'; - - goto prec_int_pad0; - } - - bps = "(nil)"; - bpe = bps + 5; - break; case 'n': if (IS_ENABLED(CONFIG_CBPRINTF_N_SPECIFIER)) { @@ -1817,7 +1817,7 @@ int z_cbvprintf_impl(cbprintf_cb out, void *ctx, const char *fp, OUTS(cp, bpe); } else { - if (conv->altform_0c | conv->altform_0) { + if ((conv->altform_0c | conv->altform_0) != 0) { OUTC('0'); } diff --git a/lib/os/cbprintf_packaged.c b/lib/os/cbprintf_packaged.c index 1c208c42e67a18..8b167dfd4da148 100644 --- a/lib/os/cbprintf_packaged.c +++ b/lib/os/cbprintf_packaged.c @@ -753,7 +753,7 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags, #endif /* Store strings pointer locations of read only strings. */ - if (s_ro_cnt) { + if (s_ro_cnt != 0U) { for (i = 0; i < s_idx; i++) { if (!(str_ptr_pos[i] & STR_POS_RO_FLAG)) { continue; diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index e02bc2f661f41d..b3c4ad13cd0371 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -31,12 +31,14 @@ struct fd_entry { struct k_condvar cond; }; -#ifdef CONFIG_POSIX_API +#if defined(CONFIG_POSIX_DEVICE_IO) static const struct fd_op_vtable stdinout_fd_op_vtable; -#endif -static struct fd_entry fdtable[CONFIG_POSIX_MAX_FDS] = { -#ifdef CONFIG_POSIX_API +BUILD_ASSERT(CONFIG_ZVFS_OPEN_MAX >= 3, "CONFIG_ZVFS_OPEN_MAX >= 3 for CONFIG_POSIX_DEVICE_IO"); +#endif /* defined(CONFIG_POSIX_DEVICE_IO) */ + +static struct fd_entry fdtable[CONFIG_ZVFS_OPEN_MAX] = { +#if defined(CONFIG_POSIX_DEVICE_IO) /* * Predefine entries for stdin/stdout/stderr. */ @@ -62,9 +64,7 @@ static struct fd_entry fdtable[CONFIG_POSIX_MAX_FDS] = { .cond = Z_CONDVAR_INITIALIZER(fdtable[2].cond), }, #else - { - 0 - }, + {0}, #endif }; @@ -224,7 +224,7 @@ void *z_get_fd_obj_and_vtable(int fd, const struct fd_op_vtable **vtable, entry = &fdtable[fd]; *vtable = entry->vtable; - if (lock) { + if (lock != NULL) { *lock = &entry->lock; } @@ -296,9 +296,7 @@ int z_alloc_fd(void *obj, const struct fd_op_vtable *vtable) return fd; } -#ifdef CONFIG_POSIX_API - -ssize_t read(int fd, void *buf, size_t sz) +ssize_t zvfs_read(int fd, void *buf, size_t sz) { ssize_t res; @@ -314,9 +312,8 @@ ssize_t read(int fd, void *buf, size_t sz) return res; } -FUNC_ALIAS(read, _read, ssize_t); -ssize_t write(int fd, const void *buf, size_t sz) +ssize_t zvfs_write(int fd, const void *buf, size_t sz) { ssize_t res; @@ -332,9 +329,8 @@ ssize_t write(int fd, const void *buf, size_t sz) return res; } -FUNC_ALIAS(write, _write, ssize_t); -int close(int fd) +int zvfs_close(int fd) { int res; @@ -352,10 +348,8 @@ int close(int fd) return res; } -FUNC_ALIAS(close, _close, int); -#ifdef CONFIG_POSIX_FSYNC -int fsync(int fd) +int zvfs_fsync(int fd) { if (_check_fd(fd) < 0) { return -1; @@ -363,19 +357,16 @@ int fsync(int fd) return z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_FSYNC); } -FUNC_ALIAS(fsync, _fsync, int); -#endif /* CONFIG_POSIX_FSYNC */ -off_t lseek(int fd, off_t offset, int whence) +off_t zvfs_lseek(int fd, off_t offset, int whence) { if (_check_fd(fd) < 0) { return -1; } - return z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_LSEEK, - offset, whence); + return z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_LSEEK, offset, + whence); } -FUNC_ALIAS(lseek, _lseek, off_t); int ioctl(int fd, unsigned long request, ...) { @@ -393,30 +384,21 @@ int ioctl(int fd, unsigned long request, ...) return res; } -int fcntl(int fd, int cmd, ...) +int zvfs_fcntl(int fd, int cmd, va_list args) { - va_list args; int res; if (_check_fd(fd) < 0) { return -1; } - /* Handle fdtable commands. */ - if (cmd == F_DUPFD) { - /* Not implemented so far. */ - errno = EINVAL; - return -1; - } - /* The rest of commands are per-fd, handled by ioctl vmethod. */ - va_start(args, cmd); res = fdtable[fd].vtable->ioctl(fdtable[fd].obj, cmd, args); - va_end(args); return res; } +#if defined(CONFIG_POSIX_DEVICE_IO) /* * fd operations for stdio/stdout/stderr */ @@ -431,7 +413,7 @@ static ssize_t stdinout_read_vmeth(void *obj, void *buffer, size_t count) static ssize_t stdinout_write_vmeth(void *obj, const void *buffer, size_t count) { #if defined(CONFIG_BOARD_NATIVE_POSIX) - return write(1, buffer, count); + return zvfs_write(1, buffer, count); #elif defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_ARCMWDT_LIBC) return z_impl_zephyr_write_stdout(buffer, count); #else @@ -452,4 +434,4 @@ static const struct fd_op_vtable stdinout_fd_op_vtable = { .ioctl = stdinout_ioctl_vmeth, }; -#endif /* CONFIG_POSIX_API */ +#endif /* defined(CONFIG_POSIX_DEVICE_IO) */ diff --git a/lib/os/mpsc_pbuf.c b/lib/os/mpsc_pbuf.c index 52a26b5d41672b..81025c1cf495b2 100644 --- a/lib/os/mpsc_pbuf.c +++ b/lib/os/mpsc_pbuf.c @@ -14,7 +14,7 @@ mpsc_state_print(buffer); \ } \ } \ -} while (0) +} while (false) static inline void mpsc_state_print(struct mpsc_pbuf_buffer *buffer) { diff --git a/lib/os/zvfs/CMakeLists.txt b/lib/os/zvfs/CMakeLists.txt new file mode 100644 index 00000000000000..ca191a4d3ad7af --- /dev/null +++ b/lib/os/zvfs/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c) diff --git a/lib/os/zvfs/Kconfig b/lib/os/zvfs/Kconfig new file mode 100644 index 00000000000000..7f50ff52befc24 --- /dev/null +++ b/lib/os/zvfs/Kconfig @@ -0,0 +1,36 @@ +# Copyright (c) 2020 Tobias Svehagen +# Copyright (c) 2023 Meta +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ZVFS + bool "Zephyr virtual filesystem (ZVFS) support [EXPERIMENTAL]" + select FDTABLE + select EXPERIMENTAL + help + ZVFS is a central, Zephyr-native library that provides a common interoperable API for all + types of file descriptors such as those from the non-virtual FS, sockets, eventfds, FILE *'s + and more. It is designed to be used by all Zephyr subsystems that need to work with files. + +if ZVFS + +config ZVFS_EVENTFD + bool "ZVFS event file descriptor support" + select POLL + help + Enable support for ZVFS event file descriptors. An eventfd can + be used as an event wait/notify mechanism together with POSIX calls + like read, write and poll. + +if ZVFS_EVENTFD + +config ZVFS_EVENTFD_MAX + int "Maximum number of ZVFS eventfd's" + default 1 + range 1 4096 + help + The maximum number of supported event file descriptors. + +endif # ZVFS_EVENTFD + +endif # ZVFS diff --git a/lib/os/zvfs/zvfs_eventfd.c b/lib/os/zvfs/zvfs_eventfd.c new file mode 100644 index 00000000000000..069f4d680e9317 --- /dev/null +++ b/lib/os/zvfs/zvfs_eventfd.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2020 Tobias Svehagen + * Copyright (c) 2023, Meta + * Copyright (c) 2024, Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ZVFS_EFD_IN_USE 0x1 +#define ZVFS_EFD_FLAGS_SET (ZVFS_EFD_SEMAPHORE | ZVFS_EFD_NONBLOCK) + +struct zvfs_eventfd { + struct k_poll_signal read_sig; + struct k_poll_signal write_sig; + struct k_spinlock lock; + zvfs_eventfd_t cnt; + int flags; +}; + +static ssize_t zvfs_eventfd_rw_op(void *obj, void *buf, size_t sz, + int (*op)(struct zvfs_eventfd *efd, zvfs_eventfd_t *value)); + +SYS_BITARRAY_DEFINE_STATIC(efds_bitarray, CONFIG_ZVFS_EVENTFD_MAX); +static struct zvfs_eventfd efds[CONFIG_ZVFS_EVENTFD_MAX]; +static const struct fd_op_vtable zvfs_eventfd_fd_vtable; + +static inline bool zvfs_eventfd_is_in_use(struct zvfs_eventfd *efd) +{ + return (efd->flags & ZVFS_EFD_IN_USE) != 0; +} + +static inline bool zvfs_eventfd_is_semaphore(struct zvfs_eventfd *efd) +{ + return (efd->flags & ZVFS_EFD_SEMAPHORE) != 0; +} + +static inline bool zvfs_eventfd_is_blocking(struct zvfs_eventfd *efd) +{ + return (efd->flags & ZVFS_EFD_NONBLOCK) == 0; +} + +static int zvfs_eventfd_poll_prepare(struct zvfs_eventfd *efd, + struct zsock_pollfd *pfd, + struct k_poll_event **pev, + struct k_poll_event *pev_end) +{ + if (pfd->events & ZSOCK_POLLIN) { + if (*pev == pev_end) { + errno = ENOMEM; + return -1; + } + + (*pev)->obj = &efd->read_sig; + (*pev)->type = K_POLL_TYPE_SIGNAL; + (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; + (*pev)->state = K_POLL_STATE_NOT_READY; + (*pev)++; + } + + if (pfd->events & ZSOCK_POLLOUT) { + if (*pev == pev_end) { + errno = ENOMEM; + return -1; + } + + (*pev)->obj = &efd->write_sig; + (*pev)->type = K_POLL_TYPE_SIGNAL; + (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; + (*pev)->state = K_POLL_STATE_NOT_READY; + (*pev)++; + } + + return 0; +} + +static int zvfs_eventfd_poll_update(struct zvfs_eventfd *efd, + struct zsock_pollfd *pfd, + struct k_poll_event **pev) +{ + if (pfd->events & ZSOCK_POLLIN) { + pfd->revents |= ZSOCK_POLLIN * (efd->cnt > 0); + (*pev)++; + } + + if (pfd->events & ZSOCK_POLLOUT) { + pfd->revents |= ZSOCK_POLLOUT * (efd->cnt < UINT64_MAX - 1); + (*pev)++; + } + + return 0; +} + +static int zvfs_eventfd_read_locked(struct zvfs_eventfd *efd, zvfs_eventfd_t *value) +{ + if (!zvfs_eventfd_is_in_use(efd)) { + /* file descriptor has been closed */ + return -EBADF; + } + + if (efd->cnt == 0) { + /* would block / try again */ + return -EAGAIN; + } + + /* successful read */ + if (zvfs_eventfd_is_semaphore(efd)) { + *value = 1; + --efd->cnt; + } else { + *value = efd->cnt; + efd->cnt = 0; + } + + if (efd->cnt == 0) { + k_poll_signal_reset(&efd->read_sig); + } + + k_poll_signal_raise(&efd->write_sig, 0); + + return 0; +} + +static int zvfs_eventfd_write_locked(struct zvfs_eventfd *efd, zvfs_eventfd_t *value) +{ + zvfs_eventfd_t result; + + if (!zvfs_eventfd_is_in_use(efd)) { + /* file descriptor has been closed */ + return -EBADF; + } + + if (*value == UINT64_MAX) { + /* not a permitted value */ + return -EINVAL; + } + + if (u64_add_overflow(efd->cnt, *value, &result) || result == UINT64_MAX) { + /* would block / try again */ + return -EAGAIN; + } + + /* successful write */ + efd->cnt = result; + + if (efd->cnt == (UINT64_MAX - 1)) { + k_poll_signal_reset(&efd->write_sig); + } + + k_poll_signal_raise(&efd->read_sig, 0); + + return 0; +} + +static ssize_t zvfs_eventfd_read_op(void *obj, void *buf, size_t sz) +{ + return zvfs_eventfd_rw_op(obj, buf, sz, zvfs_eventfd_read_locked); +} + +static ssize_t zvfs_eventfd_write_op(void *obj, const void *buf, size_t sz) +{ + return zvfs_eventfd_rw_op(obj, (zvfs_eventfd_t *)buf, sz, zvfs_eventfd_write_locked); +} + +static int zvfs_eventfd_close_op(void *obj) +{ + int ret; + int err; + k_spinlock_key_t key; + struct k_mutex *lock = NULL; + struct k_condvar *cond = NULL; + struct zvfs_eventfd *efd = (struct zvfs_eventfd *)obj; + + if (k_is_in_isr()) { + /* not covered by the man page, but necessary in Zephyr */ + errno = EWOULDBLOCK; + return -1; + } + + err = (int)z_get_obj_lock_and_cond(obj, &zvfs_eventfd_fd_vtable, &lock, &cond); + __ASSERT((bool)err, "z_get_obj_lock_and_cond() failed"); + __ASSERT_NO_MSG(lock != NULL); + __ASSERT_NO_MSG(cond != NULL); + + err = k_mutex_lock(lock, K_FOREVER); + __ASSERT(err == 0, "k_mutex_lock() failed: %d", err); + + key = k_spin_lock(&efd->lock); + + if (!zvfs_eventfd_is_in_use(efd)) { + errno = EBADF; + ret = -1; + goto unlock; + } + + err = sys_bitarray_free(&efds_bitarray, 1, (struct zvfs_eventfd *)obj - efds); + __ASSERT(err == 0, "sys_bitarray_free() failed: %d", err); + + efd->flags = 0; + efd->cnt = 0; + + ret = 0; + +unlock: + k_spin_unlock(&efd->lock, key); + /* when closing an zvfs_eventfd, broadcast to all waiters */ + err = k_condvar_broadcast(cond); + __ASSERT(err == 0, "k_condvar_broadcast() failed: %d", err); + err = k_mutex_unlock(lock); + __ASSERT(err == 0, "k_mutex_unlock() failed: %d", err); + + return ret; +} + +static int zvfs_eventfd_ioctl_op(void *obj, unsigned int request, va_list args) +{ + int ret; + k_spinlock_key_t key; + struct zvfs_eventfd *efd = (struct zvfs_eventfd *)obj; + + /* note: zsock_poll_internal() has already taken the mutex */ + key = k_spin_lock(&efd->lock); + + if (!zvfs_eventfd_is_in_use(efd)) { + errno = EBADF; + ret = -1; + goto unlock; + } + + switch (request) { + case F_GETFL: + ret = efd->flags & ZVFS_EFD_FLAGS_SET; + break; + + case F_SETFL: { + int flags; + + flags = va_arg(args, int); + + if (flags & ~ZVFS_EFD_FLAGS_SET) { + errno = EINVAL; + ret = -1; + } else { + int prev_flags = efd->flags & ~ZVFS_EFD_FLAGS_SET; + + efd->flags = flags | prev_flags; + ret = 0; + } + } break; + + case ZFD_IOCTL_POLL_PREPARE: { + struct zsock_pollfd *pfd; + struct k_poll_event **pev; + struct k_poll_event *pev_end; + + pfd = va_arg(args, struct zsock_pollfd *); + pev = va_arg(args, struct k_poll_event **); + pev_end = va_arg(args, struct k_poll_event *); + + ret = zvfs_eventfd_poll_prepare(obj, pfd, pev, pev_end); + } break; + + case ZFD_IOCTL_POLL_UPDATE: { + struct zsock_pollfd *pfd; + struct k_poll_event **pev; + + pfd = va_arg(args, struct zsock_pollfd *); + pev = va_arg(args, struct k_poll_event **); + + ret = zvfs_eventfd_poll_update(obj, pfd, pev); + } break; + + default: + errno = EOPNOTSUPP; + ret = -1; + break; + } + +unlock: + k_spin_unlock(&efd->lock, key); + + return ret; +} + +static const struct fd_op_vtable zvfs_eventfd_fd_vtable = { + .read = zvfs_eventfd_read_op, + .write = zvfs_eventfd_write_op, + .close = zvfs_eventfd_close_op, + .ioctl = zvfs_eventfd_ioctl_op, +}; + +/* common to both zvfs_eventfd_read_op() and zvfs_eventfd_write_op() */ +static ssize_t zvfs_eventfd_rw_op(void *obj, void *buf, size_t sz, + int (*op)(struct zvfs_eventfd *efd, zvfs_eventfd_t *value)) +{ + int err; + ssize_t ret; + k_spinlock_key_t key; + struct zvfs_eventfd *efd = obj; + struct k_mutex *lock = NULL; + struct k_condvar *cond = NULL; + + if (sz < sizeof(zvfs_eventfd_t)) { + errno = EINVAL; + return -1; + } + + if (buf == NULL) { + errno = EFAULT; + return -1; + } + + key = k_spin_lock(&efd->lock); + + if (!zvfs_eventfd_is_blocking(efd)) { + /* + * Handle the non-blocking case entirely within this scope + */ + ret = op(efd, buf); + if (ret < 0) { + errno = -ret; + ret = -1; + } else { + ret = sizeof(zvfs_eventfd_t); + } + + goto unlock_spin; + } + + /* + * Handle the blocking case below + */ + __ASSERT_NO_MSG(zvfs_eventfd_is_blocking(efd)); + + if (k_is_in_isr()) { + /* not covered by the man page, but necessary in Zephyr */ + errno = EWOULDBLOCK; + ret = -1; + goto unlock_spin; + } + + err = (int)z_get_obj_lock_and_cond(obj, &zvfs_eventfd_fd_vtable, &lock, &cond); + __ASSERT((bool)err, "z_get_obj_lock_and_cond() failed"); + __ASSERT_NO_MSG(lock != NULL); + __ASSERT_NO_MSG(cond != NULL); + + /* do not hold a spinlock when taking a mutex */ + k_spin_unlock(&efd->lock, key); + err = k_mutex_lock(lock, K_FOREVER); + __ASSERT(err == 0, "k_mutex_lock() failed: %d", err); + + while (true) { + /* retake the spinlock */ + key = k_spin_lock(&efd->lock); + + ret = op(efd, buf); + switch (ret) { + case -EAGAIN: + /* not an error in blocking mode. break and try again */ + break; + case 0: + /* success! */ + ret = sizeof(zvfs_eventfd_t); + goto unlock_mutex; + default: + /* some other error */ + __ASSERT_NO_MSG(ret < 0); + errno = -ret; + ret = -1; + goto unlock_mutex; + } + + /* do not hold a spinlock when taking a mutex */ + k_spin_unlock(&efd->lock, key); + + /* wait for a write or close */ + err = k_condvar_wait(cond, lock, K_FOREVER); + __ASSERT(err == 0, "k_condvar_wait() failed: %d", err); + } + +unlock_mutex: + k_spin_unlock(&efd->lock, key); + /* only wake a single waiter */ + err = k_condvar_signal(cond); + __ASSERT(err == 0, "k_condvar_signal() failed: %d", err); + err = k_mutex_unlock(lock); + __ASSERT(err == 0, "k_mutex_unlock() failed: %d", err); + goto out; + +unlock_spin: + k_spin_unlock(&efd->lock, key); + +out: + return ret; +} + +/* + * Public-facing API + */ + +int zvfs_eventfd(unsigned int initval, int flags) +{ + int fd = 1; + size_t offset; + struct zvfs_eventfd *efd = NULL; + + if (flags & ~ZVFS_EFD_FLAGS_SET) { + errno = EINVAL; + return -1; + } + + if (sys_bitarray_alloc(&efds_bitarray, 1, &offset) < 0) { + errno = ENOMEM; + return -1; + } + + efd = &efds[offset]; + + fd = z_reserve_fd(); + if (fd < 0) { + sys_bitarray_free(&efds_bitarray, 1, offset); + return -1; + } + + efd->flags = ZVFS_EFD_IN_USE | flags; + efd->cnt = initval; + + k_poll_signal_init(&efd->write_sig); + k_poll_signal_init(&efd->read_sig); + + if (initval != 0) { + k_poll_signal_raise(&efd->read_sig, 0); + } + + k_poll_signal_raise(&efd->write_sig, 0); + + z_finalize_fd(fd, efd, &zvfs_eventfd_fd_vtable); + + return fd; +} + +int zvfs_eventfd_read(int fd, zvfs_eventfd_t *value) +{ + int ret; + void *obj; + + obj = z_get_fd_obj(fd, &zvfs_eventfd_fd_vtable, EBADF); + if (obj == NULL) { + return -1; + } + + ret = zvfs_eventfd_rw_op(obj, value, sizeof(zvfs_eventfd_t), zvfs_eventfd_read_locked); + __ASSERT_NO_MSG(ret == -1 || ret == sizeof(zvfs_eventfd_t)); + if (ret < 0) { + return -1; + } + + return 0; +} + +int zvfs_eventfd_write(int fd, zvfs_eventfd_t value) +{ + int ret; + void *obj; + + obj = z_get_fd_obj(fd, &zvfs_eventfd_fd_vtable, EBADF); + if (obj == NULL) { + return -1; + } + + ret = zvfs_eventfd_rw_op(obj, &value, sizeof(zvfs_eventfd_t), zvfs_eventfd_write_locked); + __ASSERT_NO_MSG(ret == -1 || ret == sizeof(zvfs_eventfd_t)); + if (ret < 0) { + return -1; + } + + return 0; +} diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index 96995cbeebb810..b4981a62eace13 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -2,15 +2,13 @@ set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) -zephyr_syscall_header( - posix_clock.h -) +zephyr_syscall_header_ifdef(CONFIG_POSIX_TIMERS posix_clock.h) if(CONFIG_POSIX_API) zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix) endif() -if(CONFIG_POSIX_SIGNAL) +if(CONFIG_POSIX_SIGNALS) set(STRSIGNAL_TABLE_H ${GEN_DIR}/posix/strsignal_table.h) add_custom_command( @@ -24,8 +22,9 @@ if(CONFIG_POSIX_SIGNAL) ) endif() -if(CONFIG_POSIX_API OR CONFIG_PTHREAD_IPC OR CONFIG_POSIX_CLOCK OR - CONFIG_POSIX_MQUEUE OR CONFIG_POSIX_FS OR CONFIG_EVENTFD OR CONFIG_GETOPT) +if(CONFIG_POSIX_API OR CONFIG_POSIX_THREADS OR CONFIG_POSIX_TIMERS OR + CONFIG_POSIX_MESSAGE_PASSING OR CONFIG_POSIX_FILE_SYSTEM OR CONFIG_EVENTFD OR + CONFIG_POSIX_C_LIB_EXT OR CONFIG_POSIX_SINGLE_PROCESS) # This is a temporary workaround so that Newlib declares the appropriate # types for us. POSIX features to be formalized as part of #51211 zephyr_compile_options($<$:-D_POSIX_THREADS>) @@ -33,36 +32,63 @@ if(CONFIG_POSIX_API OR CONFIG_PTHREAD_IPC OR CONFIG_POSIX_CLOCK OR endif() zephyr_library() -add_subdirectory_ifdef(CONFIG_GETOPT getopt) zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c) -zephyr_library_sources_ifdef(CONFIG_FNMATCH fnmatch.c) -zephyr_library_sources_ifdef(CONFIG_GETENTROPY getentropy.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_API perror.c) zephyr_library_sources_ifdef(CONFIG_POSIX_ASYNCHRONOUS_IO aio.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK clock.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK nanosleep.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK sleep.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_CONFSTR confstr.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_ENV env.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_FS fs.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_MQUEUE mqueue.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_BARRIERS barrier.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_C_LIB_EXT + fnmatch.c + getentropy.c + getopt/getopt.c + getopt/getopt_common.c +) +zephyr_library_sources_ifdef(CONFIG_POSIX_DEVICE_IO + # perror should be moved to the common libc + perror.c + device_io.c +) +zephyr_library_sources_ifdef(CONFIG_POSIX_FD_MGMT + fd_mgmt.c +) +zephyr_library_sources_ifdef(CONFIG_POSIX_FILE_SYSTEM fs.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_FSYNC fsync.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_MESSAGE_PASSING mqueue.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_MULTI_PROCESS + sleep.c + multi_process.c +) zephyr_library_sources_ifdef(CONFIG_POSIX_NETWORKING net.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_PUTMSG stropts.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_SIGNAL signal.c ${STRSIGNAL_TABLE_H}) -zephyr_library_sources_ifdef(CONFIG_POSIX_SYSCONF_IMPL_FULL sysconf.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_SIGNALS signal.c ${STRSIGNAL_TABLE_H}) +zephyr_library_sources_ifdef(CONFIG_POSIX_SINGLE_PROCESS + confstr.c + env.c + sysconf.c + uname.c +) +zephyr_library_sources_ifdef(CONFIG_POSIX_SPIN_LOCKS spinlock.c) zephyr_library_sources_ifdef(CONFIG_POSIX_SYSLOG syslog.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_UNAME uname.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC _common.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_BARRIER barrier.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_COND cond.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_KEY key.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_MUTEX mutex.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD pthread.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_RWLOCK rwlock.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_TIMERS + clock.c + timer.c + timespec_to_timeout.c +) zephyr_library_sources_ifdef(CONFIG_POSIX_PRIORITY_SCHEDULING sched.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC semaphore.c) -zephyr_library_sources_ifdef(CONFIG_PTHREAD_SPINLOCK spinlock.c) -zephyr_library_sources_ifdef(CONFIG_TIMER timer.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_READER_WRITER_LOCKS rwlock.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_SEMAPHORES semaphore.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_THREADS + cond.c + key.c + mutex.c + pthread.c +) +zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c) +zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c) + +zephyr_library_sources_ifdef(CONFIG_GETOPT_LONG + getopt/getopt_long.c +) +zephyr_include_directories_ifdef(CONFIG_POSIX_C_LIB_EXT + getopt/ +) zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include diff --git a/lib/posix/options/Kconfig b/lib/posix/options/Kconfig index 2197148bca5bb4..bdf0ed4901f051 100644 --- a/lib/posix/options/Kconfig +++ b/lib/posix/options/Kconfig @@ -1,56 +1,36 @@ # Copyright (c) 2018 Intel Corporation # Copyright (c) 2023 Meta +# Copyright (c) 2024 Tenstorrent AI ULC # # SPDX-License-Identifier: Apache-2.0 menu "POSIX Options" -config POSIX_API - depends on !NATIVE_APPLICATION - bool "POSIX APIs" - select NATIVE_LIBC_INCOMPATIBLE - help - Enable mostly-standards-compliant implementations of - various POSIX (IEEE 1003.1) APIs. - -if POSIX_CLOCK - -config PTHREAD_IPC - bool "POSIX pthread IPC API" - default y if POSIX_API - help - This enables a mostly-standards-compliant implementation of - the pthread mutex, condition variable and barrier IPC - mechanisms. - -endif # POSIX_CLOCK +rsource "Kconfig.profile" rsource "Kconfig.aio" rsource "Kconfig.barrier" -rsource "Kconfig.clock" -rsource "Kconfig.cond" -rsource "Kconfig.confstr" -rsource "Kconfig.env" -rsource "Kconfig.eventfd" -rsource "Kconfig.fdtable" -rsource "Kconfig.fnmatch" +rsource "Kconfig.c_lib_ext" +rsource "Kconfig.device_io" +rsource "Kconfig.fd_mgmt" rsource "Kconfig.fs" -rsource "Kconfig.getentropy" -rsource "Kconfig.getopt" -rsource "Kconfig.key" +rsource "Kconfig.mem" rsource "Kconfig.mqueue" -rsource "Kconfig.mutex" rsource "Kconfig.net" +rsource "Kconfig.proc1" +rsource "Kconfig.procN" rsource "Kconfig.pthread" rsource "Kconfig.rwlock" rsource "Kconfig.sched" rsource "Kconfig.semaphore" rsource "Kconfig.signal" rsource "Kconfig.spinlock" -rsource "Kconfig.stropts" -rsource "Kconfig.sysconf" -rsource "Kconfig.syslog" +rsource "Kconfig.sync_io" rsource "Kconfig.timer" -rsource "Kconfig.uname" +rsource "Kconfig.xsi" + +rsource "Kconfig.compat" + +rsource "Kconfig.deprecated" endmenu # "POSIX Options" diff --git a/lib/posix/options/Kconfig.aio b/lib/posix/options/Kconfig.aio index 6fc35349738f3f..43e681f39abc80 100644 --- a/lib/posix/options/Kconfig.aio +++ b/lib/posix/options/Kconfig.aio @@ -3,8 +3,8 @@ # SPDX-License-Identifier: Apache-2.0 config POSIX_ASYNCHRONOUS_IO - bool "Asynchronous IO" - default y if POSIX_API + bool "POSIX asynchronous I/O [EXPERIMENTAL]" + select EXPERIMENTAL help Enable this option for asynchronous I/O. This option is present for conformance purposes only. All functions listed in return -1 and set errno to ENOSYS. diff --git a/lib/posix/options/Kconfig.barrier b/lib/posix/options/Kconfig.barrier index 72dd8148277590..b349d0376551b3 100644 --- a/lib/posix/options/Kconfig.barrier +++ b/lib/posix/options/Kconfig.barrier @@ -1,17 +1,29 @@ # Copyright (c) 2017 Intel Corporation # Copyright (c) 2023 Meta +# Copyright (c) 2024 Tenstorrent # # SPDX-License-Identifier: Apache-2.0 -TYPE = PTHREAD_BARRIER -type = pthread_barrier_t -type-function = pthread_barrier_wait -rsource "Kconfig.template.pooled_ipc_type" +menuconfig POSIX_BARRIERS + bool "POSIX barriers" + help + Select 'y' here to enable POSIX barriers. + + For more information please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_BARRIERS -if PTHREAD_BARRIER +config MAX_PTHREAD_BARRIER_COUNT + int "Maximum number of POSIX barriers" + default 5 + help + Maximum simultaneously active pthread_barrier_t in a POSIX application. + + Note: this is a non-standard option. config PTHREAD_CREATE_BARRIER - bool "Use a pthread_barrier_t to serialize pthread_create()" + bool "Use a POSIX barrier to serialize pthread_create()" help When running several SMP applications in parallel instances of Qemu, e.g. via twister, explicit serialization may be required between @@ -21,4 +33,8 @@ config PTHREAD_CREATE_BARRIER On such systems, say Y here to introduce explicit serialization via pthread_barrier_wait(). -endif +module = PTHREAD_BARRIER +module-str = POSIX thread barriers +source "subsys/logging/Kconfig.template.log_config" + +endif # POSIX_BARRIERS diff --git a/lib/posix/options/Kconfig.c_lib_ext b/lib/posix/options/Kconfig.c_lib_ext new file mode 100644 index 00000000000000..e8c55d8818b19a --- /dev/null +++ b/lib/posix/options/Kconfig.c_lib_ext @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig POSIX_C_LIB_EXT + bool "POSIX general C library extension" + help + Select 'y' here and Zephyr will provide an implementation of the POSIX_C_LIB_EXT Option + Group, consisting of fnmatch(), getopt(), getsubopt(), optarg, opterr, optind, optopt, + stpcpy(), stpncpy(), strcasecmp(), strdup(), strfmon(), and strncasecmp(), strndup(), and + strnlen(). + + For more informnation, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_C_LIB_EXT + +config GETOPT_LONG + bool "Getopt long library support" + help + This option adds support of the getopt long. + Different shell backends are using their own instance of getopt to + not interfere with each other. + All not shell threads share one global instance of getopt state, hence + apart from shell this library is not thread safe. User can add support + for other threads by extending function getopt_state_get in + getopt_common.c file. + +endif # POSIX_C_LIB_EXT diff --git a/lib/posix/options/Kconfig.clock b/lib/posix/options/Kconfig.clock deleted file mode 100644 index 0d541c9f32fd8e..00000000000000 --- a/lib/posix/options/Kconfig.clock +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2018 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -config POSIX_CLOCK - bool "clock and sleep APIs" - default y if POSIX_API - imply TIMER - depends on !NATIVE_LIBC - help - This enables POSIX clock\_\*() and \*sleep() functions. diff --git a/lib/posix/options/Kconfig.eventfd b/lib/posix/options/Kconfig.compat similarity index 59% rename from lib/posix/options/Kconfig.eventfd rename to lib/posix/options/Kconfig.compat index eadf8f80916f6d..a07c2b125795e8 100644 --- a/lib/posix/options/Kconfig.eventfd +++ b/lib/posix/options/Kconfig.compat @@ -3,21 +3,16 @@ # # SPDX-License-Identifier: Apache-2.0 -menuconfig EVENTFD +menu "Miscellaneous POSIX-related options" + +config EVENTFD bool "Support for eventfd" depends on !NATIVE_APPLICATION - select POLL - select FDTABLE - default y if POSIX_API + select ZVFS + select ZVFS_EVENTFD help Enable support for event file descriptors, eventfd. An eventfd can be used as an event wait/notify mechanism together with POSIX calls like read, write and poll. -config EVENTFD_MAX - int "Maximum number of eventfd's" - depends on EVENTFD - default 1 - range 1 4096 - help - The maximum number of supported event file descriptors. +endmenu diff --git a/lib/posix/options/Kconfig.cond b/lib/posix/options/Kconfig.cond deleted file mode 100644 index b69b35dece6f8a..00000000000000 --- a/lib/posix/options/Kconfig.cond +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017 Intel Corporation -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -TYPE = PTHREAD_COND -type = pthread_cond_t -type-function = pthread_cond_wait -rsource "Kconfig.template.pooled_ipc_type" diff --git a/lib/posix/options/Kconfig.confstr b/lib/posix/options/Kconfig.confstr deleted file mode 100644 index 154f14f2d52512..00000000000000 --- a/lib/posix/options/Kconfig.confstr +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2024, Meta -# -# SPDX-License-Identifier: Apache-2.0 - -config POSIX_CONFSTR - bool "Retrieve string system configuration" - default y if POSIX_API - help - This enables the POSIX confstr() function. diff --git a/lib/posix/options/Kconfig.deprecated b/lib/posix/options/Kconfig.deprecated new file mode 100644 index 00000000000000..3f39a701dc9ce5 --- /dev/null +++ b/lib/posix/options/Kconfig.deprecated @@ -0,0 +1,313 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +# This file should be removed after Zephyr 4.0 is released + +menu "Deprecated POSIX options" + +config EVENTFD_MAX + int "Maximum number of eventfd's [DEPRECATED]" + default ZVFS_EVENTFD_MAX if ZVFS_EVENTFD + default 0 + help + This option is deprecated. + + Please use CONFIG_ZVFS_EVENTFD_MAX instead. + +config FNMATCH + bool "Support for fnmatch [DEPRECATED]" + select DEPRECATED + select POSIX_C_LIB_EXT + help + This option is deprecated. + + Please use CONFIG_POSIX_C_LIB_EXT instead. + +config GETENTROPY + bool "Support for getentropy [DEPRECATED]" + select DEPRECATED + select POSIX_C_LIB_EXT + help + This option is deprecated. + + Please use CONFIG_POSIX_C_LIB_EXT instead. + +config GETOPT + bool "Getopt library support [DEPRECATED]" + select DEPRECATED + select POSIX_C_LIB_EXT + help + This option is deprecated. + + Please use CONFIG_POSIX_C_LIB_EXT instead. + +config MAX_PTHREAD_COUNT + int "Maximum number of pthread_t [DEPRECATED]" + default POSIX_THREAD_THREADS_MAX if POSIX_THREADS + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_THREAD_THREADS_MAX instead. + +config MAX_PTHREAD_KEY_COUNT + int "Maximum number of pthread_key_t [DEPRECATED]" + default POSIX_THREAD_KEYS_MAX if POSIX_THREADS + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_THREAD_KEYS_MAX instead. + +config MAX_TIMER_COUNT + int "Maximum number of timer_t [DEPRECATED]" + default POSIX_TIMER_MAX if POSIX_TIMERS + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_TIMER_MAX instead. + +config MSG_COUNT_MAX + int "Maximum number of messages in a POSIX message queue [DEPRECATED]" + default POSIX_MQ_OPEN_MAX if POSIX_MESSAGE_PASSING + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_MQ_OPEN_MAX instead. + +config POSIX_CLOCK + bool "clock and sleep APIs [DEPRECATED]" + select DEPRECATED + select POSIX_CLOCK_SELECTION + select POSIX_CPUTIME + select POSIX_MONOTONIC_CLOCK + select POSIX_TIMERS + select POSIX_TIMEOUTS + help + This option is deprecated. + + Please use CONFIG_POSIX_TIMERS instead. + +config POSIX_CONFSTR + bool "Retrieve string system configuration [DEPRECATED]" + select DEPRECATED + select POSIX_SINGLE_PROCESS + help + This option is deprecated. + + Please use CONFIG_POSIX_SINGLE_PROCESS instead. + +config POSIX_ENV + bool "Support for environ, getenv(), getenv_r(), setenv(), and unsetenv() [DEPRECATED]" + select DEPRECATED + select POSIX_SINGLE_PROCESS + help + This option is deprecated. + + Please use CONFIG_POSIX_SINGLE_PROCESS instead. + +config POSIX_FS + bool "Support for environ, getenv(), getenv_r(), setenv(), and unsetenv() [DEPRECATED]" + select DEPRECATED + select POSIX_FILE_SYSTEM + help + This option is deprecated. + + Please use CONFIG_POSIX_FILE_SYSTEM instead. + +config POSIX_LIMITS_RTSIG_MAX + int "_POSIX_RTSIG_MAX value in limits.h [DEPRECATED]" + default POSIX_RTSIG_MAX if POSIX_REALTIME_SIGNALS + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_RTSIG_MAX instead. + +config POSIX_MAX_FDS + int "Maximum number of open file descriptors [DEPRECATED]" + default POSIX_OPEN_MAX + help + This option is deprecated. + + Please use CONFIG_POSIX_OPEN_MAX instead. + + See also CONFIG_ZVFS_OPEN_MAX. + +config POSIX_MAX_OPEN_FILES + int "Maximum number of open file descriptors [DEPRECATED]" + default POSIX_OPEN_MAX + help + This option is deprecated. + + Please use CONFIG_POSIX_OPEN_MAX instead. + + See also CONFIG_ZVFS_OPEN_MAX. + +config POSIX_MQUEUE + bool "Message queue support [DEPRECATED]" + select DEPRECATED + select POSIX_MESSAGE_PASSING + help + This option is deprecated. + + Please use CONFIG_POSIX_MESSAGE_PASSING instead. + +config POSIX_PUTMSG + bool "Support for putmsg function [DEPRECATED]" + select DEPRECATED + select XOPEN_STREAMS + help + This option is deprecated. + + Please use CONFIG_XOPEN_STREAMS instead. + +config POSIX_SIGNAL + bool "Support for POSIX signal APIs [DEPRECATED]" + select DEPRECATED + select POSIX_SIGNALS + help + This option is deprecated. + + Please use CONFIG_POSIX_SIGNALS instead. + +config POSIX_SYSCONF + bool "Support for sysconf() [DEPRECATED]" + select DEPRECATED + select POSIX_SINGLE_PROCESS + help + This option is deprecated. + + Please use CONFIG_POSIX_SINGLE_PROCESS instead. + +config POSIX_SYSLOG + bool "Support for syslog() [DEPRECATED]" + select DEPRECATED + select XSI_SYSTEM_LOGGING + help + This option is deprecated. + + Please use CONFIG_XSI_SYSTEM_LOGGING instead. + +config POSIX_UNAME + bool "Support for uname [DEPRECATED]" + select DEPRECATED + select POSIX_SINGLE_PROCESS + help + This option is deprecated. + + Please use CONFIG_POSIX_SINGLE_PROCESS instead. + +config PTHREAD + bool "pthread_t support [DEPRECATED]" + select DEPRECATED + select POSIX_THREADS + help + This option is deprecated. + + Please use CONFIG_POSIX_THREADS instead. + +config PTHREAD_BARRIER + bool "pthread_barrier_t support [DEPRECATED]" + select DEPRECATED + select POSIX_BARRIERS + help + This option is deprecated. + + Please use CONFIG_POSIX_BARRIERS instead. + +config PTHREAD_COND + bool "pthread_cond_t support [DEPRECATED]" + select DEPRECATED + select POSIX_THREADS + help + This option is deprecated. + + Please use CONFIG_POSIX_THREADS instead. + + +config PTHREAD_IPC + bool "POSIX pthread IPC API [DEPRECATED]" + select DEPRECATED + select POSIX_THREADS + help + This option is deprecated. + + Please use CONFIG_POSIX_THREADS instead. + +config PTHREAD_KEY + bool "pthread_key_t support [DEPRECATED]" + select DEPRECATED + select POSIX_THREADS + help + This option is deprecated. + + Please use CONFIG_POSIX_THREADS instead. + +config PTHREAD_MUTEX + bool "pthread_mutex_t support [DEPRECATED]" + select DEPRECATED + select POSIX_THREADS + help + This option is deprecated. + + Please use CONFIG_POSIX_THREADS instead. + +config PTHREAD_RWLOCK + bool "pthread_spinlock_t support [DEPRECATED]" + select DEPRECATED + select POSIX_READER_WRITER_LOCKS + help + This option is deprecated. + + Please use CONFIG_POSIX_READER_WRITER_LOCKS instead. + +config PTHREAD_SPINLOCK + bool "pthread_spinlock_t support [DEPRECATED]" + select DEPRECATED + select POSIX_SPIN_LOCKS + help + This option is deprecated. + + Please use CONFIG_POSIX_SPIN_LOCKS instead. + +config TIMER + bool "Timer support [DEPRECATED]" + select DEPRECATED + select POSIX_TIMERS + help + This option is deprecated. + + Please use CONFIG_POSIX_TIMERS instead. + +config TIMER_DELAYTIMER_MAX + int "Maximum count returned my timer_getoverrun() in POSIX application [DEPRECATED]" + default POSIX_DELAYTIMER_MAX if POSIX_TIMERS + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_DELAYTIMER_MAX instead. + +config SEM_NAMELEN_MAX + int "Maximum name length [DEPRECATED]" + default POSIX_SEM_NAMELEN_MAX if POSIX_SEMAPHORES + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_SEM_NAMELEN_MAX instead. + +config SEM_VALUE_MAX + int "Maximum semaphore limit [DEPRECATED]" + default POSIX_SEM_VALUE_MAX if POSIX_SEMAPHORES + default 0 + help + This option is deprecated. + + Please use CONFIG_POSIX_SEM_VALUE_MAX instead. + +endmenu diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io new file mode 100644 index 00000000000000..9cfbd453102bcb --- /dev/null +++ b/lib/posix/options/Kconfig.device_io @@ -0,0 +1,56 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menu "POSIX device I/O" + +config POSIX_DEVICE_IO + bool "POSIX device I/O [EXPERIMENTAL]" + select FDTABLE + select EXPERIMENTAL + help + Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option + Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), + poll(), pread(), pselect(), pwrite(), read(), select(), and write(). + + For more informnation, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_DEVICE_IO + +# These options are intended to be used for compatibility with external POSIX +# implementations such as those in Newlib or Picolibc. + +config POSIX_DEVICE_IO_ALIAS_CLOSE + bool + help + Select 'y' here and Zephyr will provide an alias for close() as _close(). + +config POSIX_DEVICE_IO_ALIAS_OPEN + bool + help + Select 'y' here and Zephyr will provide an alias for open() as _open(). + +config POSIX_DEVICE_IO_ALIAS_READ + bool + help + Select 'y' here and Zephyr will provide an alias for read() as _read(). + +config POSIX_DEVICE_IO_ALIAS_WRITE + bool + help + Select 'y' here and Zephyr will provide an alias for write() as _write(). + +endif # POSIX_DEVICE_IO + +config POSIX_OPEN_MAX + int + default ZVFS_OPEN_MAX + help + The maximum number of files that a process can have open at one time. This option is not + directly user-configurable but can be adjusted via CONFIG_ZVFS_OPEN_MAX. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html + +endmenu diff --git a/lib/posix/options/Kconfig.env b/lib/posix/options/Kconfig.env deleted file mode 100644 index 222392d273719e..00000000000000 --- a/lib/posix/options/Kconfig.env +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2023, Meta -# -# SPDX-License-Identifier: Apache-2.0 - -config POSIX_ENV - bool "Support for environ, getenv(), getenv_r(), setenv(), and unsetenv()" - depends on COMMON_LIBC_MALLOC - default y if POSIX_API - help - Select this option to add support for environment variables. - -module = POSIX_ENV -module-str = POSIX env logging -source "subsys/logging/Kconfig.template.log_config" diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt new file mode 100644 index 00000000000000..ca165395601482 --- /dev/null +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig POSIX_FD_MGMT + bool "POSIX file descriptor management [EXPERIMENTAL]" + select EXPERIMENTAL + help + Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group. + This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(), + and lseek(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_FD_MGMT + +# These options are intended to be used for compatibility with external POSIX +# implementations such as those in Newlib or Picolibc. + +config POSIX_FD_MGMT_ALIAS_FCNTL + bool + help + Select 'y' here and Zephyr will provide an alias for fcntl() as _fcntl(). + +config POSIX_FD_MGMT_ALIAS_FTRUNCATE + bool + help + Select 'y' here and Zephyr will provide an alias for ftruncate() as _ftruncate(). + +config POSIX_FD_MGMT_ALIAS_LSEEK + bool + help + Select 'y' here and Zephyr will provide an alias for lseek() as _lseek(). + +endif # POSIX_FD_MGMT diff --git a/lib/posix/options/Kconfig.fdtable b/lib/posix/options/Kconfig.fdtable deleted file mode 100644 index 214e4a04ae98f0..00000000000000 --- a/lib/posix/options/Kconfig.fdtable +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2018 Linaro -# -# SPDX-License-Identifier: Apache-2.0 - -menu "File descriptor table options" - -config POSIX_MAX_FDS - int "Maximum number of open file descriptors" - default 16 if WIFI_NM_WPA_SUPPLICANT - default 16 if POSIX_API - default 4 - help - Maximum number of open file descriptors, this includes - files, sockets, special devices, etc. - -endmenu # "File descriptor table options" diff --git a/lib/posix/options/Kconfig.fnmatch b/lib/posix/options/Kconfig.fnmatch deleted file mode 100644 index 81f1a00938f3a4..00000000000000 --- a/lib/posix/options/Kconfig.fnmatch +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2018 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -config FNMATCH - bool "Support for fnmatch" - default y if POSIX_API - help - Match filenames using the the fnmatch function. For example, the pattern - "*.c" matches the filename "hello.c". diff --git a/lib/posix/options/Kconfig.fs b/lib/posix/options/Kconfig.fs index bff95a906a9cfa..663d706e3fb803 100644 --- a/lib/posix/options/Kconfig.fs +++ b/lib/posix/options/Kconfig.fs @@ -2,27 +2,19 @@ # # SPDX-License-Identifier: Apache-2.0 -menuconfig POSIX_FS +menuconfig POSIX_FILE_SYSTEM bool "POSIX file system API support" default y if POSIX_API - depends on FILE_SYSTEM + select FILE_SYSTEM select FDTABLE help This enables POSIX style file system related APIs. -if POSIX_FS +if POSIX_FILE_SYSTEM -config POSIX_MAX_OPEN_FILES - int "Maximum number of open file descriptors" - default 16 +config POSIX_FILE_SYSTEM_ALIAS_FSTAT + bool help - Maximum number of open files. Note that this setting - is additionally bounded by CONFIG_POSIX_MAX_FDS. + Select 'y' here and Zephyr will provide an alias for fstat() as _fstat(). -config POSIX_FSYNC - bool "Support for fsync()" - default y - help - This enables fsync() support. - -endif # POSIX_FS +endif # POSIX_FILE_SYSTEM diff --git a/lib/posix/options/Kconfig.getentropy b/lib/posix/options/Kconfig.getentropy deleted file mode 100644 index 74454135019296..00000000000000 --- a/lib/posix/options/Kconfig.getentropy +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024 Google LLC -# -# SPDX-License-Identifier: Apache-2.0 - -DT_CHOSEN_ZEPHYR_ENTROPY := zephyr,entropy - -config GETENTROPY - bool "Support for getentropy" - depends on !NATIVE_APPLICATION - select NATIVE_LIBC_INCOMPATIBLE - depends on ENTROPY_HAS_DRIVER - depends on $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_ENTROPY)) - help - Enable support for getentropy() function. diff --git a/lib/posix/options/Kconfig.getopt b/lib/posix/options/Kconfig.getopt deleted file mode 100644 index 4d3559cd855c32..00000000000000 --- a/lib/posix/options/Kconfig.getopt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -rsource "getopt/Kconfig" diff --git a/lib/posix/options/Kconfig.key b/lib/posix/options/Kconfig.key deleted file mode 100644 index 671cce103735d7..00000000000000 --- a/lib/posix/options/Kconfig.key +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2018 Intel Corporation -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -TYPE = PTHREAD_KEY -type = pthread_key_t -type-function = pthread_setspecific -rsource "Kconfig.template.pooled_ipc_type" diff --git a/lib/posix/options/Kconfig.mem b/lib/posix/options/Kconfig.mem new file mode 100644 index 00000000000000..5a5783340919d5 --- /dev/null +++ b/lib/posix/options/Kconfig.mem @@ -0,0 +1,13 @@ +# Copyright (c) 2024 BayLibre SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config POSIX_PAGE_SIZE_BITS + int "Number of bits to use for PAGE_SIZE" + range 6 16 + default 12 if POSIX_BASE_DEFINITIONS + default 6 + help + Define PAGE_SIZE as BIT(n), where n is the value configured here. + PAGE_SIZE is supported in the range [64, 65536] + If CONFIG_POSIX_API=y, PAGE_SIZE defaults to 4096, otherwise, it is 64 bytes. diff --git a/lib/posix/options/Kconfig.mqueue b/lib/posix/options/Kconfig.mqueue index 3688455d781fa3..4a1e9925fdaf13 100644 --- a/lib/posix/options/Kconfig.mqueue +++ b/lib/posix/options/Kconfig.mqueue @@ -2,33 +2,38 @@ # # SPDX-License-Identifier: Apache-2.0 -menuconfig POSIX_MQUEUE - bool "Message queue support" - default y if POSIX_API +menuconfig POSIX_MESSAGE_PASSING + bool "POSIX message queue support" help This enabled POSIX message queue related APIs. -if POSIX_MQUEUE +if POSIX_MESSAGE_PASSING -config MSG_COUNT_MAX - int "Maximum number of messages in message queue" +config POSIX_MQ_OPEN_MAX + int "Maximum number of messages in a POSIX message queue" default 16 help Mention maximum number of messages in message queue in POSIX compliant application. +config POSIX_MQ_PRIO_MAX + int "Maximum number of POSIX message priorities" + default 32 + help + Maximum number of message priorities supported by the implementation. + config MSG_SIZE_MAX - int "Maximum size of a message" + int "Maximum size of a POSIX message" default 16 help Mention maximum size of message in bytes. config MQUEUE_NAMELEN_MAX - int "Maximum size of a name length" + int "Maximum POSIX message queue name size" default 16 range 2 255 help - Mention length of message queue name in number of characters. + Mention size of message queue name in number of characters. config HEAP_MEM_POOL_ADD_SIZE_MQUEUE def_int 1024 diff --git a/lib/posix/options/Kconfig.mutex b/lib/posix/options/Kconfig.mutex deleted file mode 100644 index 6d5729e80aa024..00000000000000 --- a/lib/posix/options/Kconfig.mutex +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017 Intel Corporation -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -TYPE = PTHREAD_MUTEX -type = pthread_mutex_t -type-function = pthread_mutex_lock -rsource "Kconfig.template.pooled_ipc_type" diff --git a/lib/posix/options/Kconfig.net b/lib/posix/options/Kconfig.net index 5e2b363e167df3..f63aaaf141152a 100644 --- a/lib/posix/options/Kconfig.net +++ b/lib/posix/options/Kconfig.net @@ -2,10 +2,48 @@ # # SPDX-License-Identifier: Apache-2.0 -config POSIX_NETWORKING +menuconfig POSIX_NETWORKING bool "POSIX Networking API" - default y if POSIX_API depends on NETWORKING + select NET_HOSTNAME_ENABLE + select NET_HOSTNAME_DYNAMIC + select NET_INTERFACE_NAME + select NET_SOCKETPAIR + select NET_SOCKETS help Enable this option to support the POSIX networking API. This includes support for BSD Sockets. + + For additional details, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_NETWORKING + +config POSIX_HOST_NAME_MAX + int + default NET_HOSTNAME_MAX_LEN + help + The maximum length of a host name as defined by POSIX. + + For additional details, please see + https://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html + +config POSIX_IPV6 + bool "POSIX IPv6 support" + select NET_IPV6 + help + Enable this option to support the POSIX IPv6 API. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 + +config POSIX_RAW_SOCKETS + bool "POSIX RAW socket support" + select NET_SOCKETS_PACKET + help + Enable this option to support the raw sockets. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/xrat/V4_xsh_chap02.html#tag_22_02_10_18 + +endif # POSIX_NETWORKING diff --git a/lib/posix/options/Kconfig.proc1 b/lib/posix/options/Kconfig.proc1 new file mode 100644 index 00000000000000..9ab29048ca2bb0 --- /dev/null +++ b/lib/posix/options/Kconfig.proc1 @@ -0,0 +1,56 @@ +# Copyright (c) 2023 Meta +# Copyright (c) 2024 BayLibre SAS +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig POSIX_SINGLE_PROCESS + bool "POSIX single process support" + # imply COMMON_LIBC_MALLOC # for env.c + help + Select 'y' here to use confstr(), environ, errno, getenv(), setenv(), sysconf(), uname(), + or unsetenv(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_SINGLE_PROCESS + +choice POSIX_SYSCONF_IMPL_CHOICE + default POSIX_SYSCONF_IMPL_FULL if CPP + default POSIX_SYSCONF_IMPL_MACRO + prompt "Sysconf implementation method" + +config POSIX_SYSCONF_IMPL_MACRO + bool "Macro" + help + The sysconf() function is implemented compile-time constant via macros. This is the option + with the least overhead. The downside is that sysconf() is not an addressable function. + +config POSIX_SYSCONF_IMPL_FULL + bool "Full" + help + The sysconf() function is implemented as a large integer-integer array. The advantage if this + option is that all sysconf() options can be queried and that the sysconf() symbol is + addressable. + +endchoice + +config POSIX_UNAME_VERSION_LEN + int "uname version string length" + default 70 + help + Defines the maximum string length of uname version. + +config POSIX_UNAME_NODENAME_LEN + int "uname nodename string length" + default 6 if !NET_HOSTNAME_UNIQUE + default 22 if NET_HOSTNAME_UNIQUE + help + Defines the maximum string length of nodename version. + +module = POSIX_ENV +module-str = POSIX env logging +source "subsys/logging/Kconfig.template.log_config" + +endif # POSIX_SINGLE_PROCESS diff --git a/lib/posix/options/Kconfig.procN b/lib/posix/options/Kconfig.procN new file mode 100644 index 00000000000000..b3a467b88b9d3d --- /dev/null +++ b/lib/posix/options/Kconfig.procN @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig POSIX_MULTI_PROCESS + bool "POSIX multi-process support [EXPERIMENTAL]" + select EXPERIMENTAL + help + Support for multi-processing. + + Note: Currently Zephyr does not support multiple processes and therefore much of this option + group is not implemented and is considered undefined behaviour. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_MULTI_PROCESS + +# These options are intended to be used for compatibility with external POSIX +# implementations such as those in Newlib or Picolibc. + +config POSIX_MULTI_PROCESS_ALIAS_GETPID + bool + default y + help + Select 'y' here and Zephyr will provide an alias for getpid() as _getpid(). + +endif # POSIX_MULTI_PROCESS diff --git a/lib/posix/options/Kconfig.profile b/lib/posix/options/Kconfig.profile new file mode 100644 index 00000000000000..b57e07fbc28288 --- /dev/null +++ b/lib/posix/options/Kconfig.profile @@ -0,0 +1,186 @@ +# Copyright (c) 2024 Tenstorrent +# +# SPDX-License-Identifier: Apache-2.0 + +config POSIX_API + bool "POSIX APIs" + depends on !NATIVE_APPLICATION + select NATIVE_LIBC_INCOMPATIBLE + select POSIX_BASE_DEFINITIONS # clock_gettime(), pthread_create(), sem_get(), etc + select POSIX_AEP_REALTIME_MINIMAL # CLOCK_MONOTONIC, pthread_attr_setstack(), etc + select POSIX_NETWORKING if NETWORKING # inet_ntoa(), socket(), etc + imply EVENTFD # eventfd(), eventfd_read(), eventfd_write() + imply POSIX_FD_MGMT # open(), close(), read(), write() + imply POSIX_MESSAGE_PASSING # mq_open(), etc + imply POSIX_MULTI_PROCESS # sleep(), getpid(), etc + help + This option enables the required POSIX System Interfaces (base definitions), all of PSE51, + and some features found in PSE52. + + Note: in the future, this option may be deprecated in favour of subprofiling options. + +choice POSIX_AEP_CHOICE + prompt "POSIX Subprofile" + default POSIX_AEP_CHOICE_NONE + help + This choice is intended to help users select the correct POSIX profile for their + application. Choices are based on IEEE 1003.13-2003 (now inactive / reserved) and + extrapolated to the more recent Subprofiling Option Groups in IEEE 1003.3-2017. + + For more information, please refer to + https://standards.ieee.org/ieee/1003.13/3322/ + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_AEP_CHOICE_NONE + bool "No pre-defined POSIX subprofile" + help + No pre-defined POSIX profile is selected. + +config POSIX_AEP_CHOICE_BASE + bool "Base definitions (system interfaces)" + depends on !NATIVE_APPLICATION + select NATIVE_LIBC_INCOMPATIBLE + select POSIX_BASE_DEFINITIONS + help + Only enable the base definitions required for all POSIX systems. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_03_01 + +config POSIX_AEP_CHOICE_PSE51 + bool "Minimal Realtime System Profile (PSE51)" + depends on !NATIVE_APPLICATION + select NATIVE_LIBC_INCOMPATIBLE + select POSIX_BASE_DEFINITIONS + select POSIX_AEP_REALTIME_MINIMAL + help + PSE51 includes the POSIX Base Definitions (System Interfaces) as well as several Options and + Option Groups to facilitate device I/O, signals, mandatory configuration utilities, and + threading. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_AEP_CHOICE_PSE52 + bool "Realtime Controller System Profile (PSE52)" + depends on !NATIVE_APPLICATION + select NATIVE_LIBC_INCOMPATIBLE + select POSIX_BASE_DEFINITIONS + select POSIX_AEP_REALTIME_MINIMAL + select POSIX_AEP_REALTIME_CONTROLLER + help + PSE52 includes the POSIX Base Definitions (System Interfaces) as well as all features of + PSE51. Additionally, it includes interfaces for file descriptor management, filesystem + support, support for message queues, and tracing. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_AEP_CHOICE_PSE53 + bool "Dedicated Realtime System Profile (PSE53)" + depends on !NATIVE_APPLICATION + select NATIVE_LIBC_INCOMPATIBLE + select POSIX_BASE_DEFINITIONS + select POSIX_AEP_REALTIME_MINIMAL + select POSIX_AEP_REALTIME_CONTROLLER + select POSIX_AEP_REALTIME_DEDICATED + help + PSE53 includes the POSIX Base Definitions (System Interfaces) as well as all features of + PSE52. Additionally, it includes interfaces for POSIX multi-processing, networking, pipes, + and prioritized I/O. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +# TODO: PSE54: Multi-purpose Realtime System Profile + +endchoice # POSIX_AEP_CHOICE + +# Base Definitions (System Interfaces) +config POSIX_BASE_DEFINITIONS + bool + select POSIX_ASYNCHRONOUS_IO + select POSIX_BARRIERS + select POSIX_CLOCK_SELECTION + # select POSIX_MAPPED_FILES + # select POSIX_MEMORY_PROTECTION + select POSIX_READER_WRITER_LOCKS + select POSIX_REALTIME_SIGNALS + select POSIX_SEMAPHORES + select POSIX_SPIN_LOCKS + select POSIX_THREAD_SAFE_FUNCTIONS + select POSIX_THREADS + select POSIX_TIMEOUTS + select POSIX_TIMERS + help + This option is not user configurable. It may be configured indirectly by selecting + CONFIG_POSIX_AEP_CHOICE_BASE=y. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_03_01 + +config POSIX_AEP_REALTIME_MINIMAL + bool + # Option Groups + select POSIX_DEVICE_IO + select POSIX_SIGNALS + select POSIX_SINGLE_PROCESS + select XSI_THREADS_EXT + # Options + select POSIX_FSYNC + # select POSIX_MEMLOCK + # select POSIX_MEMLOCK_RANGE + select POSIX_MONOTONIC_CLOCK + # select POSIX_SHARED_MEMORY_OBJECTS + select POSIX_SYNCHRONIZED_IO + select POSIX_THREAD_ATTR_STACKADDR + select POSIX_THREAD_ATTR_STACKSIZE + select POSIX_THREAD_CPUTIME + select POSIX_THREAD_PRIO_INHERIT + select POSIX_THREAD_PRIO_PROTECT + select POSIX_THREAD_PRIORITY_SCHEDULING + # select POSIX_THREAD_SPORADIC_SERVER + help + This option is not user configurable. It may be configured indirectly by selecting + CONFIG_POSIX_AEP_CHOICE_PSE51=y. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_AEP_REALTIME_CONTROLLER + bool + # Option Groups + select POSIX_FD_MGMT + select POSIX_FILE_SYSTEM + # Options + select POSIX_MESSAGE_PASSING + # select POSIX_TRACE + # select POSIX_TRACE_EVENT_FILTER + # select POSIX_TRACE_LOG + help + This option is not user configurable. It may be configured indirectly by selecting + CONFIG_POSIX_AEP_CHOICE_PSE52=y. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_AEP_REALTIME_DEDICATED + bool + # Option Groups + select POSIX_MULTI_PROCESS + select POSIX_NETWORKING + # select POSIX_PIPE + # select POSIX_SIGNAL_JUMP + # Options + select POSIX_CPUTIME + # select POSIX_PRIORITIZED_IO + select POSIX_PRIORITY_SCHEDULING + select POSIX_RAW_SOCKETS + # select POSIX_SPAWN + # select POSIX_SPORADIC_SERVER + help + This option is not user configurable. It may be configured indirectly by selecting + CONFIG_POSIX_AEP_CHOICE_PSE53=y. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/Kconfig.pthread b/lib/posix/options/Kconfig.pthread index f0c65836b60007..ec38286ff49a3e 100644 --- a/lib/posix/options/Kconfig.pthread +++ b/lib/posix/options/Kconfig.pthread @@ -1,14 +1,49 @@ # Copyright (c) 2017 Intel Corporation # Copyright (c) 2023 Meta +# Copyright (c) 2024 Tenstorrent AI ULC # # SPDX-License-Identifier: Apache-2.0 -TYPE = PTHREAD -type = pthread_t -type-function = pthread_create -rsource "Kconfig.template.pooled_ipc_type" +menuconfig POSIX_THREADS + bool "POSIX thread support" + help + Select 'y' here to enable POSIX threads, mutexes, condition variables, and thread-specific + storage. + + For more information please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_THREADS + +config POSIX_THREAD_THREADS_MAX + int "Maximum number of POSIX threads" + default 5 + help + Maximum simultaneously active threads in a POSIX application. -if PTHREAD + For more information, see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html + +config MAX_PTHREAD_MUTEX_COUNT + int "Maximum number of POSIX mutexes" + default 5 + help + Maximum simultaneously active mutexes in a POSIX application. + +config MAX_PTHREAD_COND_COUNT + int "Maximum number of POSIX condition variables" + default 5 + help + Maximum simultaneously active condition variables in a POSIX application. + +config POSIX_THREAD_KEYS_MAX + int "Maximum number of POSIX thread-specific-storage keys" + default 5 + help + Maximum simultaneously active thread-specific-storage keys in a POSIX application. + + For more information, see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html config PTHREAD_RECYCLER_DELAY_MS int "Delay for reclaiming dynamic pthread stacks (ms)" @@ -27,6 +62,50 @@ config PTHREAD_RECYCLER_DELAY_MS Note: this option should be considered temporary and will likely be removed once a more synchronous solution is available. +config POSIX_THREAD_ATTR_STACKADDR + bool "Support getting and setting POSIX thread stack addresses" + help + Enable this option to use pthread_attr_getstackaddr() and + pthread_attr_setstackaddr(). + + This option was removed in IEEE 1003.1-2017 in favour of + pthread_attr_getstack() and pthread_attr_setstack(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/009696799/functions/pthread_attr_getstackaddr.html + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap03.html + https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_08 + +config POSIX_THREAD_ATTR_STACKSIZE + bool "Support getting and setting POSIX thread stack sizes" + help + Enable this option to use pthread_attr_getstacksize() or + pthread_attr_setstacksize(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/009696699/functions/pthread_attr_getstacksize.html + +config POSIX_THREADS_EXT + bool "Extended POSIX thread support" + help + Enable this option to use pthread_attr_getguardsize(), pthread_attr_setguardsize(), + pthread_mutexattr_gettype(), or pthread_mutexattr_settype(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config POSIX_THREAD_PRIORITY_SCHEDULING + bool "Run POSIX threads with different priorities and schedulers" + help + Enabling this option allows the application to configure different priorities and + scheduling algorithms for different threads via functions such as pthread_setschedparam() + and pthread_setschedprio(). This is required for Realtime Threads and Advanced Realtime + Threads. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_06 + https://man7.org/linux/man-pages/man7/posixoptions.7.html + config POSIX_PTHREAD_ATTR_STACKSIZE_BITS int "Significant bits for pthread_attr_t stacksize" range 8 31 @@ -59,4 +138,47 @@ config POSIX_PTHREAD_ATTR_GUARDSIZE_DEFAULT facilitate a more dynamic approach to guard areas (via software or hardware) but for now it simply increases the size of thread stacks. -endif +config POSIX_THREAD_PRIO_INHERIT + bool "POSIX mutex priority inheritance" + help + Select 'y' here to enable POSIX mutex priority inheritance. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_getprotocol.html + +config POSIX_THREAD_PRIO_PROTECT + bool "POSIX mutex priority protection" + help + Select 'y' here to enable POSIX mutex priority protection. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_getprotocol.html + +config POSIX_THREAD_SAFE_FUNCTIONS + bool "POSIX thread-safe functions" + help + Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(), + flockfile(), ftrylockfile(), funlockfile(), getc_unlocked(), getchar_unlocked(), + getgrgid_r(), getgrnam_r(), getpwnam_r(), getpwuid_r(), gmtime_r(), localtime_r(), + putc_unlocked(), putchar_unlocked(), rand_r(), readdir_r(), strerror_r(), and strtok_r(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_09_07 + +module = PTHREAD +module-str = POSIX thread +source "subsys/logging/Kconfig.template.log_config" + +module = PTHREAD_MUTEX +module-str = POSIX mutex +source "subsys/logging/Kconfig.template.log_config" + +module = PTHREAD_COND +module-str = POSIX condition variable +source "subsys/logging/Kconfig.template.log_config" + +module = PTHREAD_KEY +module-str = POSIX thread-specific data +source "subsys/logging/Kconfig.template.log_config" + +endif # POSIX_THREADS diff --git a/lib/posix/options/Kconfig.rwlock b/lib/posix/options/Kconfig.rwlock index fea61551ec356f..8626b3bb1a40b4 100644 --- a/lib/posix/options/Kconfig.rwlock +++ b/lib/posix/options/Kconfig.rwlock @@ -2,7 +2,26 @@ # # SPDX-License-Identifier: Apache-2.0 -TYPE = PTHREAD_RWLOCK -type = pthread_rwlock_t -type-function = pthread_rwlock_timedrdlock -rsource "Kconfig.template.pooled_ipc_type" +menuconfig POSIX_READER_WRITER_LOCKS + bool "POSIX reader-writer locks" + help + Select 'y' here to enable POSIX reader-writer locks. + + For more information please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_READER_WRITER_LOCKS + +config MAX_PTHREAD_RWLOCK_COUNT + int "Maximum number of POSIX reader-writer locks" + default 5 + help + Maximum simultaneously active reader-writer locks in a POSIX application. + + Note: this is a non-standard option. + +module = PTHREAD_RWLOCK +module-str = POSIX Reader-Writer Locks +source "subsys/logging/Kconfig.template.log_config" + +endif # POSIX_READER_WRITER_LOCKS diff --git a/lib/posix/options/Kconfig.sched b/lib/posix/options/Kconfig.sched index b5fb3a5dcb1e95..7e0dc70fca119e 100644 --- a/lib/posix/options/Kconfig.sched +++ b/lib/posix/options/Kconfig.sched @@ -2,10 +2,19 @@ # # SPDX-License-Identifier: Apache-2.0 +menu "POSIX scheduler options" + config POSIX_PRIORITY_SCHEDULING - bool "Priority scheduling" - default y if PTHREAD - default y if POSIX_API - depends on PTHREAD + bool "POSIX priority-based process scheduling [EXPERIMENTAL]" + select EXPERIMENTAL help This enables POSIX scheduling APIs (_POSIX_PRIORITY_SCHEDULING). + + Since Zephyr does not yet support processes, most of this behaviour is undefined, except for + use of sched_get_priority_min() and sched_get_priority_max(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 + https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_get_priority_max.html + +endmenu diff --git a/lib/posix/options/Kconfig.semaphore b/lib/posix/options/Kconfig.semaphore index 53fb030736b01b..65bc2a686930b8 100644 --- a/lib/posix/options/Kconfig.semaphore +++ b/lib/posix/options/Kconfig.semaphore @@ -2,21 +2,35 @@ # # SPDX-License-Identifier: Apache-2.0 -menu "sem_t support" +menuconfig POSIX_SEMAPHORES + bool "POSIX semaphore support" + help + Enable this option for POSIX semaphore support. + +if POSIX_SEMAPHORES -config SEM_VALUE_MAX - int "Maximum semaphore limit" +config POSIX_SEM_VALUE_MAX + int "Maximum semaphore value" default 32767 range 1 32767 help Maximum semaphore count in POSIX compliant Application. -config SEM_NAMELEN_MAX - int "Maximum name length" +config POSIX_SEM_NSEMS_MAX + int "Maximum number of semaphores" + default 256 + help + Maximum number of semaphores in a POSIX application. + + Note: currently, in Zephyr, this only limits the number of named semaphores (i.e. those + created via sem_open()). + +config POSIX_SEM_NAMELEN_MAX + int "Maximum semaphore name length" default 16 range 2 255 help Maximum length of name for a named semaphore. The max value of 255 corresponds to {NAME_MAX}. -endmenu # "sem_t support" +endif # POSIX_SEMAPHORES diff --git a/lib/posix/options/Kconfig.signal b/lib/posix/options/Kconfig.signal index 99c225564c7114..4507302e3f32d0 100644 --- a/lib/posix/options/Kconfig.signal +++ b/lib/posix/options/Kconfig.signal @@ -2,24 +2,32 @@ # # SPDX-License-Identifier: Apache-2.0 -menu "Signal support" +menu "POSIX signals" + +config POSIX_REALTIME_SIGNALS + bool "POSIX realtime signals [EXPERIMENTAL]" + select EXPERIMENTAL + help + Enable support for POSIX realtime signals. + +if POSIX_REALTIME_SIGNALS -# needed outside of if clause above to define constants & types in signal.h config POSIX_RTSIG_MAX int "Maximum number of realtime signals" - default 31 if POSIX_SIGNAL - default 0 + default 8 help Define the maximum number of realtime signals (RTSIG_MAX). The range of realtime signals is [SIGRTMIN .. (SIGRTMIN+RTSIG_MAX)] -config POSIX_SIGNAL - bool "Support for POSIX signal APIs" - default y if POSIX_API +endif # POSIX_REALTIME_SIGNALS + +config POSIX_SIGNALS + bool "POSIX signals [EXPERIMENTAL]" + select EXPERIMENTAL help - Enable support for POSIX signal APIs. + Enable support for POSIX signals. -if POSIX_SIGNAL +if POSIX_SIGNALS config POSIX_SIGNAL_STRING_DESC bool "Use full description for the strsignal API" @@ -28,13 +36,6 @@ config POSIX_SIGNAL_STRING_DESC Use full description for the strsignal API. Will use 256 bytes of ROM. -config POSIX_LIMITS_RTSIG_MAX - int "_POSIX_RTSIG_MAX value in limits.h" - default 8 - help - Define the _POSIX_RTSIG_MAX value in limits.h. - IEEE 1003.1 defines this to be 8. - endif endmenu # "Signal support" diff --git a/lib/posix/options/Kconfig.spinlock b/lib/posix/options/Kconfig.spinlock index 8374aadfd6dd68..312a432ce38e90 100644 --- a/lib/posix/options/Kconfig.spinlock +++ b/lib/posix/options/Kconfig.spinlock @@ -2,7 +2,26 @@ # # SPDX-License-Identifier: Apache-2.0 -TYPE = PTHREAD_SPINLOCK -type = pthread_spinlock_t -type-function = pthread_spin_lock -rsource "Kconfig.template.pooled_ipc_type" +menuconfig POSIX_SPIN_LOCKS + bool "POSIX spin locks" + help + Select 'y' here to enable POSIX spin locks. + + For more information please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_SPIN_LOCKS + +config MAX_PTHREAD_SPINLOCK_COUNT + int "Maximum number of POSIX spin locks" + default 5 + help + Maximum simultaneously active spin locks in a POSIX application. + + Note: this is a non-standard option. + +module = PTHREAD_SPINLOCK +module-str = POSIX Spin Locks +source "subsys/logging/Kconfig.template.log_config" + +endif # POSIX_SPIN_LOCKS diff --git a/lib/posix/options/Kconfig.stropts b/lib/posix/options/Kconfig.stropts deleted file mode 100644 index 347f0f33c150af..00000000000000 --- a/lib/posix/options/Kconfig.stropts +++ /dev/null @@ -1,9 +0,0 @@ -# copyright (c) 2024 Abhinav Srivastava -# -# SPDX-License-Identifier: Apache-2.0 - -config POSIX_PUTMSG - bool "Support for putmsg function" - default y if POSIX_API - help - This option provides support for the putmsg function used in message passing. diff --git a/lib/posix/options/Kconfig.sync_io b/lib/posix/options/Kconfig.sync_io new file mode 100644 index 00000000000000..4575ff06020ae0 --- /dev/null +++ b/lib/posix/options/Kconfig.sync_io @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menu "POSIX synchronized I/O" + +config POSIX_FSYNC + bool "Support for fsync()" + help + Select 'y' here and Zephyr will provide an implementation of fsync(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html + + +config POSIX_SYNCHRONIZED_IO + bool "POSIX synchronized I/O" + select POSIX_FSYNC + help + Select 'y' here and Zephyr will provide an implementation of fdatasync(), fsync(), + and msync(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/functions/msync.html + https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html + +if POSIX_FSYNC + +# These options are intended to be used for compatibility with external POSIX +# implementations such as those in Newlib or Picolibc. + +config POSIX_FILE_SYSTEM_ALIAS_FSYNC + bool + help + Select 'y' here and Zephyr will provide an alias for fsync() as _fsync(). + +endif # POSIX_FSYNC + +endmenu diff --git a/lib/posix/options/Kconfig.sysconf b/lib/posix/options/Kconfig.sysconf deleted file mode 100644 index 7e904d5b6722fe..00000000000000 --- a/lib/posix/options/Kconfig.sysconf +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2024 BayLibre SAS -# -# SPDX-License-Identifier: Apache-2.0 - -menu "Sysconf support" - -config POSIX_SYSCONF - bool "Support for sysconf" - default y if POSIX_API - help - The sysconf() function provides a method for the application to determine - the current value of a configurable system limit or option (variable). - -config POSIX_PAGE_SIZE_BITS - int "Number of bits to use for PAGE_SIZE" - range 6 16 - default 12 if POSIX_API - default 6 - help - Define PAGE_SIZE as BIT(n), where n is the value configured here. - PAGE_SIZE is supported in the range [64, 65536] - If CONFIG_POSIX_API=y, PAGE_SIZE defaults to 4096, otherwise, it is 64 bytes. - -if POSIX_SYSCONF - -choice POSIX_SYSCONF_IMPL_CHOICE - default POSIX_SYSCONF_IMPL_FULL if CPP - default POSIX_SYSCONF_IMPL_MACRO - prompt "Sysconf implementation method" - -config POSIX_SYSCONF_IMPL_MACRO - bool "Macro" - help - The sysconf() function is implemented compile-time constant via macros. This is the option - with the least overhead. The downside is that sysconf() is not an addressable function. - -config POSIX_SYSCONF_IMPL_FULL - bool "Full" - help - The sysconf() function is implemented as a large integer-integer array. The advantage if this - option is that all sysconf() options can be queried and that the sysconf() symbol is - addressable. - -endchoice - -endif # POSIX_SYSCONF - -endmenu # "Sysconf support" diff --git a/lib/posix/options/Kconfig.syslog b/lib/posix/options/Kconfig.syslog deleted file mode 100644 index 1fedd93cddf7c9..00000000000000 --- a/lib/posix/options/Kconfig.syslog +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2024, Meta -# -# SPDX-License-Identifier: Apache-2.0 - -config POSIX_SYSLOG - bool "Support for syslog()" - default y if POSIX_API - help - This option provides support for closelog(), openlog(), syslog(), - setlogmask(), and vsyslog(). diff --git a/lib/posix/options/Kconfig.template.pooled_ipc_type b/lib/posix/options/Kconfig.template.pooled_ipc_type deleted file mode 100644 index 08d804382e801e..00000000000000 --- a/lib/posix/options/Kconfig.template.pooled_ipc_type +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -rsource "Kconfig.template.with_url" - -# Not user configurable (i.e. private for now) -menuconfig $(TYPE) - bool "$(type) support" - depends on PTHREAD_IPC - default y - help - Support for $(TYPE) - For more info, see - $(posix-url-base)/$(type-function).html - -if $(TYPE) - -# eventually, this size should be defaulted to 0 -config MAX_$(TYPE)_COUNT - int "Maximum number of $(type)" - default 5 - depends on $(TYPE) - help - Maximum simultaneously active $(type) in a POSIX application. - -rsource "Kconfig.template.with_logging" - -endif # $(TYPE) diff --git a/lib/posix/options/Kconfig.template.pooled_type b/lib/posix/options/Kconfig.template.pooled_type deleted file mode 100644 index 5a75c2ee890fe2..00000000000000 --- a/lib/posix/options/Kconfig.template.pooled_type +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -rsource "Kconfig.template.with_url" - -# This is mainly for TIMER currently. -menuconfig $(TYPE) - bool "$(type) support" - help - For more info, see - $(posix-url-base)/$(type-function).html - -if $(TYPE) - -# eventually, this size should be defaulted to 0 as a safe value -config MAX_$(TYPE)_COUNT - int "Maximum number of $(type)" - default 5 - help - Maximum simultaneously active $(type) in a POSIX application. - -rsource "Kconfig.template.with_logging" - -endif # $(TYPE) diff --git a/lib/posix/options/Kconfig.template.with_logging b/lib/posix/options/Kconfig.template.with_logging deleted file mode 100644 index f1fc5141e7cd18..00000000000000 --- a/lib/posix/options/Kconfig.template.with_logging +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -module = $(TYPE) -module-str = $(TYPE) logging -source "subsys/logging/Kconfig.template.log_config" diff --git a/lib/posix/options/Kconfig.template.with_url b/lib/posix/options/Kconfig.template.with_url deleted file mode 100644 index 33e34756ee71e9..00000000000000 --- a/lib/posix/options/Kconfig.template.with_url +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -posix-url-base = https://pubs.opengroup.org/onlinepubs/9699919799 diff --git a/lib/posix/options/Kconfig.timer b/lib/posix/options/Kconfig.timer index 10905e9c21d561..42eed40bce68dc 100644 --- a/lib/posix/options/Kconfig.timer +++ b/lib/posix/options/Kconfig.timer @@ -1,13 +1,85 @@ # Copyright (c) 2018 Intel Corporation +# Copyright (c) 2024 Tenstorrent AI ULC # # SPDX-License-Identifier: Apache-2.0 -TYPE = TIMER -type = timer_t -type-function = timer_create -rsource "Kconfig.template.pooled_type" +menuconfig POSIX_TIMERS + bool "POSIX timers, clocks, and sleep functions" + help + Select 'y' here and Zephyr will provide implementations of clock_getres(), clock_gettime(), + clock_settime(), nanosleep(), timer_create(), timer_delete(), timer_getoverrun(), + timer_settime(), and timer_gettime(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +if POSIX_TIMERS + +config POSIX_THREAD_CPUTIME + bool "POSIX per-thread CPU-time clocks" + help + This enables CLOCK_THREAD_CPUTIME_ID. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_118 + https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_05_04 + +config POSIX_MONOTONIC_CLOCK + bool "POSIX Monotonic clock support" + help + This enables CLOCK_MONOTONIC. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html + https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_05_03 + +config POSIX_CPUTIME + bool "POSIX per-process CPU-time clocks" + help + This enables CLOCK_PROCESS_CPUTIME_ID. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_118 + https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_05_04 + +config POSIX_CLOCK_SELECTION + bool "POSIX Clock selection" + help + This enables POSIX clock selection. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 -if TIMER +config POSIX_DELAYTIMER_MAX + int "Maximum count returned my timer_getoverrun() in POSIX application" + default 32 + help + This controls the maximum number of times a timer can overrun before + timer_getoverrun() in POSIX compliant application. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html + +config POSIX_TIMER_MAX + int "Maximum number of POSIX timers per process" + default 32 + help + Maximum simultaneously active timer_t in a POSIX application. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html + +config POSIX_TIMEOUTS + bool "Support timeouts for some blocking POSIX services" + help + Enable mandatory timeouts for some blocking operations. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap02.html config TIMER_CREATE_WAIT int "Time to wait for timer availability (in msec) in POSIX application" @@ -17,11 +89,8 @@ config TIMER_CREATE_WAIT This controls how long to wait for resources to come available to create a new timer in POSIX compliant application -config TIMER_DELAYTIMER_MAX - int "Maximum count returned my timer_getoverrun() in POSIX application" - default 20 - help - This controls the maximum number of times a timer can overrun before - timer_getoverrun() in POSIX compliant application. +module = TIMER +module-str = POSIX Timers +source "subsys/logging/Kconfig.template.log_config" -endif # TIMER +endif # POSIX_TIMERS diff --git a/lib/posix/options/Kconfig.uname b/lib/posix/options/Kconfig.uname deleted file mode 100644 index 8b4482252492d8..00000000000000 --- a/lib/posix/options/Kconfig.uname +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2023 Meta -# -# SPDX-License-Identifier: Apache-2.0 - -menuconfig POSIX_UNAME - bool "Support for uname" - default y if POSIX_API - help - The uname() function shall store information identifying the current - system in the structure pointed to by name. - -if POSIX_UNAME -config POSIX_UNAME_VERSION_LEN - int "uname version string length" - default 70 - help - Defines the maximum string length of uname version. - -config POSIX_UNAME_NODENAME_LEN - int "uname nodename string length" - default 6 if !NET_HOSTNAME_UNIQUE - default 22 if NET_HOSTNAME_UNIQUE - help - Defines the maximum string length of nodename version. - -endif # POSIX_UNAME diff --git a/lib/posix/options/Kconfig.xsi b/lib/posix/options/Kconfig.xsi new file mode 100644 index 00000000000000..f8be61e245d5d2 --- /dev/null +++ b/lib/posix/options/Kconfig.xsi @@ -0,0 +1,45 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +menu "X/Open system interfaces" + +config XSI_SINGLE_PROCESS + bool "X/Open single process" + depends on POSIX_SINGLE_PROCESS + depends on POSIX_TIMERS + help + Select 'y' here and Zephyr will provide implementations of + gethostid(), gettimeofday(), and putenv(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config XOPEN_STREAMS + bool "X/Open streams" + help + This option provides support for the X/Open Streams interface, including functions such as + fattach(), fdetach(), getmsg(), getpmsg(), putmsg(), and putpmsg(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_05_09 + +config XSI_SYSTEM_LOGGING + bool "X/Open system logging" + help + This option provides support for closelog(), openlog(), syslog(), + setlogmask(), and vsyslog(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +config XSI_THREADS_EXT + bool "X/Open threads extensions" + help + This option provides support for pthread_attr_getstack(), pthread_attr_setstack(), + pthread_getconcurrency(), and pthread_setconcurrency(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +endmenu diff --git a/lib/posix/options/clock.c b/lib/posix/options/clock.c index 68692b5ecd6f9e..5fa09daaae6d7a 100644 --- a/lib/posix/options/clock.c +++ b/lib/posix/options/clock.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2018 Friedt Professional Engineering Services, Inc * * SPDX-License-Identifier: Apache-2.0 */ @@ -156,14 +157,43 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) return 0; } +/* + * Note: usleep() was removed in Issue 7. + * + * It is kept here for compatibility purposes. + * + * For more information, please see + * https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap01.html + * https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap03.html + */ +int usleep(useconds_t useconds) +{ + int32_t rem; + + if (useconds >= USEC_PER_SEC) { + errno = EINVAL; + return -1; + } + + rem = k_usleep(useconds); + __ASSERT_NO_MSG(rem >= 0); + if (rem > 0) { + /* sleep was interrupted by a call to k_wakeup() */ + errno = EINTR; + return -1; + } + + return 0; +} + /** * @brief Suspend execution for a nanosecond interval, or * until some absolute time relative to the specified clock. * * See IEEE 1003.1 */ -int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, - struct timespec *rmtp) +static int __z_clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, + struct timespec *rmtp) { uint64_t ns; uint64_t us; @@ -225,6 +255,17 @@ int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, return 0; } +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + return __z_clock_nanosleep(CLOCK_MONOTONIC, 0, rqtp, rmtp); +} + +int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, + struct timespec *rmtp) +{ + return __z_clock_nanosleep(clock_id, flags, rqtp, rmtp); +} + /** * @brief Get current real time. * diff --git a/lib/posix/options/device_io.c b/lib/posix/options/device_io.c new file mode 100644 index 00000000000000..585dc7000c2be7 --- /dev/null +++ b/lib/posix/options/device_io.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include + +/* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ +int zvfs_close(int fd); +int zvfs_open(const char *name, int flags); +ssize_t zvfs_read(int fd, void *buf, size_t sz); +ssize_t zvfs_write(int fd, const void *buf, size_t sz); + +int close(int fd) +{ + return zvfs_close(fd); +} +#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_CLOSE +FUNC_ALIAS(close, _close, int); +#endif + +int open(const char *name, int flags, ...) +{ + /* FIXME: necessarily need to check for O_CREAT and unpack ... if set */ + return zvfs_open(name, flags); +} +#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN +FUNC_ALIAS(open, _open, int); +#endif + +int poll(struct pollfd *fds, int nfds, int timeout) +{ + /* TODO: create zvfs_poll() and dispatch to subsystems based on file type */ + return zsock_poll(fds, nfds, timeout); +} + +ssize_t read(int fd, void *buf, size_t sz) +{ + return zvfs_read(fd, buf, sz); +} +#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_READ +FUNC_ALIAS(read, _read, ssize_t); +#endif + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ + /* TODO: create zvfs_select() and dispatch to subsystems based on file type */ + return zsock_select(nfds, readfds, writefds, exceptfds, (struct zsock_timeval *)timeout); +} + +ssize_t write(int fd, const void *buf, size_t sz) +{ + return zvfs_write(fd, buf, sz); +} +#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE +FUNC_ALIAS(write, _write, ssize_t); +#endif diff --git a/lib/posix/options/eventfd.c b/lib/posix/options/eventfd.c index 81b8f6d6dd8106..b272bfa636fc26 100644 --- a/lib/posix/options/eventfd.c +++ b/lib/posix/options/eventfd.c @@ -1,484 +1,23 @@ /* - * Copyright (c) 2020 Tobias Svehagen - * Copyright (c) 2023, Meta + * Copyright (c) 2024, Tenstorrent AI ULC * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include #include -#include -#include -#include - -#define EFD_IN_USE_INTERNAL 0x1 -#define EFD_FLAGS_SET_INTERNAL (EFD_SEMAPHORE | EFD_NONBLOCK) - -struct eventfd { - struct k_poll_signal read_sig; - struct k_poll_signal write_sig; - struct k_spinlock lock; - eventfd_t cnt; - int flags; -}; - -static ssize_t eventfd_rw_op(void *obj, void *buf, size_t sz, - int (*op)(struct eventfd *efd, eventfd_t *value)); - -SYS_BITARRAY_DEFINE_STATIC(efds_bitarray, CONFIG_EVENTFD_MAX); -static struct eventfd efds[CONFIG_EVENTFD_MAX]; -static const struct fd_op_vtable eventfd_fd_vtable; - -static inline bool eventfd_is_in_use(struct eventfd *efd) -{ - return (efd->flags & EFD_IN_USE_INTERNAL) != 0; -} - -static inline bool eventfd_is_semaphore(struct eventfd *efd) -{ - return (efd->flags & EFD_SEMAPHORE) != 0; -} - -static inline bool eventfd_is_blocking(struct eventfd *efd) -{ - return (efd->flags & EFD_NONBLOCK) == 0; -} - -static int eventfd_poll_prepare(struct eventfd *efd, - struct zsock_pollfd *pfd, - struct k_poll_event **pev, - struct k_poll_event *pev_end) -{ - if (pfd->events & ZSOCK_POLLIN) { - if (*pev == pev_end) { - errno = ENOMEM; - return -1; - } - - (*pev)->obj = &efd->read_sig; - (*pev)->type = K_POLL_TYPE_SIGNAL; - (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; - (*pev)->state = K_POLL_STATE_NOT_READY; - (*pev)++; - } - - if (pfd->events & ZSOCK_POLLOUT) { - if (*pev == pev_end) { - errno = ENOMEM; - return -1; - } - - (*pev)->obj = &efd->write_sig; - (*pev)->type = K_POLL_TYPE_SIGNAL; - (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; - (*pev)->state = K_POLL_STATE_NOT_READY; - (*pev)++; - } - - return 0; -} - -static int eventfd_poll_update(struct eventfd *efd, - struct zsock_pollfd *pfd, - struct k_poll_event **pev) -{ - if (pfd->events & ZSOCK_POLLIN) { - pfd->revents |= ZSOCK_POLLIN * (efd->cnt > 0); - (*pev)++; - } - - if (pfd->events & ZSOCK_POLLOUT) { - pfd->revents |= ZSOCK_POLLOUT * (efd->cnt < UINT64_MAX - 1); - (*pev)++; - } - - return 0; -} - -static int eventfd_read_locked(struct eventfd *efd, eventfd_t *value) -{ - if (!eventfd_is_in_use(efd)) { - /* file descriptor has been closed */ - return -EBADF; - } - - if (efd->cnt == 0) { - /* would block / try again */ - return -EAGAIN; - } - - /* successful read */ - if (eventfd_is_semaphore(efd)) { - *value = 1; - --efd->cnt; - } else { - *value = efd->cnt; - efd->cnt = 0; - } - - if (efd->cnt == 0) { - k_poll_signal_reset(&efd->read_sig); - } - - k_poll_signal_raise(&efd->write_sig, 0); - - return 0; -} - -static int eventfd_write_locked(struct eventfd *efd, eventfd_t *value) -{ - eventfd_t result; - - if (!eventfd_is_in_use(efd)) { - /* file descriptor has been closed */ - return -EBADF; - } - - if (*value == UINT64_MAX) { - /* not a permitted value */ - return -EINVAL; - } - - if (u64_add_overflow(efd->cnt, *value, &result) || result == UINT64_MAX) { - /* would block / try again */ - return -EAGAIN; - } - - /* successful write */ - efd->cnt = result; - - if (efd->cnt == (UINT64_MAX - 1)) { - k_poll_signal_reset(&efd->write_sig); - } - - k_poll_signal_raise(&efd->read_sig, 0); - - return 0; -} - -static ssize_t eventfd_read_op(void *obj, void *buf, size_t sz) -{ - return eventfd_rw_op(obj, buf, sz, eventfd_read_locked); -} - -static ssize_t eventfd_write_op(void *obj, const void *buf, size_t sz) -{ - return eventfd_rw_op(obj, (eventfd_t *)buf, sz, eventfd_write_locked); -} - -static int eventfd_close_op(void *obj) -{ - int ret; - int err; - k_spinlock_key_t key; - struct k_mutex *lock = NULL; - struct k_condvar *cond = NULL; - struct eventfd *efd = (struct eventfd *)obj; - - if (k_is_in_isr()) { - /* not covered by the man page, but necessary in Zephyr */ - errno = EWOULDBLOCK; - return -1; - } - - err = (int)z_get_obj_lock_and_cond(obj, &eventfd_fd_vtable, &lock, &cond); - __ASSERT((bool)err, "z_get_obj_lock_and_cond() failed"); - __ASSERT_NO_MSG(lock != NULL); - __ASSERT_NO_MSG(cond != NULL); - - err = k_mutex_lock(lock, K_FOREVER); - __ASSERT(err == 0, "k_mutex_lock() failed: %d", err); - - key = k_spin_lock(&efd->lock); - - if (!eventfd_is_in_use(efd)) { - errno = EBADF; - ret = -1; - goto unlock; - } - - err = sys_bitarray_free(&efds_bitarray, 1, (struct eventfd *)obj - efds); - __ASSERT(err == 0, "sys_bitarray_free() failed: %d", err); - - efd->flags = 0; - efd->cnt = 0; - - ret = 0; - -unlock: - k_spin_unlock(&efd->lock, key); - /* when closing an eventfd, broadcast to all waiters */ - err = k_condvar_broadcast(cond); - __ASSERT(err == 0, "k_condvar_broadcast() failed: %d", err); - err = k_mutex_unlock(lock); - __ASSERT(err == 0, "k_mutex_unlock() failed: %d", err); - - return ret; -} - -static int eventfd_ioctl_op(void *obj, unsigned int request, va_list args) -{ - int ret; - k_spinlock_key_t key; - struct eventfd *efd = (struct eventfd *)obj; - - /* note: zsock_poll_internal() has already taken the mutex */ - key = k_spin_lock(&efd->lock); - - if (!eventfd_is_in_use(efd)) { - errno = EBADF; - ret = -1; - goto unlock; - } - - switch (request) { - case F_GETFL: - ret = efd->flags & EFD_FLAGS_SET_INTERNAL; - break; - - case F_SETFL: { - int flags; - - flags = va_arg(args, int); - - if (flags & ~EFD_FLAGS_SET_INTERNAL) { - errno = EINVAL; - ret = -1; - } else { - int prev_flags = efd->flags & ~EFD_FLAGS_SET_INTERNAL; - - efd->flags = flags | prev_flags; - ret = 0; - } - } break; - - case ZFD_IOCTL_POLL_PREPARE: { - struct zsock_pollfd *pfd; - struct k_poll_event **pev; - struct k_poll_event *pev_end; - - pfd = va_arg(args, struct zsock_pollfd *); - pev = va_arg(args, struct k_poll_event **); - pev_end = va_arg(args, struct k_poll_event *); - - ret = eventfd_poll_prepare(obj, pfd, pev, pev_end); - } break; - - case ZFD_IOCTL_POLL_UPDATE: { - struct zsock_pollfd *pfd; - struct k_poll_event **pev; - - pfd = va_arg(args, struct zsock_pollfd *); - pev = va_arg(args, struct k_poll_event **); - - ret = eventfd_poll_update(obj, pfd, pev); - } break; - - default: - errno = EOPNOTSUPP; - ret = -1; - break; - } - -unlock: - k_spin_unlock(&efd->lock, key); - - return ret; -} - -static const struct fd_op_vtable eventfd_fd_vtable = { - .read = eventfd_read_op, - .write = eventfd_write_op, - .close = eventfd_close_op, - .ioctl = eventfd_ioctl_op, -}; - -/* common to both eventfd_read_op() and eventfd_write_op() */ -static ssize_t eventfd_rw_op(void *obj, void *buf, size_t sz, - int (*op)(struct eventfd *efd, eventfd_t *value)) -{ - int err; - ssize_t ret; - k_spinlock_key_t key; - struct eventfd *efd = obj; - struct k_mutex *lock = NULL; - struct k_condvar *cond = NULL; - - if (sz < sizeof(eventfd_t)) { - errno = EINVAL; - return -1; - } - - if (buf == NULL) { - errno = EFAULT; - return -1; - } - - key = k_spin_lock(&efd->lock); - - if (!eventfd_is_blocking(efd)) { - /* - * Handle the non-blocking case entirely within this scope - */ - ret = op(efd, buf); - if (ret < 0) { - errno = -ret; - ret = -1; - } else { - ret = sizeof(eventfd_t); - } - - goto unlock_spin; - } - - /* - * Handle the blocking case below - */ - __ASSERT_NO_MSG(eventfd_is_blocking(efd)); - - if (k_is_in_isr()) { - /* not covered by the man page, but necessary in Zephyr */ - errno = EWOULDBLOCK; - ret = -1; - goto unlock_spin; - } - - err = (int)z_get_obj_lock_and_cond(obj, &eventfd_fd_vtable, &lock, &cond); - __ASSERT((bool)err, "z_get_obj_lock_and_cond() failed"); - __ASSERT_NO_MSG(lock != NULL); - __ASSERT_NO_MSG(cond != NULL); - - /* do not hold a spinlock when taking a mutex */ - k_spin_unlock(&efd->lock, key); - err = k_mutex_lock(lock, K_FOREVER); - __ASSERT(err == 0, "k_mutex_lock() failed: %d", err); - - while (true) { - /* retake the spinlock */ - key = k_spin_lock(&efd->lock); - - ret = op(efd, buf); - switch (ret) { - case -EAGAIN: - /* not an error in blocking mode. break and try again */ - break; - case 0: - /* success! */ - ret = sizeof(eventfd_t); - goto unlock_mutex; - default: - /* some other error */ - __ASSERT_NO_MSG(ret < 0); - errno = -ret; - ret = -1; - goto unlock_mutex; - } - - /* do not hold a spinlock when taking a mutex */ - k_spin_unlock(&efd->lock, key); - - /* wait for a write or close */ - err = k_condvar_wait(cond, lock, K_FOREVER); - __ASSERT(err == 0, "k_condvar_wait() failed: %d", err); - } - -unlock_mutex: - k_spin_unlock(&efd->lock, key); - /* only wake a single waiter */ - err = k_condvar_signal(cond); - __ASSERT(err == 0, "k_condvar_signal() failed: %d", err); - err = k_mutex_unlock(lock); - __ASSERT(err == 0, "k_mutex_unlock() failed: %d", err); - goto out; - -unlock_spin: - k_spin_unlock(&efd->lock, key); - -out: - return ret; -} - -/* - * Public-facing API - */ +#include int eventfd(unsigned int initval, int flags) { - int fd = 1; - size_t offset; - struct eventfd *efd = NULL; - - if (flags & ~EFD_FLAGS_SET_INTERNAL) { - errno = EINVAL; - return -1; - } - - if (sys_bitarray_alloc(&efds_bitarray, 1, &offset) < 0) { - errno = ENOMEM; - return -1; - } - - efd = &efds[offset]; - - fd = z_reserve_fd(); - if (fd < 0) { - sys_bitarray_free(&efds_bitarray, 1, offset); - return -1; - } - - efd->flags = EFD_IN_USE_INTERNAL | flags; - efd->cnt = initval; - - k_poll_signal_init(&efd->write_sig); - k_poll_signal_init(&efd->read_sig); - - if (initval != 0) { - k_poll_signal_raise(&efd->read_sig, 0); - } - - k_poll_signal_raise(&efd->write_sig, 0); - - z_finalize_fd(fd, efd, &eventfd_fd_vtable); - - return fd; + return zvfs_eventfd(initval, flags); } int eventfd_read(int fd, eventfd_t *value) { - int ret; - void *obj; - - obj = z_get_fd_obj(fd, &eventfd_fd_vtable, EBADF); - if (obj == NULL) { - return -1; - } - - ret = eventfd_rw_op(obj, value, sizeof(eventfd_t), eventfd_read_locked); - __ASSERT_NO_MSG(ret == -1 || ret == sizeof(eventfd_t)); - if (ret < 0) { - return -1; - } - - return 0; + return zvfs_eventfd_read(fd, value); } int eventfd_write(int fd, eventfd_t value) { - int ret; - void *obj; - - obj = z_get_fd_obj(fd, &eventfd_fd_vtable, EBADF); - if (obj == NULL) { - return -1; - } - - ret = eventfd_rw_op(obj, &value, sizeof(eventfd_t), eventfd_write_locked); - __ASSERT_NO_MSG(ret == -1 || ret == sizeof(eventfd_t)); - if (ret < 0) { - return -1; - } - - return 0; + return zvfs_eventfd_write(fd, value); } diff --git a/lib/posix/options/fd_mgmt.c b/lib/posix/options/fd_mgmt.c new file mode 100644 index 00000000000000..c1f60aca8e490f --- /dev/null +++ b/lib/posix/options/fd_mgmt.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024, Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include + +/* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */ +int zvfs_fcntl(int fd, int cmd, va_list arg); +int zvfs_ftruncate(int fd, off_t length); +off_t zvfs_lseek(int fd, off_t offset, int whence); + +int fcntl(int fd, int cmd, ...) +{ + int ret; + va_list args; + + va_start(args, cmd); + ret = zvfs_fcntl(fd, cmd, args); + va_end(args); + + return ret; +} +#ifdef CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL +FUNC_ALIAS(fcntl, _fcntl, int); +#endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FCNTL */ + +int ftruncate(int fd, off_t length) +{ + return zvfs_ftruncate(fd, length); +} +#ifdef CONFIG_POSIX_FD_MGMT_ALIAS_FTRUNCATE +FUNC_ALIAS(ftruncate, _ftruncate, int); +#endif /* CONFIG_POSIX_FD_MGMT_ALIAS_FTRUNCATE */ + +off_t lseek(int fd, off_t offset, int whence) +{ + return zvfs_lseek(fd, offset, whence); +} +#ifdef CONFIG_POSIX_FD_MGMT_ALIAS_LSEEK +FUNC_ALIAS(lseek, _lseek, off_t); +#endif /* CONFIG_POSIX_FD_MGMT_ALIAS_LSEEK */ diff --git a/lib/posix/options/fs.c b/lib/posix/options/fs.c index 091a3ddccda0db..6a572c278f4dda 100644 --- a/lib/posix/options/fs.c +++ b/lib/posix/options/fs.c @@ -26,7 +26,7 @@ struct posix_fs_desc { bool used; }; -static struct posix_fs_desc desc_array[CONFIG_POSIX_MAX_OPEN_FILES]; +static struct posix_fs_desc desc_array[CONFIG_POSIX_OPEN_MAX]; static struct fs_dirent fdirent; static struct dirent pdirent; @@ -39,7 +39,7 @@ static struct posix_fs_desc *posix_fs_alloc_obj(bool is_dir) struct posix_fs_desc *ptr = NULL; unsigned int key = irq_lock(); - for (i = 0; i < CONFIG_POSIX_MAX_OPEN_FILES; i++) { + for (i = 0; i < CONFIG_POSIX_OPEN_MAX; i++) { if (desc_array[i].used == false) { ptr = &desc_array[i]; ptr->used = true; @@ -80,12 +80,7 @@ static int posix_mode_to_zephyr(int mf) return mode; } -/** - * @brief Open a file. - * - * See IEEE 1003.1 - */ -int open(const char *name, int flags, ...) +int zvfs_open(const char *name, int flags) { int rc, fd; struct posix_fs_desc *ptr = NULL; @@ -123,10 +118,6 @@ int open(const char *name, int flags, ...) return fd; } -#if !defined(CONFIG_NEWLIB_LIBC) && !defined(CONFIG_PICOLIBC) -FUNC_ALIAS(open, _open, int); -#endif - static int fs_close_vmeth(void *obj) { struct posix_fs_desc *ptr = obj; @@ -421,7 +412,7 @@ int mkdir(const char *path, mode_t mode) * @brief Truncate file to specified length. * */ -int ftruncate(int fd, off_t length) +int zvfs_ftruncate(int fd, off_t length) { int rc; struct posix_fs_desc *ptr = NULL; @@ -438,3 +429,15 @@ int ftruncate(int fd, off_t length) return 0; } + +int fstat(int fildes, struct stat *buf) +{ + ARG_UNUSED(fildes); + ARG_UNUSED(buf); + + errno = ENOTSUP; + return -1; +} +#ifdef CONFIG_POSIX_FILE_SYSTEM_ALIAS_FSTAT +FUNC_ALIAS(fstat, _fstat, int); +#endif diff --git a/lib/posix/options/fsync.c b/lib/posix/options/fsync.c new file mode 100644 index 00000000000000..8ec28b4440dc97 --- /dev/null +++ b/lib/posix/options/fsync.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* prototypes for external, not-yet-public, functions in fdtable.c */ +int zvfs_fsync(int fd); + +int fsync(int fd) +{ + return zvfs_fsync(fd); +} +#ifdef CONFIG_POSIX_FILE_SYSTEM_ALIAS_FSYNC +FUNC_ALIAS(fsync, _fsync, int); +#endif diff --git a/lib/posix/options/getentropy.c b/lib/posix/options/getentropy.c index dcc271617cbe2f..974ea4dce507f4 100644 --- a/lib/posix/options/getentropy.c +++ b/lib/posix/options/getentropy.c @@ -10,11 +10,11 @@ #include #include -#define ENTROPY_NODE DT_CHOSEN(zephyr_entropy) +#define ENTROPY_NODE DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)) int getentropy(void *buffer, size_t length) { - const struct device * const entropy = DEVICE_DT_GET(ENTROPY_NODE); + const struct device *const entropy = ENTROPY_NODE; if (!buffer) { errno = EFAULT; @@ -26,7 +26,7 @@ int getentropy(void *buffer, size_t length) return -1; } - if (!device_is_ready(entropy)) { + if (entropy == NULL || !device_is_ready(entropy)) { errno = EIO; return -1; } diff --git a/lib/posix/options/getopt/CMakeLists.txt b/lib/posix/options/getopt/CMakeLists.txt deleted file mode 100644 index 642e3b9949b5a6..00000000000000 --- a/lib/posix/options/getopt/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2021 Nordic Semiconductor -# -# SPDX-License-Identifier: Apache-2.0 -# - -zephyr_include_directories_ifdef( - CONFIG_GETOPT - . -) - -zephyr_sources_ifdef( - CONFIG_GETOPT - getopt.c - getopt_common.c -) - -zephyr_sources_ifdef( - CONFIG_GETOPT_LONG - getopt_long.c -) diff --git a/lib/posix/options/getopt/Kconfig b/lib/posix/options/getopt/Kconfig deleted file mode 100644 index 72c9961fb9041d..00000000000000 --- a/lib/posix/options/getopt/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2021 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - - -menuconfig GETOPT - bool "Getopt library support" - default y if POSIX_API - help - This option adds support of getopt. - Different shell backends are use their own instance of getopt to - not interfere with each other. - All not shell threads share one global instance of getopt state, hence - apart from shell this library is not thread safe. User can add support - for other threads by extending function getopt_state_get in - getopt_common.c file. - This option enables the following function: getopt. - -config GETOPT_LONG - bool "Getopt long library support" - depends on GETOPT - help - This option adds support of the getopt long. - Different shell backends are using their own instance of getopt to - not interfere with each other. - All not shell threads share one global instance of getopt state, hence - apart from shell this library is not thread safe. User can add support - for other threads by extending function getopt_state_get in - getopt_common.c file. diff --git a/lib/posix/options/getopt/getopt.h b/lib/posix/options/getopt/getopt.h index 3ae474f4304fcb..666c5541c635cd 100644 --- a/lib/posix/options/getopt/getopt.h +++ b/lib/posix/options/getopt/getopt.h @@ -29,6 +29,10 @@ struct getopt_state { }; extern int optreset; /* reset getopt */ +extern char *optarg; +extern int opterr; +extern int optind; +extern int optopt; #define no_argument 0 #define required_argument 1 diff --git a/lib/posix/options/key.c b/lib/posix/options/key.c index 5e68381c53b398..a7906b8d9f7ce5 100644 --- a/lib/posix/options/key.c +++ b/lib/posix/options/key.c @@ -29,11 +29,11 @@ static struct k_spinlock pthread_key_lock; * perspective of the application). With a linear space, this means that * the theoretical pthread_key_t range is [0,2147483647]. */ -BUILD_ASSERT(CONFIG_MAX_PTHREAD_KEY_COUNT < PTHREAD_OBJ_MASK_INIT, +BUILD_ASSERT(CONFIG_POSIX_THREAD_KEYS_MAX < PTHREAD_OBJ_MASK_INIT, "CONFIG_MAX_PTHREAD_KEY_COUNT is too high"); -static pthread_key_obj posix_key_pool[CONFIG_MAX_PTHREAD_KEY_COUNT]; -SYS_BITARRAY_DEFINE_STATIC(posix_key_bitarray, CONFIG_MAX_PTHREAD_KEY_COUNT); +static pthread_key_obj posix_key_pool[CONFIG_POSIX_THREAD_KEYS_MAX]; +SYS_BITARRAY_DEFINE_STATIC(posix_key_bitarray, CONFIG_POSIX_THREAD_KEYS_MAX); static inline size_t posix_key_to_offset(pthread_key_obj *k) { diff --git a/lib/posix/options/mqueue.c b/lib/posix/options/mqueue.c index ca8e54744889ca..ce77283e63782b 100644 --- a/lib/posix/options/mqueue.c +++ b/lib/posix/options/mqueue.c @@ -118,7 +118,7 @@ mqd_t mq_open(const char *name, int oflags, ...) /* Check for message quantity and size in message queue */ if (attrs->mq_msgsize > CONFIG_MSG_SIZE_MAX && - attrs->mq_maxmsg > CONFIG_MSG_COUNT_MAX) { + attrs->mq_maxmsg > CONFIG_POSIX_MQ_OPEN_MAX) { goto free_mq_desc; } diff --git a/lib/posix/options/multi_process.c b/lib/posix/options/multi_process.c new file mode 100644 index 00000000000000..221dc04ae1ad97 --- /dev/null +++ b/lib/posix/options/multi_process.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024, Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +pid_t getpid(void) +{ + /* + * To maintain compatibility with some other POSIX operating systems, + * a PID of zero is used to indicate that the process exists in another namespace. + * PID zero is also used by the scheduler in some cases. + * PID one is usually reserved for the init process. + * Also note, that negative PIDs may be used by kill() + * to send signals to process groups in some implementations. + * + * At the moment, getpid just returns an arbitrary number >= 2 + */ + + return 42; +} diff --git a/lib/posix/options/nanosleep.c b/lib/posix/options/nanosleep.c deleted file mode 100644 index aafb9dbeb79936..00000000000000 --- a/lib/posix/options/nanosleep.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Friedt Professional Engineering Services, Inc - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -/* required for struct timespec */ -#include -#include -#include - -/** - * @brief Suspend execution for nanosecond intervals. - * - * See IEEE 1003.1 - */ -int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) -{ - return clock_nanosleep(CLOCK_MONOTONIC, 0, rqtp, rmtp); -} diff --git a/lib/posix/options/net.c b/lib/posix/options/net.c index 5fcfdca464c8e1..84e4001a9b40db 100644 --- a/lib/posix/options/net.c +++ b/lib/posix/options/net.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include /* From arpa/inet.h */ @@ -102,11 +100,6 @@ char *if_indextoname(unsigned int ifindex, char *ifname) { int ret; - if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) { - errno = ENOTSUP; - return NULL; - } - ret = net_if_get_name(net_if_get_by_index(ifindex), ifname, IF_NAMESIZE); if (ret < 0) { errno = ENXIO; @@ -120,14 +113,14 @@ void if_freenameindex(struct if_nameindex *ptr) { size_t n; - if (ptr == NULL || !IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) { + if (ptr == NULL) { return; } NET_IFACE_COUNT(&n); for (size_t i = 0; i < n; ++i) { - if (IS_ENABLED(CONFIG_NET_INTERFACE_NAME) && ptr[i].if_name != NULL) { + if (ptr[i].if_name != NULL) { free(ptr[i].if_name); } } @@ -141,11 +134,6 @@ struct if_nameindex *if_nameindex(void) char *name; struct if_nameindex *ni; - if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) { - errno = ENOTSUP; - return NULL; - } - /* FIXME: would be nice to use this without malloc */ NET_IFACE_COUNT(&n); ni = malloc((n + 1) * sizeof(*ni)); @@ -181,10 +169,6 @@ unsigned int if_nametoindex(const char *ifname) { int ret; - if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) { - return 0; - } - ret = net_if_get_by_name(ifname); if (ret < 0) { return 0; @@ -355,11 +339,6 @@ int listen(int sock, int backlog) return zsock_listen(sock, backlog); } -int poll(struct pollfd *fds, int nfds, int timeout) -{ - return zsock_poll(fds, nfds, timeout); -} - ssize_t recv(int sock, void *buf, size_t max_len, int flags) { return zsock_recv(sock, buf, max_len, flags); @@ -376,11 +355,6 @@ ssize_t recvmsg(int sock, struct msghdr *msg, int flags) return zsock_recvmsg(sock, msg, flags); } -int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) -{ - return zsock_select(nfds, readfds, writefds, exceptfds, (struct zsock_timeval *)timeout); -} - ssize_t send(int sock, const void *buf, size_t len, int flags) { return zsock_send(sock, buf, len, flags); diff --git a/lib/posix/options/pthread.c b/lib/posix/options/pthread.c index a46cde7614cbec..d9748c64637a79 100644 --- a/lib/posix/options/pthread.c +++ b/lib/posix/options/pthread.c @@ -86,7 +86,7 @@ static sys_dlist_t posix_thread_q[] = { SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_RUN_Q]), SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_DONE_Q]), }; -static struct posix_thread posix_thread_pool[CONFIG_MAX_PTHREAD_COUNT]; +static struct posix_thread posix_thread_pool[CONFIG_POSIX_THREAD_THREADS_MAX]; static struct k_spinlock pthread_pool_lock; static int pthread_concurrency; @@ -123,8 +123,8 @@ static inline enum posix_thread_qid posix_thread_q_get(struct posix_thread *t) * perspective of the application). With a linear space, this means that * the theoretical pthread_t range is [0,2147483647]. */ -BUILD_ASSERT(CONFIG_MAX_PTHREAD_COUNT < PTHREAD_OBJ_MASK_INIT, - "CONFIG_MAX_PTHREAD_COUNT is too high"); +BUILD_ASSERT(CONFIG_POSIX_THREAD_THREADS_MAX < PTHREAD_OBJ_MASK_INIT, + "CONFIG_POSIX_THREAD_THREADS_MAX is too high"); static inline size_t posix_thread_to_offset(struct posix_thread *t) { @@ -148,7 +148,7 @@ struct posix_thread *to_posix_thread(pthread_t pthread) return NULL; } - if (bit >= CONFIG_MAX_PTHREAD_COUNT) { + if (bit >= ARRAY_SIZE(posix_thread_pool)) { LOG_DBG("Invalid pthread (%x)", pthread); return NULL; } @@ -188,22 +188,6 @@ int pthread_equal(pthread_t pt1, pthread_t pt2) return (pt1 == pt2); } -pid_t getpid(void) -{ - /* - * To maintain compatibility with some other POSIX operating systems, - * a PID of zero is used to indicate that the process exists in another namespace. - * PID zero is also used by the scheduler in some cases. - * PID one is usually reserved for the init process. - * Also note, that negative PIDs may be used by kill() - * to send signals to process groups in some implementations. - * - * At the moment, getpid just returns an arbitrary number >= 2 - */ - - return 42; -} - static inline void __z_pthread_cleanup_init(struct __pthread_cleanup *c, void (*routine)(void *arg), void *arg) { @@ -252,8 +236,8 @@ void __z_pthread_cleanup_pop(int execute) static bool is_posix_policy_prio_valid(int priority, int policy) { - if (priority >= sched_get_priority_min(policy) && - priority <= sched_get_priority_max(policy)) { + if (priority >= posix_sched_priority_min(policy) && + priority <= posix_sched_priority_max(policy)) { return true; } @@ -879,7 +863,7 @@ int pthread_setschedprio(pthread_t thread, int prio) int ret; int new_prio = K_LOWEST_APPLICATION_THREAD_PRIO; struct posix_thread *t = NULL; - int policy; + int policy = -1; struct sched_param param; ret = pthread_getschedparam(thread, &policy, ¶m); @@ -1375,7 +1359,7 @@ int pthread_setname_np(pthread_t thread, const char *name) k_tid_t kthread; thread = get_posix_thread_idx(thread); - if (thread >= CONFIG_MAX_PTHREAD_COUNT) { + if (thread >= ARRAY_SIZE(posix_thread_pool)) { return ESRCH; } @@ -1399,7 +1383,7 @@ int pthread_getname_np(pthread_t thread, char *name, size_t len) k_tid_t kthread; thread = get_posix_thread_idx(thread); - if (thread >= CONFIG_MAX_PTHREAD_COUNT) { + if (thread >= ARRAY_SIZE(posix_thread_pool)) { return ESRCH; } @@ -1474,10 +1458,8 @@ int pthread_sigmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT static int posix_thread_pool_init(void) { - size_t i; - - for (i = 0; i < CONFIG_MAX_PTHREAD_COUNT; ++i) { - posix_thread_q_set(&posix_thread_pool[i], POSIX_THREAD_READY_Q); + ARRAY_FOR_EACH_PTR(posix_thread_pool, th) { + posix_thread_q_set(th, POSIX_THREAD_READY_Q); } return 0; diff --git a/lib/posix/options/pthread_sched.h b/lib/posix/options/pthread_sched.h index 4a70d081f8480b..f51d05a985f098 100644 --- a/lib/posix/options/pthread_sched.h +++ b/lib/posix/options/pthread_sched.h @@ -7,6 +7,7 @@ #ifndef ZEPHYR_LIB_POSIX_POSIX_PTHREAD_SCHED_H_ #define ZEPHYR_LIB_POSIX_POSIX_PTHREAD_SCHED_H_ +#include #include #include @@ -16,4 +17,27 @@ static inline bool valid_posix_policy(int policy) return policy == SCHED_FIFO || policy == SCHED_RR || policy == SCHED_OTHER; } +static inline int posix_sched_priority_min(int policy) +{ + if (!valid_posix_policy(policy)) { + errno = EINVAL; + return -1; + } + + return 0; +} + +static inline int posix_sched_priority_max(int policy) +{ + if (IS_ENABLED(CONFIG_COOP_ENABLED) && policy == SCHED_FIFO) { + return CONFIG_NUM_COOP_PRIORITIES - 1; + } else if (IS_ENABLED(CONFIG_PREEMPT_ENABLED) && + (policy == SCHED_RR || policy == SCHED_OTHER)) { + return CONFIG_NUM_PREEMPT_PRIORITIES - 1; + } + + errno = EINVAL; + return -1; +} + #endif diff --git a/lib/posix/options/rwlock.c b/lib/posix/options/rwlock.c index b8a91a03232b83..f282fc26549fed 100644 --- a/lib/posix/options/rwlock.c +++ b/lib/posix/options/rwlock.c @@ -12,7 +12,7 @@ #include #include -#define CONCURRENT_READER_LIMIT (CONFIG_MAX_PTHREAD_COUNT + 1) +#define CONCURRENT_READER_LIMIT (CONFIG_POSIX_THREAD_THREADS_MAX + 1) struct posix_rwlock { struct k_sem rd_sem; diff --git a/lib/posix/options/sched.c b/lib/posix/options/sched.c index be174d92cd64ec..a37b01d0106b21 100644 --- a/lib/posix/options/sched.c +++ b/lib/posix/options/sched.c @@ -16,12 +16,7 @@ */ int sched_get_priority_min(int policy) { - if (!valid_posix_policy(policy)) { - errno = EINVAL; - return -1; - } - - return 0; + return posix_sched_priority_min(policy); } /** @@ -31,15 +26,7 @@ int sched_get_priority_min(int policy) */ int sched_get_priority_max(int policy) { - if (IS_ENABLED(CONFIG_COOP_ENABLED) && policy == SCHED_FIFO) { - return CONFIG_NUM_COOP_PRIORITIES - 1; - } else if (IS_ENABLED(CONFIG_PREEMPT_ENABLED) && - (policy == SCHED_RR || policy == SCHED_OTHER)) { - return CONFIG_NUM_PREEMPT_PRIORITIES - 1; - } - - errno = EINVAL; - return -1; + return posix_sched_priority_max(policy); } /** diff --git a/lib/posix/options/semaphore.c b/lib/posix/options/semaphore.c index 45cac48372f8d1..fddad0caf6b20d 100644 --- a/lib/posix/options/semaphore.c +++ b/lib/posix/options/semaphore.c @@ -120,7 +120,7 @@ int sem_getvalue(sem_t *semaphore, int *value) */ int sem_init(sem_t *semaphore, int pshared, unsigned int value) { - if (value > CONFIG_SEM_VALUE_MAX) { + if (value > CONFIG_POSIX_SEM_VALUE_MAX) { errno = EINVAL; return -1; } @@ -131,7 +131,7 @@ int sem_init(sem_t *semaphore, int pshared, unsigned int value) */ __ASSERT(pshared == 0, "pshared should be 0"); - k_sem_init(semaphore, value, CONFIG_SEM_VALUE_MAX); + k_sem_init(semaphore, value, CONFIG_POSIX_SEM_VALUE_MAX); return 0; } @@ -232,7 +232,7 @@ sem_t *sem_open(const char *name, int oflags, ...) value = va_arg(va, unsigned int); va_end(va); - if (value > CONFIG_SEM_VALUE_MAX) { + if (value > CONFIG_POSIX_SEM_VALUE_MAX) { errno = EINVAL; return (sem_t *)SEM_FAILED; } @@ -243,7 +243,7 @@ sem_t *sem_open(const char *name, int oflags, ...) } namelen = strlen(name); - if ((namelen + 1) > CONFIG_SEM_NAMELEN_MAX) { + if ((namelen + 1) > CONFIG_POSIX_SEM_NAMELEN_MAX) { errno = ENAMETOOLONG; return (sem_t *)SEM_FAILED; } @@ -291,7 +291,7 @@ sem_t *sem_open(const char *name, int oflags, ...) /* 1 for this open instance, +1 for the linked name */ nsem->ref_count = 2; - (void)k_sem_init(&nsem->sem, value, CONFIG_SEM_VALUE_MAX); + (void)k_sem_init(&nsem->sem, value, CONFIG_POSIX_SEM_VALUE_MAX); sys_slist_append(&nsem_list, (sys_snode_t *)&(nsem->snode)); @@ -318,7 +318,7 @@ int sem_unlink(const char *name) return -1; } - if ((strlen(name) + 1) > CONFIG_SEM_NAMELEN_MAX) { + if ((strlen(name) + 1) > CONFIG_POSIX_SEM_NAMELEN_MAX) { errno = ENAMETOOLONG; return -1; } diff --git a/lib/posix/options/signal.c b/lib/posix/options/signal.c index f14ef7fe614f96..d0674aea94b4d7 100644 --- a/lib/posix/options/signal.c +++ b/lib/posix/options/signal.c @@ -8,13 +8,13 @@ #include #include +#include #include #define SIGNO_WORD_IDX(_signo) (signo / BITS_PER_LONG) #define SIGNO_WORD_BIT(_signo) (signo & BIT_MASK(LOG2(BITS_PER_LONG))) -BUILD_ASSERT(CONFIG_POSIX_LIMITS_RTSIG_MAX >= 0); -BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= CONFIG_POSIX_LIMITS_RTSIG_MAX); +BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= 0); static inline bool signo_valid(int signo) { diff --git a/lib/posix/options/sleep.c b/lib/posix/options/sleep.c index 98fff715dda5f7..dd739322c75eeb 100644 --- a/lib/posix/options/sleep.c +++ b/lib/posix/options/sleep.c @@ -23,27 +23,3 @@ unsigned sleep(unsigned int seconds) return rem / MSEC_PER_SEC; } -/** - * @brief Suspend execution for microsecond intervals. - * - * See IEEE 1003.1 - */ -int usleep(useconds_t useconds) -{ - int32_t rem; - - if (useconds >= USEC_PER_SEC) { - errno = EINVAL; - return -1; - } - - rem = k_usleep(useconds); - __ASSERT_NO_MSG(rem >= 0); - if (rem > 0) { - /* sleep was interrupted by a call to k_wakeup() */ - errno = EINTR; - return -1; - } - - return 0; -} diff --git a/lib/posix/options/stropts.c b/lib/posix/options/stropts.c index c1e6c9f54eda32..dab6ea976855cc 100644 --- a/lib/posix/options/stropts.c +++ b/lib/posix/options/stropts.c @@ -19,6 +19,19 @@ int putmsg(int fildes, const struct strbuf *ctlptr, const struct strbuf *dataptr return -1; } +int putpmsg(int fildes, const struct strbuf *ctlptr, const struct strbuf *dataptr, int band, + int flags) +{ + ARG_UNUSED(fildes); + ARG_UNUSED(ctlptr); + ARG_UNUSED(dataptr); + ARG_UNUSED(band); + ARG_UNUSED(flags); + + errno = ENOSYS; + return -1; +} + int fdetach(const char *path) { ARG_UNUSED(path); diff --git a/lib/posix/options/sysconf.c b/lib/posix/options/sysconf.c index 78491bd6eb019d..5d3492918fb404 100644 --- a/lib/posix/options/sysconf.c +++ b/lib/posix/options/sysconf.c @@ -4,263 +4,271 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include #include +#ifdef CONFIG_POSIX_SYSCONF_IMPL_FULL + +#define z_sysconf(x) (long)CONCAT(__z_posix_sysconf, x) + long sysconf(int x) { switch (x) { case _SC_ADVISORY_INFO: - return _POSIX_ADVISORY_INFO; + return z_sysconf(_SC_ADVISORY_INFO); case _SC_ASYNCHRONOUS_IO: - return _POSIX_ASYNCHRONOUS_IO; + return z_sysconf(_SC_ASYNCHRONOUS_IO); case _SC_BARRIERS: - return _POSIX_BARRIERS; + return z_sysconf(_SC_BARRIERS); case _SC_CLOCK_SELECTION: - return _POSIX_CLOCK_SELECTION; + return z_sysconf(_SC_CLOCK_SELECTION); case _SC_CPUTIME: - return _POSIX_CPUTIME; + return z_sysconf(_SC_CPUTIME); case _SC_FSYNC: - return _POSIX_FSYNC; + return z_sysconf(_SC_FSYNC); case _SC_IPV6: - return _POSIX_IPV6; + return z_sysconf(_SC_IPV6); case _SC_JOB_CONTROL: - return _POSIX_JOB_CONTROL; - case _SC_MAPPED_FILE: - return _POSIX_MAPPED_FILES; + return z_sysconf(_SC_JOB_CONTROL); + case _SC_MAPPED_FILES: + return z_sysconf(_SC_MAPPED_FILES); case _SC_MEMLOCK: - return _POSIX_MEMLOCK; + return z_sysconf(_SC_MEMLOCK); case _SC_MEMLOCK_RANGE: - return _POSIX_MEMLOCK_RANGE; + return z_sysconf(_SC_MEMLOCK_RANGE); case _SC_MEMORY_PROTECTION: - return _POSIX_MEMORY_PROTECTION; + return z_sysconf(_SC_MEMORY_PROTECTION); case _SC_MESSAGE_PASSING: - return _POSIX_MESSAGE_PASSING; + return z_sysconf(_SC_MESSAGE_PASSING); case _SC_MONOTONIC_CLOCK: - return _POSIX_MONOTONIC_CLOCK; + return z_sysconf(_SC_MONOTONIC_CLOCK); case _SC_PRIORITIZED_IO: - return _POSIX_PRIORITIZED_IO; + return z_sysconf(_SC_PRIORITIZED_IO); case _SC_PRIORITY_SCHEDULING: - return _POSIX_PRIORITY_SCHEDULING; + return z_sysconf(_SC_PRIORITY_SCHEDULING); case _SC_RAW_SOCKETS: - return _POSIX_RAW_SOCKETS; + return z_sysconf(_SC_RAW_SOCKETS); case _SC_RE_DUP_MAX: - return _POSIX_RE_DUP_MAX; + return z_sysconf(_SC_RE_DUP_MAX); case _SC_READER_WRITER_LOCKS: - return _POSIX_READER_WRITER_LOCKS; + return z_sysconf(_SC_READER_WRITER_LOCKS); case _SC_REALTIME_SIGNALS: - return _POSIX_REALTIME_SIGNALS; + return z_sysconf(_SC_REALTIME_SIGNALS); case _SC_REGEXP: - return _POSIX_REGEXP; + return z_sysconf(_SC_REGEXP); case _SC_SAVED_IDS: - return _POSIX_SAVED_IDS; + return z_sysconf(_SC_SAVED_IDS); case _SC_SEMAPHORES: - return _POSIX_SEMAPHORES; + return z_sysconf(_SC_SEMAPHORES); case _SC_SHARED_MEMORY_OBJECTS: - return _POSIX_SHARED_MEMORY_OBJECTS; + return z_sysconf(_SC_SHARED_MEMORY_OBJECTS); case _SC_SHELL: - return _POSIX_SHELL; + return z_sysconf(_SC_SHELL); case _SC_SPAWN: - return _POSIX_SPAWN; + return z_sysconf(_SC_SPAWN); case _SC_SPIN_LOCKS: - return _POSIX_SPIN_LOCKS; + return z_sysconf(_SC_SPIN_LOCKS); case _SC_SPORADIC_SERVER: - return _POSIX_SPORADIC_SERVER; + return z_sysconf(_SC_SPORADIC_SERVER); case _SC_SS_REPL_MAX: - return _POSIX_SS_REPL_MAX; + return z_sysconf(_SC_SS_REPL_MAX); case _SC_SYNCHRONIZED_IO: - return _POSIX_SYNCHRONIZED_IO; + return z_sysconf(_SC_SYNCHRONIZED_IO); case _SC_THREAD_ATTR_STACKADDR: - return _POSIX_THREAD_ATTR_STACKADDR; + return z_sysconf(_SC_THREAD_ATTR_STACKADDR); case _SC_THREAD_ATTR_STACKSIZE: - return _POSIX_THREAD_ATTR_STACKSIZE; + return z_sysconf(_SC_THREAD_ATTR_STACKSIZE); case _SC_THREAD_CPUTIME: - return _POSIX_THREAD_CPUTIME; + return z_sysconf(_SC_THREAD_CPUTIME); case _SC_THREAD_PRIO_INHERIT: - return _POSIX_THREAD_PRIO_INHERIT; + return z_sysconf(_SC_THREAD_PRIO_INHERIT); case _SC_THREAD_PRIO_PROTECT: - return _POSIX_THREAD_PRIO_PROTECT; + return z_sysconf(_SC_THREAD_PRIO_PROTECT); case _SC_THREAD_PRIORITY_SCHEDULING: - return _POSIX_THREAD_PRIORITY_SCHEDULING; + return z_sysconf(_SC_THREAD_PRIORITY_SCHEDULING); case _SC_THREAD_PROCESS_SHARED: - return _POSIX_THREAD_PROCESS_SHARED; + return z_sysconf(_SC_THREAD_PROCESS_SHARED); case _SC_THREAD_ROBUST_PRIO_INHERIT: - return _POSIX_THREAD_ROBUST_PRIO_INHERIT; + return z_sysconf(_SC_THREAD_ROBUST_PRIO_INHERIT); case _SC_THREAD_ROBUST_PRIO_PROTECT: - return _POSIX_THREAD_ROBUST_PRIO_PROTECT; + return z_sysconf(_SC_THREAD_ROBUST_PRIO_PROTECT); case _SC_THREAD_SAFE_FUNCTIONS: - return _POSIX_THREAD_SAFE_FUNCTIONS; + return z_sysconf(_SC_THREAD_SAFE_FUNCTIONS); case _SC_THREAD_SPORADIC_SERVER: - return _POSIX_THREAD_SPORADIC_SERVER; + return z_sysconf(_SC_THREAD_SPORADIC_SERVER); case _SC_THREADS: - return _POSIX_THREADS; + return z_sysconf(_SC_THREADS); case _SC_TIMEOUTS: - return _POSIX_TIMEOUTS; + return z_sysconf(_SC_TIMEOUTS); case _SC_TIMERS: - return _POSIX_TIMERS; + return z_sysconf(_SC_TIMERS); case _SC_TRACE: - return _POSIX_TRACE; + return z_sysconf(_SC_TRACE); case _SC_TRACE_EVENT_FILTER: - return _POSIX_TRACE_EVENT_FILTER; + return z_sysconf(_SC_TRACE_EVENT_FILTER); case _SC_TRACE_EVENT_NAME_MAX: - return _POSIX_TRACE_EVENT_NAME_MAX; + return z_sysconf(_SC_TRACE_EVENT_NAME_MAX); case _SC_TRACE_INHERIT: - return _POSIX_TRACE_INHERIT; + return z_sysconf(_SC_TRACE_INHERIT); case _SC_TRACE_LOG: - return _POSIX_TRACE_LOG; + return z_sysconf(_SC_TRACE_LOG); case _SC_TRACE_NAME_MAX: - return _POSIX_TRACE_NAME_MAX; + return z_sysconf(_SC_TRACE_NAME_MAX); case _SC_TRACE_SYS_MAX: - return _POSIX_TRACE_SYS_MAX; + return z_sysconf(_SC_TRACE_SYS_MAX); case _SC_TRACE_USER_EVENT_MAX: - return _POSIX_TRACE_USER_EVENT_MAX; + return z_sysconf(_SC_TRACE_USER_EVENT_MAX); case _SC_TYPED_MEMORY_OBJECTS: - return _POSIX_TYPED_MEMORY_OBJECTS; + return z_sysconf(_SC_TYPED_MEMORY_OBJECTS); case _SC_VERSION: - return _POSIX_VERSION; - case _SC_V7_ILP32_OFF32: - return _POSIX_V7_ILP32_OFF32; - case _SC_V7_ILP32_OFFBIG: - return _POSIX_V7_ILP32_OFFBIG; - case _SC_V7_LP64_OFF64: - return _POSIX_V7_LP64_OFF64; - case _SC_V7_LPBIG_OFFBIG: - return _POSIX_V7_LPBIG_OFFBIG; + return z_sysconf(_SC_VERSION); case _SC_V6_ILP32_OFF32: - return _POSIX_V6_ILP32_OFF32; + return z_sysconf(_SC_V6_ILP32_OFF32); case _SC_V6_ILP32_OFFBIG: - return _POSIX_V6_ILP32_OFFBIG; + return z_sysconf(_SC_V6_ILP32_OFFBIG); case _SC_V6_LP64_OFF64: - return _POSIX_V6_LP64_OFF64; + return z_sysconf(_SC_V6_LP64_OFF64); case _SC_V6_LPBIG_OFFBIG: - return _POSIX_V6_LPBIG_OFFBIG; + return z_sysconf(_SC_V6_LPBIG_OFFBIG); + case _SC_V7_ILP32_OFF32: + return z_sysconf(_SC_V7_ILP32_OFF32); + case _SC_V7_ILP32_OFFBIG: + return z_sysconf(_SC_V7_ILP32_OFFBIG); + case _SC_V7_LP64_OFF64: + return z_sysconf(_SC_V7_LP64_OFF64); + case _SC_V7_LPBIG_OFFBIG: + return z_sysconf(_SC_V7_LPBIG_OFFBIG); case _SC_BC_BASE_MAX: - return _POSIX2_BC_BASE_MAX; + return z_sysconf(_SC_BC_BASE_MAX); case _SC_BC_DIM_MAX: - return _POSIX2_BC_DIM_MAX; + return z_sysconf(_SC_BC_DIM_MAX); case _SC_BC_SCALE_MAX: - return _POSIX2_BC_SCALE_MAX; + return z_sysconf(_SC_BC_SCALE_MAX); case _SC_BC_STRING_MAX: - return _POSIX2_BC_STRING_MAX; + return z_sysconf(_SC_BC_STRING_MAX); case _SC_2_C_BIND: - return _POSIX2_C_BIND; + return z_sysconf(_SC_2_C_BIND); case _SC_2_C_DEV: - return _POSIX2_C_DEV; + return z_sysconf(_SC_2_C_DEV); case _SC_2_CHAR_TERM: - return _POSIX2_CHAR_TERM; + return z_sysconf(_SC_2_CHAR_TERM); case _SC_COLL_WEIGHTS_MAX: - return _POSIX2_COLL_WEIGHTS_MAX; + return z_sysconf(_SC_COLL_WEIGHTS_MAX); case _SC_DELAYTIMER_MAX: - return _POSIX2_DELAYTIMER_MAX; + return z_sysconf(_SC_DELAYTIMER_MAX); case _SC_EXPR_NEST_MAX: - return _POSIX2_EXPR_NEST_MAX; + return z_sysconf(_SC_EXPR_NEST_MAX); case _SC_2_FORT_DEV: - return _POSIX2_FORT_DEV; + return z_sysconf(_SC_2_FORT_DEV); case _SC_2_FORT_RUN: - return _POSIX2_FORT_RUN; + return z_sysconf(_SC_2_FORT_RUN); case _SC_LINE_MAX: - return _POSIX2_LINE_MAX; + return z_sysconf(_SC_LINE_MAX); case _SC_2_LOCALEDEF: - return _POSIX2_LOCALEDEF; + return z_sysconf(_SC_2_LOCALEDEF); case _SC_2_PBS: - return _POSIX2_PBS; + return z_sysconf(_SC_2_PBS); case _SC_2_PBS_ACCOUNTING: - return _POSIX2_PBS_ACCOUNTING; + return z_sysconf(_SC_2_PBS_ACCOUNTING); case _SC_2_PBS_CHECKPOINT: - return _POSIX2_PBS_CHECKPOINT; + return z_sysconf(_SC_2_PBS_CHECKPOINT); case _SC_2_PBS_LOCATE: - return _POSIX2_PBS_LOCATE; + return z_sysconf(_SC_2_PBS_LOCATE); case _SC_2_PBS_MESSAGE: - return _POSIX2_PBS_MESSAGE; + return z_sysconf(_SC_2_PBS_MESSAGE); case _SC_2_PBS_TRACK: - return _POSIX2_PBS_TRACK; + return z_sysconf(_SC_2_PBS_TRACK); case _SC_2_SW_DEV: - return _POSIX2_SW_DEV; + return z_sysconf(_SC_2_SW_DEV); case _SC_2_UPE: - return _POSIX2_UPE; + return z_sysconf(_SC_2_UPE); case _SC_2_VERSION: - return _POSIX2_VERSION; + return z_sysconf(_SC_2_VERSION); case _SC_XOPEN_CRYPT: - return _XOPEN_CRYPT; + return z_sysconf(_SC_XOPEN_CRYPT); case _SC_XOPEN_ENH_I18N: - return _XOPEN_ENH_I18N; + return z_sysconf(_SC_XOPEN_ENH_I18N); case _SC_XOPEN_REALTIME: - return _XOPEN_REALTIME; + return z_sysconf(_SC_XOPEN_REALTIME); case _SC_XOPEN_REALTIME_THREADS: - return _XOPEN_REALTIME_THREADS; + return z_sysconf(_SC_XOPEN_REALTIME_THREADS); case _SC_XOPEN_SHM: - return _XOPEN_SHM; + return z_sysconf(_SC_XOPEN_SHM); case _SC_XOPEN_STREAMS: - return _XOPEN_STREAMS; + return z_sysconf(_SC_XOPEN_STREAMS); case _SC_XOPEN_UNIX: - return _XOPEN_UNIX; + return z_sysconf(_SC_XOPEN_UNIX); case _SC_XOPEN_UUCP: - return _XOPEN_UUCP; + return z_sysconf(_SC_XOPEN_UUCP); case _SC_XOPEN_VERSION: - return _XOPEN_VERSION; + return z_sysconf(_SC_XOPEN_VERSION); case _SC_CLK_TCK: - return (100L); + return z_sysconf(_SC_CLK_TCK); case _SC_GETGR_R_SIZE_MAX: - return (0L); + return z_sysconf(_SC_GETGR_R_SIZE_MAX); case _SC_GETPW_R_SIZE_MAX: - return (0L); + return z_sysconf(_SC_GETPW_R_SIZE_MAX); case _SC_AIO_LISTIO_MAX: - return AIO_LISTIO_MAX; + return z_sysconf(_SC_AIO_LISTIO_MAX); case _SC_AIO_MAX: - return AIO_MAX; + return z_sysconf(_SC_AIO_MAX); case _SC_AIO_PRIO_DELTA_MAX: - return AIO_PRIO_DELTA_MAX; + return z_sysconf(_SC_AIO_PRIO_DELTA_MAX); case _SC_ARG_MAX: - return ARG_MAX; + return z_sysconf(_SC_ARG_MAX); case _SC_ATEXIT_MAX: - return ATEXIT_MAX; + return z_sysconf(_SC_ATEXIT_MAX); case _SC_CHILD_MAX: - return CHILD_MAX; + return z_sysconf(_SC_CHILD_MAX); case _SC_HOST_NAME_MAX: - return _POSIX_HOST_NAME_MAX; + return z_sysconf(_SC_HOST_NAME_MAX); case _SC_IOV_MAX: - return IOV_MAX; + return z_sysconf(_SC_IOV_MAX); case _SC_LOGIN_NAME_MAX: - return LOGIN_NAME_MAX; + return z_sysconf(_SC_LOGIN_NAME_MAX); case _SC_NGROUPS_MAX: - return _POSIX_NGROUPS_MAX; + return z_sysconf(_SC_NGROUPS_MAX); case _SC_MQ_OPEN_MAX: - return MQ_OPEN_MAX; + return z_sysconf(_SC_MQ_OPEN_MAX); case _SC_MQ_PRIO_MAX: - return MQ_PRIO_MAX; + return z_sysconf(_SC_MQ_PRIO_MAX); case _SC_OPEN_MAX: - return CONFIG_POSIX_MAX_FDS; + return z_sysconf(_SC_OPEN_MAX); case _SC_PAGE_SIZE: - return PAGE_SIZE; + return z_sysconf(_SC_PAGE_SIZE); case _SC_PAGESIZE: - return PAGESIZE; + return z_sysconf(_SC_PAGESIZE); case _SC_THREAD_DESTRUCTOR_ITERATIONS: - return PTHREAD_DESTRUCTOR_ITERATIONS; + return z_sysconf(_SC_THREAD_DESTRUCTOR_ITERATIONS); case _SC_THREAD_KEYS_MAX: - return PTHREAD_KEYS_MAX; + return z_sysconf(_SC_THREAD_KEYS_MAX); case _SC_THREAD_STACK_MIN: - return PAGE_SIZE; + return z_sysconf(_SC_THREAD_STACK_MIN); case _SC_THREAD_THREADS_MAX: - return PTHREAD_THREADS_MAX; + return z_sysconf(_SC_THREAD_THREADS_MAX); case _SC_RTSIG_MAX: - return RTSIG_MAX; + return z_sysconf(_SC_RTSIG_MAX); case _SC_SEM_NSEMS_MAX: - return SEM_NSEMS_MAX; + return z_sysconf(_SC_SEM_NSEMS_MAX); case _SC_SEM_VALUE_MAX: - return SEM_VALUE_MAX; + return z_sysconf(_SC_SEM_VALUE_MAX); case _SC_SIGQUEUE_MAX: - return SIGQUEUE_MAX; + return z_sysconf(_SC_SIGQUEUE_MAX); case _SC_STREAM_MAX: - return STREAM_MAX; + return z_sysconf(_SC_STREAM_MAX); case _SC_SYMLOOP_MAX: - return SYMLOOP_MAX; + return z_sysconf(_SC_SYMLOOP_MAX); case _SC_TIMER_MAX: - return TIMER_MAX; + return z_sysconf(_SC_TIMER_MAX); case _SC_TTY_NAME_MAX: - return TTY_NAME_MAX; + return z_sysconf(_SC_TTY_NAME_MAX); case _SC_TZNAME_MAX: - return TZNAME_MAX; + return z_sysconf(_SC_TZNAME_MAX); default: errno = EINVAL; return -1; } } + +#endif /* CONFIG_POSIX_SYSCONF_IMPL_FULL */ diff --git a/lib/posix/options/timer.c b/lib/posix/options/timer.c index 7caecc180a1279..d556c78133142c 100644 --- a/lib/posix/options/timer.c +++ b/lib/posix/options/timer.c @@ -29,8 +29,8 @@ struct timer_obj { uint32_t status; }; -K_MEM_SLAB_DEFINE(posix_timer_slab, sizeof(struct timer_obj), - CONFIG_MAX_TIMER_COUNT, __alignof__(struct timer_obj)); +K_MEM_SLAB_DEFINE(posix_timer_slab, sizeof(struct timer_obj), CONFIG_POSIX_TIMER_MAX, + __alignof__(struct timer_obj)); static void zephyr_timer_wrapper(struct k_timer *ztimer) { @@ -306,8 +306,8 @@ int timer_getoverrun(timer_t timerid) int overruns = k_timer_status_get(&timer->ztimer) - 1; - if (overruns > CONFIG_TIMER_DELAYTIMER_MAX) { - overruns = CONFIG_TIMER_DELAYTIMER_MAX; + if (overruns > CONFIG_POSIX_DELAYTIMER_MAX) { + overruns = CONFIG_POSIX_DELAYTIMER_MAX; } return overruns; diff --git a/lib/posix/options/_common.c b/lib/posix/options/timespec_to_timeout.c similarity index 93% rename from lib/posix/options/_common.c rename to lib/posix/options/timespec_to_timeout.c index 85a8e7cae66db2..e72956e6e3e933 100644 --- a/lib/posix/options/_common.c +++ b/lib/posix/options/timespec_to_timeout.c @@ -8,7 +8,6 @@ #include #include -#ifdef CONFIG_POSIX_CLOCK int64_t timespec_to_timeoutms(const struct timespec *abstime) { int64_t milli_secs, secs, nsecs; @@ -30,4 +29,3 @@ int64_t timespec_to_timeoutms(const struct timespec *abstime) return milli_secs; } -#endif /* CONFIG_POSIX_CLOCK */ diff --git a/lib/posix/shell/Kconfig.env b/lib/posix/shell/Kconfig.env index d2d5fd53b3e974..bbe36bc9cbbb29 100644 --- a/lib/posix/shell/Kconfig.env +++ b/lib/posix/shell/Kconfig.env @@ -3,7 +3,7 @@ config POSIX_ENV_SHELL bool "Support for shell" - select POSIX_ENV + select POSIX_SINGLE_PROCESS select POSIX_SHELL help This shell provides access to system environment variables. diff --git a/lib/posix/shell/Kconfig.uname b/lib/posix/shell/Kconfig.uname index 11ea1166433a82..73547e3ac84b66 100644 --- a/lib/posix/shell/Kconfig.uname +++ b/lib/posix/shell/Kconfig.uname @@ -1,7 +1,7 @@ # Copyright (c) 2024 Meta # SPDX-License-Identifier: Apache-2.0 -if POSIX_UNAME +if POSIX_SINGLE_PROCESS config POSIX_UNAME_SHELL bool "Support for `uname` command" @@ -10,4 +10,4 @@ config POSIX_UNAME_SHELL help Support for `uname` command in the terminal. -endif # POSIX_UNAME +endif # POSIX_SINGLE_PROCESS diff --git a/lib/smf/smf.c b/lib/smf/smf.c index fb0c95c574f235..48c50e623ca8d6 100644 --- a/lib/smf/smf.c +++ b/lib/smf/smf.c @@ -98,12 +98,12 @@ static bool smf_execute_all_entry_actions(struct smf_ctx *const ctx, for (const struct smf_state *to_execute = get_child_of(new_state, topmost); to_execute != NULL && to_execute != new_state; to_execute = get_child_of(new_state, to_execute)) { + /* Keep track of the executing entry action in case it calls + * smf_set_state() + */ + ctx->executing = to_execute; /* Execute every entry action EXCEPT that of the topmost state */ if (to_execute->entry) { - /* Keep track of the executing entry action in case it calls - * smf_set_State() - */ - ctx->executing = to_execute; to_execute->entry(ctx); /* No need to continue if terminate was set */ @@ -114,6 +114,7 @@ static bool smf_execute_all_entry_actions(struct smf_ctx *const ctx, } /* and execute the new state entry action */ + ctx->executing = new_state; if (new_state->entry) { new_state->entry(ctx); @@ -197,7 +198,8 @@ static bool smf_execute_all_exit_actions(struct smf_ctx *const ctx, const struct { struct internal_ctx *const internal = (void *)&ctx->internal; - for (const struct smf_state *to_execute = ctx->current; to_execute != topmost; + for (const struct smf_state *to_execute = ctx->current; + to_execute != NULL && to_execute != topmost; to_execute = to_execute->parent) { if (to_execute->exit) { to_execute->exit(ctx); diff --git a/lib/utils/json.c b/lib/utils/json.c index 2041db757e97f0..73ca67e2f36613 100644 --- a/lib/utils/json.c +++ b/lib/utils/json.c @@ -1002,6 +1002,13 @@ static int opaque_string_encode(struct json_obj_token *opaque, json_append_bytes return append_bytes("\"", 1, data); } +static int encoded_obj_encode(const char **str, json_append_bytes_t append_bytes, void *data) +{ + size_t len = strlen(*str); + + return append_bytes(*str, len, data); +} + static int bool_encode(const bool *value, json_append_bytes_t append_bytes, void *data) { @@ -1036,6 +1043,8 @@ static int encode(const struct json_obj_descr *descr, const void *val, return float_ascii_encode(ptr, append_bytes, data); case JSON_TOK_OPAQUE: return opaque_string_encode(ptr, append_bytes, data); + case JSON_TOK_ENCODED_OBJ: + return encoded_obj_encode(ptr, append_bytes, data); default: return -EINVAL; } diff --git a/lib/utils/onoff.c b/lib/utils/onoff.c index 899b25a83e0271..49ff4ce28d1881 100644 --- a/lib/utils/onoff.c +++ b/lib/utils/onoff.c @@ -173,7 +173,7 @@ static void notify_one(struct onoff_manager *mgr, onoff_client_callback cb = (onoff_client_callback)sys_notify_finalize(&cli->notify, res); - if (cb) { + if (cb != NULL) { cb(mgr, cli, state, res); } } @@ -643,7 +643,7 @@ int onoff_sync_finalize(struct onoff_sync_service *srv, k_spin_unlock(&srv->lock, key); - if (cli) { + if (cli != NULL) { /* Detect service mis-use: onoff does not callback on transition * to off, so no client should have been passed. */ diff --git a/lib/utils/timeutil.c b/lib/utils/timeutil.c index 18c173acc8dc4b..980b2b5f14e069 100644 --- a/lib/utils/timeutil.c +++ b/lib/utils/timeutil.c @@ -148,7 +148,7 @@ int timeutil_sync_ref_from_local(const struct timeutil_sync_state *tsp, rv = -ERANGE; } else { *refp = ref_abs; - rv = (int)(tsp->skew != 1.0f); + rv = (tsp->skew != 1.0f) ? 1 : 0; } } @@ -175,7 +175,7 @@ int timeutil_sync_local_from_ref(const struct timeutil_sync_state *tsp, + (int64_t)local_delta; *localp = local_abs; - rv = (int)(tsp->skew != 1.0f); + rv = (tsp->skew != 1.0f) ? 1 : 0; } return rv; diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index 5d30250079fc60..4931c33568c523 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -375,6 +375,12 @@ config NXP_FW_LOADER The firmware loader is used to load firmwares to embedded tranceivers. It is needed to enable connectivity features. +config NXP_MONOLITHIC_BT + bool "BT firmware monolithic build" + help + If enabled, the BT firmware used by the device will be linked with the + application directly. + config NXP_RF_IMU bool "Include RF_IMU adapter for intercore messaging" select EVENTS diff --git a/modules/Kconfig.silabs b/modules/Kconfig.silabs index 0078bfc0b98794..c5fb0d6ca149d6 100644 --- a/modules/Kconfig.silabs +++ b/modules/Kconfig.silabs @@ -6,4 +6,4 @@ config HAS_SILABS_GECKO bool select HAS_CMSIS_CORE - depends on SOC_VENDOR_SILABS + depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 diff --git a/modules/Kconfig.simplelink b/modules/Kconfig.simplelink index cbcf1766d6b27e..13b26b1ca1a484 100644 --- a/modules/Kconfig.simplelink +++ b/modules/Kconfig.simplelink @@ -7,15 +7,15 @@ config HAS_CC3220SDK # SimpleLink drivers require types (stdint.h) from c library which is not # provided by minimal lbc # Selecting ERRNO lets host driver use Zephyr's __errno -# Selecting PTHREAD_IPC and POSIX_API are needed to build the host driver +# Selecting POSIX_THREADS and POSIX_API are needed to build the host driver config SIMPLELINK_HOST_DRIVER bool "Build the SimpleLink WiFi Host Driver" depends on HAS_CC3220SDK depends on MULTITHREADING select REQUIRES_FULL_LIBC select ERRNO - select PTHREAD_IPC - select POSIX_CLOCK + select POSIX_THREADS + select POSIX_TIMERS help Build the SimpleLink host driver diff --git a/modules/fatfs/zfs_diskio.c b/modules/fatfs/zfs_diskio.c index 7a5061f15b6e47..2b0fa742e711ec 100644 --- a/modules/fatfs/zfs_diskio.c +++ b/modules/fatfs/zfs_diskio.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2021 Zephyr contributors * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +13,7 @@ */ #include #include /* FatFs lower layer API */ +#include /* Zephyr specific FatFS API */ #include static const char * const pdrv_str[] = {FF_VOLUME_STRS}; @@ -31,13 +33,9 @@ DSTATUS disk_status(BYTE pdrv) /* Initialize a Drive */ DSTATUS disk_initialize(BYTE pdrv) { - __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + uint8_t param = DISK_IOCTL_POWER_ON; - if (disk_access_init(pdrv_str[pdrv]) != 0) { - return STA_NOINIT; - } else { - return RES_OK; - } + return disk_ioctl(pdrv, CTRL_POWER, ¶m); } /* Read Sector(s) */ @@ -109,6 +107,27 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) } break; + /* Optional IOCTL command used by Zephyr fs_unmount implementation, + * not called by FATFS + */ + case CTRL_POWER: + if (((*(uint8_t *)buff)) == DISK_IOCTL_POWER_OFF) { + /* Power disk off */ + if (disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_CTRL_DEINIT, + NULL) != 0) { + ret = RES_ERROR; + } + } else { + /* Power disk on */ + if (disk_access_ioctl(pdrv_str[pdrv], + DISK_IOCTL_CTRL_INIT, + NULL) != 0) { + ret = STA_NOINIT; + } + } + break; + default: ret = RES_PARERR; break; diff --git a/modules/fatfs/zfs_diskio.h b/modules/fatfs/zfs_diskio.h new file mode 100644 index 00000000000000..b22c75586be713 --- /dev/null +++ b/modules/fatfs/zfs_diskio.h @@ -0,0 +1,22 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_FATFS_ZFS_DISKIO_H_ +#define ZEPHYR_MODULES_FATFS_ZFS_DISKIO_H_ +/* + * Header file for Zephyr specific portions of the FatFS disk interface. + * These APIs are internal to Zephyr's FatFS VFS implementation + */ + +/* + * Values that can be passed to buffer pointer used by disk_ioctl() when + * sending CTRL_POWER IOCTL + */ +#define DISK_IOCTL_POWER_OFF 0x0 +#define DISK_IOCTL_POWER_ON 0x1 + + +#endif /* ZEPHYR_MODULES_FATFS_ZFS_DISKIO_H_ */ diff --git a/modules/hal_infineon/btstack-integration/CMakeLists.txt b/modules/hal_infineon/btstack-integration/CMakeLists.txt index d82fe10662ddaf..8033fe30443848 100644 --- a/modules/hal_infineon/btstack-integration/CMakeLists.txt +++ b/modules/hal_infineon/btstack-integration/CMakeLists.txt @@ -2,14 +2,39 @@ # # SPDX-License-Identifier: Apache-2.0 -set(hal_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}) -set(hal_ble_dir ${hal_dir}/bluetooth-freertos) -set(hal_blobs_dir ${hal_dir}/zephyr/blobs/img/bluetooth/firmware) -set(blob_gen_inc_file ${ZEPHYR_BINARY_DIR}/include/generated/bt_firmware.hcd.inc) +set(hal_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}) +set(btstack_integration ${hal_dir}/btstack-integration) +set(hal_blobs_dir ${hal_dir}/zephyr/blobs/img/bluetooth/firmware) +set(blob_gen_inc_file ${ZEPHYR_BINARY_DIR}/include/generated/bt_firmware.hcd.inc) + +######################################################################################### +# btstack integration assets sources for cyw208xx +######################################################################################### + +if(CONFIG_BT_CYW208XX) + + zephyr_include_directories(${btstack_integration}/../btstack/wiced_include) + zephyr_include_directories(${btstack_integration}/COMPONENT_BTSS-IPC/platform/include) + zephyr_include_directories(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/include) + + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/cybt_platform_freertos.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/cybt_platform_hci.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/cybt_bt_task.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/cybt_host_stack_platform_interface.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/ipc/cybt_platform_task.c) + + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/common/cybt_platform_main.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/common/cybt_platform_trace.c) + zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/common/cybt_prm.c) + + #zephyr_library_sources(${btstack_integration}/COMPONENT_BTSS-IPC/platform/common/cybt_patchram_download.c) +endif() ######################################################################################### # BT firmware ######################################################################################### + +# HCD files for CYW43xx devices # CYW43012 modules if(CONFIG_CYW43012_MURATA_1LV) set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_43012/COMPONENT_MURATA-1LV/bt_firmware.hcd) @@ -30,6 +55,38 @@ if(CONFIG_CYW4373_STERLING_LWB5PLUS) set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_4373/COMPONENT_STERLING-LWB5plus/bt_firmware.hcd) endif() +# HCD files for CYW208xx + +# CYW20829 device (FW patch for 0dBm TX Power) +if(CONFIG_CYW20829_BT_FW_TX0) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-TX0/bt_firmware.hcd) +endif() + +# CYW20829 device (FW patch for 10dBm TX Power) +if(CONFIG_CYW20829_BT_FW_TX10) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-TX10/bt_firmware.hcd) +endif() + +# CYW20829 device (FW patch with PAwR support for 0dBm TX Power) +if(CONFIG_CYW20829_BT_FW_PAWR_TX0) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-PAWR-TX0/bt_firmware.hcd) +endif() + +# CYW20829 device (FW patch with PAwR support for 10dBm TX Power) +if(CONFIG_CYW20829_BT_FW_PAWR_TX10) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-PAWR-TX10/bt_firmware.hcd) +endif() + +# CYW20829 device (FW patch with ISOC support for 0dBm TX Power) +if(CONFIG_CYW20829_BT_FW_ISOC_TX0) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-ISOC-TX0/bt_firmware.hcd) +endif() + +# CYW20829 device (FW patch with ISOC support for 10dBm TX Power) +if(CONFIG_CYW20829_BT_FW_ISOC_TX10) + set(blob_hcd_file ${hal_blobs_dir}/COMPONENT_CYW20829B0/COMPONENT_BTFW-ISOC-TX10/bt_firmware.hcd) +endif() + # use user provided FIRMWARE HCD file (path must be defined in CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB) if(CONFIG_AIROC_CUSTOM_FIRMWARE_HCD_BLOB) # Allowed to pass absolute path to HCD blob file, or relative path from Application folder. diff --git a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt index 3d264fd5ee5bc4..fd14d6da280554 100644 --- a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt +++ b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt @@ -23,6 +23,8 @@ zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1A ${pdl_dev_cat1 zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1A ${pdl_dev_cat1a_dir}/include/ip) zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1A ${pdl_dev_cat1a_dir}/source/cy_device.c) + +zephyr_include_directories(${pdl_drv_dir}/include) zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1B ${pdl_dev_cat1b_dir}/include) zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1B ${pdl_dev_cat1b_dir}/include/ip) zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1B ${pdl_dev_cat1b_dir}/source/cy_device.c) @@ -70,6 +72,7 @@ zephyr_library_sources(${pdl_drv_dir}/source/cy_sysclk.c) if(CONFIG_SOC_FAMILY_INFINEON_CAT1B) zephyr_library_sources(${pdl_drv_dir}/source/cy_sysclk_v2.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_systick_v2.c) + zephyr_library_sources(${pdl_drv_dir}/source/cy_syspm_v2.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_syspm_btss.c) endif() zephyr_library_sources(${pdl_drv_dir}/source/cy_syslib.c) @@ -77,3 +80,7 @@ zephyr_library_sources(${pdl_drv_dir}/source/cy_syspm.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_systick.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_trigmux.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_wdt.c) + +# add IPC_BT driver for CYW208XX devices +zephyr_library_sources_ifdef(CONFIG_BT_CYW208XX ${pdl_drv_dir}/source/cy_ipc_bt.c) +zephyr_library_sources_ifdef(CONFIG_BT_CYW208XX ${pdl_drv_dir}/source/cy_syspm_pdcm.c) diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index a7d55e4620aa5d..13ab8d9cd2f9c5 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -55,7 +55,7 @@ endchoice config NRF_802154_TEMPERATURE_UPDATE bool "nRF 802.15.4 temperature update" - default y + default y if !SOC_NRF54H20 help Enable temperature update for nRF 802.15.4 driver diff --git a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c index 3a3d9501d0c79c..1db86f5ad142d2 100644 --- a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c +++ b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c @@ -4,18 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include +#include +#if defined(CONFIG_CLOCK_CONTROL_NRF) #include #include +#elif !defined(NRF54H_SERIES) +#error No implementation to start or stop HFCLK due to missing clock_control. +#endif static bool hfclk_is_running; -static bool lfclk_is_running; -static struct onoff_client hfclk_cli; -static struct onoff_client lfclk_cli; void nrf_802154_clock_init(void) { @@ -27,6 +30,15 @@ void nrf_802154_clock_deinit(void) /* Intentionally empty. */ } +bool nrf_802154_clock_hfclk_is_running(void) +{ + return hfclk_is_running; +} + +#if defined(CONFIG_CLOCK_CONTROL_NRF) + +static struct onoff_client hfclk_cli; + static void hfclk_on_callback(struct onoff_manager *mgr, struct onoff_client *cli, uint32_t state, @@ -63,53 +75,39 @@ void nrf_802154_clock_hfclk_stop(void) hfclk_is_running = false; } -bool nrf_802154_clock_hfclk_is_running(void) -{ - return hfclk_is_running; -} +#elif defined(NRF54H_SERIES) -static void lfclk_on_callback(struct onoff_manager *mgr, - struct onoff_client *cli, - uint32_t state, - int res) -{ - lfclk_is_running = true; - nrf_802154_clock_lfclk_ready(); -} +#define NRF_LRCCONF_RADIO_PD NRF_LRCCONF010 +#define MAX_HFXO_RAMP_UP_TIME_US 1000 -void nrf_802154_clock_lfclk_start(void) +static void hfclk_started_timer_handler(struct k_timer *dummy) { - int ret; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); - - __ASSERT_NO_MSG(mgr != NULL); - - sys_notify_init_callback(&lfclk_cli.notify, lfclk_on_callback); - - ret = onoff_request(mgr, &lfclk_cli); - __ASSERT_NO_MSG(ret >= 0); + hfclk_is_running = true; + nrf_802154_clock_hfclk_ready(); } -void nrf_802154_clock_lfclk_stop(void) -{ - int ret; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); +K_TIMER_DEFINE(hfclk_started_timer, hfclk_started_timer_handler, NULL); - __ASSERT_NO_MSG(mgr != NULL); +void nrf_802154_clock_hfclk_start(void) +{ + /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger. + * This code might cause troubles if there are other HFXO users in this CPU. + */ + NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0; + NRF_LRCCONF_RADIO_PD->TASKS_REQHFXO = 0x1; - ret = onoff_cancel_or_release(mgr, &lfclk_cli); - __ASSERT_NO_MSG(ret >= 0); - lfclk_is_running = false; + k_timer_start(&hfclk_started_timer, K_USEC(MAX_HFXO_RAMP_UP_TIME_US), K_NO_WAIT); } -bool nrf_802154_clock_lfclk_is_running(void) +void nrf_802154_clock_hfclk_stop(void) { - return lfclk_is_running; -} + /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger. + * This code might cause troubles if there are other HFXO users in this CPU. + */ + NRF_LRCCONF_RADIO_PD->TASKS_STOPREQHFXO = 0x1; + NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0; -__WEAK void nrf_802154_clock_lfclk_ready(void) -{ - /* Intentionally empty. */ + hfclk_is_running = false; } + +#endif diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index a0f2f481bc37ef..d1f9314954ae53 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -32,7 +32,7 @@ #endif #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define NRFX_CLOCK_CONFIG_LF_SRC 1 #else #define NRFX_CLOCK_CONFIG_LF_SRC 0 @@ -40,7 +40,7 @@ #endif // CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define NRFX_CLOCK_CONFIG_LF_SRC 2 #else #define NRFX_CLOCK_CONFIG_LF_SRC 1 @@ -48,7 +48,7 @@ #endif // CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH -#ifdef CONFIG_SOC_SERIES_NRF53X +#ifdef CONFIG_SOC_COMPATIBLE_NRF53X #define NRFX_CLOCK_CONFIG_LF_SRC 3 #else #define NRFX_CLOCK_CONFIG_LF_SRC 2 diff --git a/modules/hal_nordic/nrfx/nrfx_glue.h b/modules/hal_nordic/nrfx/nrfx_glue.h index 0dd8b2bba94730..0f480a70f494a1 100644 --- a/modules/hal_nordic/nrfx/nrfx_glue.h +++ b/modules/hal_nordic/nrfx/nrfx_glue.h @@ -335,7 +335,10 @@ void nrfx_busy_wait(uint32_t usec_to_wait); NRFX_PPI_GROUPS_USED_BY_MPSL) /** @brief Bitmask that defines GPIOTE130 channels reserved for use outside of the nrfx library. */ -#define NRFX_GPIOTE130_CHANNELS_USED ~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), owned_channels) +#define NRFX_GPIOTE130_CHANNELS_USED \ + (~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), owned_channels) | \ + NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), child_owned_channels)) + #if defined(CONFIG_BT_CTLR) /* diff --git a/modules/hal_nxp/CMakeLists.txt b/modules/hal_nxp/CMakeLists.txt index 2f2e53d22ea85c..7ae7ff304ae4c2 100644 --- a/modules/hal_nxp/CMakeLists.txt +++ b/modules/hal_nxp/CMakeLists.txt @@ -23,4 +23,6 @@ if(CONFIG_HAS_MCUX OR CONFIG_HAS_IMX_HAL OR CONFIG_HAS_NXP_S32_HAL) if(CONFIG_NOCACHE_MEMORY) zephyr_compile_definitions_ifdef(CONFIG_USB_DEVICE_DRIVER DATA_SECTION_IS_CACHEABLE=1) endif() + + add_subdirectory_ifdef(CONFIG_BT_H4_NXP_CTLR bt_controller) endif() diff --git a/modules/hal_nxp/bt_controller/CMakeLists.txt b/modules/hal_nxp/bt_controller/CMakeLists.txt new file mode 100644 index 00000000000000..af3678364d30a0 --- /dev/null +++ b/modules/hal_nxp/bt_controller/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(hal_nxp_dir ${ZEPHYR_HAL_NXP_MODULE_DIR}) +set(hal_nxp_blobs_dir ${hal_nxp_dir}/zephyr/blobs) +set(blob_gen_file ${ZEPHYR_BINARY_DIR}/include/generated/bt_nxp_ctlr_fw.h) + +if(CONFIG_BT_NXP_NW612) + set(blob_file ${hal_nxp_blobs_dir}/iw612/uart_nw61x_se.h) +endif() + +if (NOT DEFINED blob_file) + message(FATAL_ERROR "Unsupported controller. Please select a BT conntroller, refer to ./driver/bluetooth/hci/Kconfig.nxp") +endif() + +zephyr_blobs_verify(FILES ${blob_file} REQUIRED) + +configure_file(${blob_file} ${blob_gen_file} COPYONLY) diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index b340c3882c8b7b..a7e3aa334bdfad 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -25,7 +25,6 @@ zephyr_library_compile_definitions( TLS_DEFAULT_CIPHERS=\""DEFAULT:!EXP:!LOW"\" CONFIG_SME CONFIG_NO_CONFIG_WRITE - CONFIG_NO_CONFIG_BLOBS CONFIG_CTRL_IFACE CONFIG_NO_RANDOM_POOL CONFIG_SHA256 @@ -76,10 +75,6 @@ zephyr_library_include_directories( ${ZEPHYR_BASE}/include/net ) -zephyr_library_compile_definitions_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO - CONFIG_NO_PBKDF2 -) - zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_NO_DEBUG CONFIG_NO_STDOUT_DEBUG ) @@ -225,17 +220,6 @@ zephyr_library_sources_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE ${HOSTAP_SRC_BASE}/rsn_supp/wpa.c ${HOSTAP_SRC_BASE}/rsn_supp/preauth.c ${HOSTAP_SRC_BASE}/rsn_supp/wpa_ie.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-bignum.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-ec.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls.c - ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c - ${HOSTAP_SRC_BASE}/crypto/aes-wrap.c - ${HOSTAP_SRC_BASE}/crypto/aes-unwrap.c - ${HOSTAP_SRC_BASE}/crypto/rc4.c - ${HOSTAP_SRC_BASE}/crypto/sha1-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha384-prf.c ) zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 @@ -243,7 +227,6 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 ${HOSTAP_SRC_BASE}/common/dragonfly.c ${HOSTAP_SRC_BASE}/crypto/dh_groups.c - ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 @@ -255,9 +238,6 @@ zephyr_library_include_directories_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_N ${CMAKE_SOURCE_DIR} ) -zephyr_library_link_libraries_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE - mbedTLS) - zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P ${WIFI_NM_WPA_SUPPLICANT_BASE}/p2p_supplicant.c ${WIFI_NM_WPA_SUPPLICANT_BASE}/p2p_supplicant_sd.c @@ -305,28 +285,10 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS EAP_WSC ) -zephyr_library_sources_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE - ${HOSTAP_SRC_BASE}/common/wpa_common.c - ${HOSTAP_SRC_BASE}/rsn_supp/wpa.c - ${HOSTAP_SRC_BASE}/rsn_supp/preauth.c - ${HOSTAP_SRC_BASE}/rsn_supp/wpa_ie.c - - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-bignum.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-ec.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls.c - ${HOSTAP_SRC_BASE}/crypto/aes-wrap.c - ${HOSTAP_SRC_BASE}/crypto/aes-unwrap.c - ${HOSTAP_SRC_BASE}/crypto/rc4.c - ${HOSTAP_SRC_BASE}/crypto/sha1-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha384-prf.c -) - zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c ${HOSTAP_SRC_BASE}/eap_peer/eap_tls.c ${HOSTAP_SRC_BASE}/eap_peer/eap_tls_common.c + ${HOSTAP_SRC_BASE}/eap_common/eap_common.c ${HOSTAP_SRC_BASE}/eap_peer/eap_peap.c ${HOSTAP_SRC_BASE}/eap_common/eap_peap_common.c @@ -364,17 +326,10 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE ${HOSTAP_SRC_BASE}/eap_common/eap_ikev2_common.c ${HOSTAP_SRC_BASE}/eap_common/ikev2_common.c - # common - ${HOSTAP_SRC_BASE}/crypto/sha384-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha1-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha1-tprf.c - ${HOSTAP_SRC_BASE}/crypto/ms_funcs.c - ${HOSTAP_SRC_BASE}/crypto/aes-eax.c - # MD4 removed from MbedTLS - ${HOSTAP_SRC_BASE}/crypto/md4-internal - ${HOSTAP_SRC_BASE}/crypto/aes-encblock.c + ${HOSTAP_SRC_BASE}/eap_peer/eap_sim.c + ${HOSTAP_SRC_BASE}/eap_common/eap_sim_common.c + ${HOSTAP_SRC_BASE}/eap_peer/eap_aka.c ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE @@ -410,4 +365,101 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_NW_SEL_RELIABILITY CONFIG_NW_SEL_RELIABILITY ) + +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP + ${WIFI_NM_WPA_SUPPLICANT_BASE}/dpp_supplicant.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/offchannel.c + ${WIFI_NM_WPA_SUPPLICANT_BASE}/gas_query.c + + ${HOSTAP_SRC_BASE}/ap/dpp_hostapd.c + ${HOSTAP_SRC_BASE}/ap/gas_query_ap.c + ${HOSTAP_SRC_BASE}/ap/gas_serv.c + + ${HOSTAP_SRC_BASE}/common/dpp_tcp.c + ${HOSTAP_SRC_BASE}/common/dpp.c + ${HOSTAP_SRC_BASE}/common/dpp_pkex.c + ${HOSTAP_SRC_BASE}/common/dpp_crypto.c + ${HOSTAP_SRC_BASE}/common/dpp_auth.c + ${HOSTAP_SRC_BASE}/common/dpp_reconfig.c + ${HOSTAP_SRC_BASE}/common/gas_server.c + ${HOSTAP_SRC_BASE}/common/gas.c + ${HOSTAP_SRC_BASE}/common/dpp_backup.c + + ${HOSTAP_SRC_BASE}/crypto/aes-siv.c + + ${HOSTAP_SRC_BASE}/utils/json.c + ${HOSTAP_SRC_BASE}/utils/ip_addr.c + + ${HOSTAP_SRC_BASE}/tls/asn1.c +) + +# crypto mbedtls related +if(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO) +zephyr_library_sources( + ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-bignum.c + ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-ec.c + ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls.c + ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c + ${HOSTAP_SRC_BASE}/crypto/aes-internal.c + ${HOSTAP_SRC_BASE}/crypto/aes-wrap.c + ${HOSTAP_SRC_BASE}/crypto/aes-unwrap.c + ${HOSTAP_SRC_BASE}/crypto/rc4.c + ${HOSTAP_SRC_BASE}/crypto/sha1-internal.c + ${HOSTAP_SRC_BASE}/crypto/sha1-prf.c + ${HOSTAP_SRC_BASE}/crypto/sha1-tlsprf.c + ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c + ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c + ${HOSTAP_SRC_BASE}/crypto/sha384-prf.c + ${HOSTAP_SRC_BASE}/crypto/sha384-kdf.c + ${HOSTAP_SRC_BASE}/crypto/sha512-internal.c + ${HOSTAP_SRC_BASE}/crypto/sha512.c + ${HOSTAP_SRC_BASE}/crypto/sha512-prf.c + ${HOSTAP_SRC_BASE}/crypto/sha512-kdf.c +) + +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 + ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c +) + +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + # common + ${HOSTAP_SRC_BASE}/crypto/sha384-tlsprf.c + ${HOSTAP_SRC_BASE}/crypto/sha256-tlsprf.c + ${HOSTAP_SRC_BASE}/crypto/sha1-tlsprf.c + ${HOSTAP_SRC_BASE}/crypto/sha1-tprf.c + ${HOSTAP_SRC_BASE}/crypto/ms_funcs.c + ${HOSTAP_SRC_BASE}/crypto/aes-eax.c + # MD4 removed from MbedTLS + ${HOSTAP_SRC_BASE}/crypto/md4-internal.c + ${HOSTAP_SRC_BASE}/crypto/aes-encblock.c +) +endif() + +if(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT) +zephyr_include_directories( + ${HOSTAP_BASE}/port/mbedtls +) + +zephyr_library_sources( + ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls_alt.c + ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls_alt.c + ${HOSTAP_SRC_BASE}/crypto/rc4.c +) + +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA + ${HOSTAP_BASE}/port/mbedtls/supp_psa_api.c +) + +zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + ${HOSTAP_SRC_BASE}/crypto/ms_funcs.c + ${HOSTAP_SRC_BASE}/crypto/aes-eax.c + ${HOSTAP_SRC_BASE}/crypto/md4-internal.c + ${HOSTAP_SRC_BASE}/crypto/fips_prf_internal.c + ${HOSTAP_SRC_BASE}/crypto/milenage.c +) +endif() + +zephyr_library_link_libraries_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE + mbedTLS) + endif() diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 490e70c0c7d674..f90ab2c0b8833c 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -7,8 +7,8 @@ config WIFI_NM_WPA_SUPPLICANT bool "WPA Suplicant from hostap project [EXPERIMENTAL]" - select POSIX_CLOCK - select POSIX_SIGNAL + select POSIX_TIMERS + select POSIX_SIGNALS select POSIX_API select NET_SOCKETS select NET_SOCKETS_PACKET @@ -41,7 +41,7 @@ config WIFI_NM_WPA_SUPPLICANT_WQ_PRIO int "Thread priority of wpa_supplicant iface workqueue" default 7 -# Currently we default POSIX_MAX_FDS to 16 in lib/posix/Kconfig +# Currently we default ZVFS_OPEN_MAX to 16 in lib/posix/Kconfig # l2_packet - 1 # ctrl_iface - 2 * socketpairs = 4(local and global) # z_wpa_event_sock - 1 socketpair = 2 @@ -106,6 +106,8 @@ choice WIFI_NM_WPA_SUPPLICANT_CRYPTO_BACKEND default WIFI_NM_WPA_SUPPLICANT_CRYPTO help Select the crypto implementation to use for WPA supplicant. + WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT support enterprise + and DPP. And use Mbedtls PSA apis for HW acceleration. config WIFI_NM_WPA_SUPPLICANT_CRYPTO bool "Crypto support for WiFi" @@ -125,11 +127,37 @@ config WIFI_NM_WPA_SUPPLICANT_CRYPTO select MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED select MBEDTLS_KEY_EXCHANGE_ALL_ENABLED +config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT + bool "Crypto Mbedtls alt support for WiFi" + select MBEDTLS + select MBEDTLS_CIPHER_MODE_CTR_ENABLED + select MBEDTLS_CIPHER_MODE_CBC_ENABLED + select MBEDTLS_ECP_C + select MBEDTLS_ECP_ALL_ENABLED + select MBEDTLS_CMAC + select MBEDTLS_PKCS5_C + select MBEDTLS_PK_WRITE_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECDSA_C + select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + select MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + select MBEDTLS_NIST_KW_C + select MBEDTLS_DHM_C + select MBEDTLS_HKDF_C + select MBEDTLS_SERVER_NAME_INDICATION + select MBEDTLS_X509_CRL_PARSE_C + config WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE bool "No Crypto support for WiFi" endchoice +config WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA + bool "Crypto Platform Secure Architecture support for WiFi" + default y if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT + help + Support Mbedtls 3.x to use PSA apis instead of legacy apis. + config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE bool "Enterprise Crypto support for WiFi" depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE @@ -174,6 +202,18 @@ config WIFI_NM_WPA_SUPPLICANT_BSS_MAX_IDLE_TIME config WIFI_NM_WPA_SUPPLICANT_NO_DEBUG bool "Disable printing of debug messages, saves code size significantly" + +config WIFI_NM_WPA_SUPPLICANT_DPP + bool "WFA Easy Connect DPP" + select DPP + select DPP2 + select DPP3 + select GAS + select GAS_SERVER + select OFFCHANNEL + select MBEDTLS_X509_CSR_WRITE_C + select MBEDTLS_X509_CSR_PARSE_C + # Create hidden config options that are used in hostap. This way we do not need # to mark them as allowed for CI checks, and also someone else cannot use the # same name options. @@ -188,7 +228,7 @@ config NO_CONFIG_WRITE config NO_CONFIG_BLOBS bool - default y + default y if !WIFI_NM_WPA_SUPPLICANT_DPP && !WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE config CTRL_IFACE bool @@ -211,7 +251,7 @@ config NO_WPA config NO_PBKDF2 bool - default y + default y if WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE config SAE_PK bool @@ -254,6 +294,9 @@ config P2P config GAS bool +config GAS_SERVER + bool + config OFFCHANNEL bool @@ -358,6 +401,15 @@ config RRM config WMM_AC bool +config DPP + bool + +config DPP2 + bool + +config DPP3 + bool + config NW_SEL_RELIABILITY bool default y diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 69a4dd8438b11c..80d90c70fb6d89 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(wifi_supplicant, CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL); #if !defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE) && !defined(CONFIG_MBEDTLS_ENABLE_HEAP) #include #endif /* !CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE && !CONFIG_MBEDTLS_ENABLE_HEAP */ +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA +#include "supp_psa_api.h" +#endif #include #include @@ -523,6 +526,10 @@ static void handler(void) mbedtls_platform_set_calloc_free(calloc, free); #endif /* !CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE && !CONFIG_MBEDTLS_ENABLE_HEAP */ +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA + supp_psa_crypto_init(); +#endif + ctx = get_default_context(); k_work_queue_init(&ctx->iface_wq); diff --git a/modules/loramac-node/CMakeLists.txt b/modules/loramac-node/CMakeLists.txt index 9e0bdbc98771ce..a711ab3e5fe94d 100644 --- a/modules/loramac-node/CMakeLists.txt +++ b/modules/loramac-node/CMakeLists.txt @@ -55,7 +55,7 @@ zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_LORAMAC ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/LoRaMacSerializer.c ) -zephyr_library_sources_ifdef(CONFIG_LORAWAN_FRAG_TRANSPORT +zephyr_library_sources_ifdef(CONFIG_LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/apps/LoRaMac/common/LmHandler/packages/FragDecoder.c ) diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c index b68ca67b87149e..e87352799f29cc 100644 --- a/modules/lvgl/input/lvgl_encoder_input.c +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -28,6 +28,8 @@ static void lvgl_encoder_process_event(const struct device *dev, struct input_ev data->pending_event.enc_diff = evt->value; } else if (evt->code == cfg->button_input_code) { data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->pending_event.enc_diff = 0; + data->pending_event.key = LV_KEY_ENTER; } else { LOG_DBG("Ignored input event: %u", evt->code); return; diff --git a/modules/lvgl/lvgl_fs.c b/modules/lvgl/lvgl_fs.c index a05e21748d41a3..63a902ea9572de 100644 --- a/modules/lvgl/lvgl_fs.c +++ b/modules/lvgl/lvgl_fs.c @@ -88,6 +88,7 @@ static lv_fs_res_t lvgl_fs_close(struct _lv_fs_drv_t *drv, void *file) int err; err = fs_close((struct fs_file_t *)file); + LV_MEM_CUSTOM_FREE(file); return errno_to_lv_fs_res(err); } diff --git a/modules/mbedtls/CMakeLists.txt b/modules/mbedtls/CMakeLists.txt index 3ea8a84d3b027d..ae4d0e1f3b2b5e 100644 --- a/modules/mbedtls/CMakeLists.txt +++ b/modules/mbedtls/CMakeLists.txt @@ -29,6 +29,12 @@ zephyr_interface_library_named(mbedTLS) include ) + if (CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW) + target_include_directories(mbedTLS INTERFACE + ${ZEPHYR_CURRENT_MODULE_DIR}/3rdparty/p256-m/p256-m + ) + endif() + # Add base library with files required by all drivers/backends. zephyr_library_named(mbedTLSBase) @@ -134,6 +140,14 @@ zephyr_interface_library_named(mbedTLS) ) endif() + if(CONFIG_MBEDTLS_PSA_P256M_DRIVER_ENABLED) + list(APPEND crypto_source + ${ZEPHYR_CURRENT_MODULE_DIR}/3rdparty/p256-m/p256-m_driver_entrypoints.c + ${ZEPHYR_CURRENT_MODULE_DIR}/3rdparty/p256-m/p256-m/p256-m.c + ) + zephyr_library_include_directories(${ZEPHYR_CURRENT_MODULE_DIR}/library) + endif() + list(APPEND crypto_source ${ZEPHYR_CURRENT_MODULE_DIR}/library/pem.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/pkcs12.c diff --git a/modules/mbedtls/Kconfig.tls-generic b/modules/mbedtls/Kconfig.tls-generic index 3cf98bdd3278cb..f4fe0db1c41146 100644 --- a/modules/mbedtls/Kconfig.tls-generic +++ b/modules/mbedtls/Kconfig.tls-generic @@ -93,6 +93,9 @@ config MBEDTLS_KEY_EXCHANGE_RSA_ENABLED bool "RSA-only based ciphersuite modes" default y if UOSCORE || UEDHOC select MBEDTLS_MD + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY if PSA_CRYPTO_CLIENT + select PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC if PSA_CRYPTO_CLIENT + select PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT if PSA_CRYPTO_CLIENT config MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED bool "DHE-RSA based ciphersuite modes" @@ -215,9 +218,7 @@ config MBEDTLS_CIPHER_ALL_ENABLED select MBEDTLS_CIPHER_AES_ENABLED select MBEDTLS_CIPHER_CAMELLIA_ENABLED select MBEDTLS_CIPHER_DES_ENABLED - select MBEDTLS_CIPHER_ARC4_ENABLED select MBEDTLS_CIPHER_CHACHA20_ENABLED - select MBEDTLS_CIPHER_BLOWFISH_ENABLED select MBEDTLS_CIPHER_CCM_ENABLED select MBEDTLS_CIPHER_GCM_ENABLED select MBEDTLS_CIPHER_MODE_XTS_ENABLED @@ -269,15 +270,9 @@ config MBEDTLS_CIPHER_CAMELLIA_ENABLED config MBEDTLS_CIPHER_DES_ENABLED bool "DES block cipher" -config MBEDTLS_CIPHER_ARC4_ENABLED - bool "ARC4 stream cipher" - config MBEDTLS_CIPHER_CHACHA20_ENABLED bool "ChaCha20 stream cipher" -config MBEDTLS_CIPHER_BLOWFISH_ENABLED - bool "Blowfish block cipher" - if MBEDTLS_SOME_AEAD_CIPHER_ENABLED config MBEDTLS_CIPHER_CCM_ENABLED @@ -312,7 +307,6 @@ comment "Supported hash algorithms" config MBEDTLS_HASH_ALL_ENABLED bool "All available MAC methods" - select MBEDTLS_MD4 select MBEDTLS_MD5 select MBEDTLS_SHA1 select MBEDTLS_SHA224 @@ -321,9 +315,6 @@ config MBEDTLS_HASH_ALL_ENABLED select MBEDTLS_SHA512 select MBEDTLS_POLY1305 -config MBEDTLS_MD4 - bool "MD4 hash algorithm" - config MBEDTLS_MD5 bool "MD5 hash algorithm" @@ -514,6 +505,24 @@ config MBEDTLS_LMS depends on MBEDTLS_SHA256 select PSA_WANT_ALG_SHA_256 +config MBEDTLS_PSA_P256M_DRIVER_ENABLED + bool "P256-M driver" + depends on MBEDTLS_PSA_CRYPTO_C + imply PSA_WANT_ALG_SHA_256 + help + Enable support for the optimized sofware implementation of the secp256r1 + curve through the standard PSA API interface. + +config MBEDTLS_PSA_P256M_DRIVER_RAW + bool "Access p256-m driver directly (without PSA interface)" + select MBEDTLS_PSA_P256M_DRIVER_ENABLED + help + Allow access to p256-m driver directly without using the PSA interface. + Warning: usage of this kconfig is prohibited in Zephyr's code base. Users + can make optionally enable it in case very memory constrained + devices, but please be aware that the p256-m interface is + absolutely not guaranted to remain stable over time. + config MBEDTLS_SSL_DTLS_CONNECTION_ID bool "DTLS Connection ID extension" depends on MBEDTLS_DTLS @@ -522,4 +531,32 @@ config MBEDTLS_SSL_DTLS_CONNECTION_ID which allows to identify DTLS connections across changes in the underlying transport. + +config MBEDTLS_NIST_KW_C + bool "NIST key wrap" + depends on MBEDTLS_CIPHER_AES_ENABLED + help + Key Wrapping mode for 128-bit block ciphers, + as defined in NIST SP 800-38F. + +config MBEDTLS_DHM_C + bool "Diffie-Hellman-Merkle mode" + help + Used by the following key exchanges, + DHE-RSA, DHE-PSK + +config MBEDTLS_X509_CRL_PARSE_C + bool "X509 CRL parsing" + help + Used by X509 CRL parsing + +config MBEDTLS_X509_CSR_WRITE_C + bool "X509 Certificate Signing Requests writing" + help + For X.509 certificate request writing. + +config MBEDTLS_X509_CSR_PARSE_C + bool "X509 Certificate Signing Request parsing" + help + For reading X.509 certificate request. endmenu diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index 8c19e30e5c0727..d76b425a569ae6 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -163,18 +163,10 @@ #define MBEDTLS_DES_C #endif -#if defined(CONFIG_MBEDTLS_CIPHER_ARC4_ENABLED) -#define MBEDTLS_ARC4_C -#endif - #if defined(CONFIG_MBEDTLS_CIPHER_CHACHA20_ENABLED) #define MBEDTLS_CHACHA20_C #endif -#if defined(CONFIG_MBEDTLS_CIPHER_BLOWFISH_ENABLED) -#define MBEDTLS_BLOWFISH_C -#endif - #if defined(CONFIG_MBEDTLS_CIPHER_CCM_ENABLED) #define MBEDTLS_CCM_C #endif @@ -273,10 +265,6 @@ /* Supported hash algorithms */ -#if defined(CONFIG_MBEDTLS_MD4) -#define MBEDTLS_MD4_C -#endif - #if defined(CONFIG_MBEDTLS_MD5) #define MBEDTLS_MD5_C #endif @@ -469,6 +457,10 @@ #define MBEDTLS_PSA_CRYPTO_C #define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS +#if defined(CONFIG_MBEDTLS_PSA_P256M_DRIVER_ENABLED) +#define MBEDTLS_PSA_P256M_DRIVER_ENABLED +#endif + #if defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_PICOLIBC) #define MBEDTLS_PSA_KEY_SLOT_COUNT 64 #define MBEDTLS_PSA_CRYPTO_STORAGE_C @@ -497,6 +489,27 @@ #define MBEDTLS_SSL_DTLS_CONNECTION_ID #endif +#if defined(CONFIG_MBEDTLS_NIST_KW_C) +#define MBEDTLS_NIST_KW_C +#endif + +#if defined(CONFIG_MBEDTLS_DHM_C) +#define MBEDTLS_DHM_C +#endif + +#if defined(CONFIG_MBEDTLS_X509_CRL_PARSE_C) +#define MBEDTLS_X509_CRL_PARSE_C +#endif + +#if defined(CONFIG_MBEDTLS_X509_CSR_WRITE_C) +#define MBEDTLS_X509_CSR_WRITE_C +#define MBEDTLS_X509_CREATE_C +#endif + +#if defined(CONFIG_MBEDTLS_X509_CSR_PARSE_C) +#define MBEDTLS_X509_CSR_PARSE_C +#endif + #if defined(CONFIG_MBEDTLS_USER_CONFIG_FILE) #include CONFIG_MBEDTLS_USER_CONFIG_FILE #endif diff --git a/modules/mbedtls/zephyr_init.c b/modules/mbedtls/zephyr_init.c index 78602e497e3899..bfdc83863463c4 100644 --- a/modules/mbedtls/zephyr_init.c +++ b/modules/mbedtls/zephyr_init.c @@ -94,6 +94,12 @@ static int _mbedtls_init(void) mbedtls_debug_set_threshold(CONFIG_MBEDTLS_DEBUG_LEVEL); #endif +#if defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) + if (psa_crypto_init() != PSA_SUCCESS) { + return -EIO; + } +#endif + return 0; } diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index c638d3394f4cb8..c155fab65f9862 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -44,11 +44,13 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING OT_BACKBON 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_AGENT_EPHEMERAL_KEY_ENABLE OT_BORDER_AGENT_EPSKC "Border agent ephemeral PSKc") 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_MANAGER_CSL OT_CHANNEL_MANAGER_CSL "Channel manager for CSL channel") 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") @@ -83,8 +85,10 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_LEGACY OT_LEGACY "Enable legacy network s 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_PLATFORM_LOG_CRASH_DUMP OT_PLATFORM_LOG_CRASH_DUMP "Platform log crash dump") 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_MULTICAST_DNS OT_MDNS "multicast DNS (mDNS)") 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)") @@ -119,6 +123,7 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_TX_BEACON_PAYLOAD OT_TX_BEACON_PAYLOAD "E 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") +kconfig_to_ot_option(CONFIG_OPENTHREAD_VERHOEFF_CHECKSUM OT_VERHOEFF_CHECKSUM "Verhoeff checksum") 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) diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 7fd9ed5080207b..32f451ca38ead0 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -46,6 +46,9 @@ config OPENTHREAD_BLE_TCAT config OPENTHREAD_BORDER_AGENT bool "Border Agent support" +config OPENTHREAD_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + bool "Border agent ephemeral PSKc" + config OPENTHREAD_BORDER_ROUTER bool "Border Router support" @@ -65,6 +68,9 @@ config OPENTHREAD_CHANNEL_MANAGER bool "Channel manager support" depends on OPENTHREAD_CHANNEL_MONITOR +config OPENTHREAD_CHANNEL_MANAGER_CSL + bool "Channel manager for CSL channel" + config OPENTHREAD_COAP bool "OpenThread CoAP support" help @@ -192,12 +198,18 @@ config OPENTHREAD_LINK_METRICS_MANAGER config OPENTHREAD_LINK_METRICS_SUBJECT bool "Link Metrics subject" +config OPENTHREAD_PLATFORM_LOG_CRASH_DUMP + bool "Platform log crash dump" + config OPENTHREAD_LOG_LEVEL_DYNAMIC bool "Dynamic log level control" config OPENTHREAD_MAC_FILTER bool "MAC filter support" +config OPENTHREAD_MULTICAST_DNS + bool "Multicast DNS (mDNS)" + config OPENTHREAD_MESH_DIAG bool "Mesh Diagnostics" depends on OPENTHREAD_FTD @@ -359,3 +371,6 @@ config OPENTHREAD_UDP_FORWARD config OPENTHREAD_UPTIME bool "Openthread uptime counter" default y if OPENTHREAD_FTD + +config OPENTHREAD_VERHOEFF_CHECKSUM + bool "Verhoeff checksum" diff --git a/modules/openthread/platform/ble.c b/modules/openthread/platform/ble.c index 7b41556b6173a1..55330e1ffe769c 100644 --- a/modules/openthread/platform/ble.c +++ b/modules/openthread/platform/ble.c @@ -23,7 +23,9 @@ #include /* OpenThread BLE driver API */ +#include #include +#include /* Zephyr Logging */ @@ -100,13 +102,17 @@ static struct bt_conn_cb conn_callbacks = {.connected = connected, .le_param_req = le_param_req, .le_param_updated = le_param_updated}; -static const struct bt_data ad[] = { +static uint8_t service_data[OT_TCAT_ADVERTISEMENT_MAX_LEN] = {0}; +static const uint8_t service_data_size = ARRAY_SIZE(service_data); + +static 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), + BT_DATA(BT_DATA_SVC_DATA16, service_data, service_data_size), }; -static const struct bt_data sd[] = { +static struct bt_data sd[] = { BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(TOBLE_SERVICE_UUID)), + BT_DATA(BT_DATA_SVC_DATA16, service_data, service_data_size), }; /* Zephyr BLE Message Queue and Thread */ @@ -388,12 +394,52 @@ static void bt_ready(int err) k_sem_give(&ot_plat_ble_init_semaphore); /* BLE stack up an running */ } +void otPlatBleGetLinkCapabilities(otInstance *aInstance, + otBleLinkCapabilities *aBleLinkCapabilities) +{ + ARG_UNUSED(aInstance); + + aBleLinkCapabilities->mGattNotifications = 1; + aBleLinkCapabilities->mL2CapDirect = 0; + aBleLinkCapabilities->mRsv = 0; +} + +bool otPlatBleSupportsMultiRadio(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return false; +} + +otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer) +{ + ARG_UNUSED(aInstance); + + *aAdvertisementBuffer = service_data; + + return OT_ERROR_NONE; +} + +otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, + uint16_t aAdvertisementLen) +{ + ARG_UNUSED(aInstance); + + if (aAdvertisementLen > OT_TCAT_ADVERTISEMENT_MAX_LEN || aAdvertisementData == NULL) { + LOG_ERR("Invalid TCAT Advertisement parameters advlen: %d", aAdvertisementLen); + return OT_ERROR_INVALID_ARGS; + } + + ad[1].data_len = (uint8_t)aAdvertisementLen; + sd[1].data_len = (uint8_t)aAdvertisementLen; + return OT_ERROR_NONE; +} + 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) { diff --git a/modules/thrift/CMakeLists.txt b/modules/thrift/CMakeLists.txt index 468286c03e6c1d..d26b6ef9c3ee43 100644 --- a/modules/thrift/CMakeLists.txt +++ b/modules/thrift/CMakeLists.txt @@ -12,7 +12,6 @@ zephyr_include_directories(include) zephyr_include_directories(${THRIFT_UPSTREAM}/lib/cpp/src) zephyr_library_sources( - src/_stat.c src/thrift/server/TFDServer.cpp ${THRIFT_UPSTREAM}/lib/cpp/src/thrift/protocol/TProtocol.cpp ${THRIFT_UPSTREAM}/lib/cpp/src/thrift/server/TConnectedClient.cpp diff --git a/modules/thrift/src/_stat.c b/modules/thrift/src/_stat.c deleted file mode 100644 index 688e1a53ceffbc..00000000000000 --- a/modules/thrift/src/_stat.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022 Meta - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include - -int stat(const char *restrict path, struct stat *restrict buf) -{ - ARG_UNUSED(path); - ARG_UNUSED(buf); - - errno = ENOTSUP; - - return -1; -} diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 5e8511947cfff2..b90390f3d043e7 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -33,7 +33,6 @@ menuconfig BUILD_WITH_TFM imply INIT_ARCH_HW_AT_BOOT imply ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS imply MBEDTLS - imply PSA_CRYPTO_ENABLE_ALL help When enabled, this option instructs the Zephyr build process to additionally generate a TF-M image for the Secure Execution diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h745i_disco_m7.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h745i_disco_m7.conf new file mode 100644 index 00000000000000..eac2504a7850e5 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h745i_disco_m7.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco_m7.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco_m7.conf new file mode 100644 index 00000000000000..eac2504a7850e5 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h747i_disco_m7.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf b/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf new file mode 100644 index 00000000000000..eac2504a7850e5 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/stm32h750b_dk.conf @@ -0,0 +1,2 @@ +CONFIG_FLASH=y +CONFIG_STM32_MEMMAP=y diff --git a/samples/application_development/code_relocation_nocopy/sample.yaml b/samples/application_development/code_relocation_nocopy/sample.yaml index b653213fa4d6e9..79c6bb65c5f659 100644 --- a/samples/application_development/code_relocation_nocopy/sample.yaml +++ b/samples/application_development/code_relocation_nocopy/sample.yaml @@ -9,6 +9,9 @@ tests: - stm32f769i_disco - stm32h7b3i_dk - b_u585i_iot02a + - stm32h745i_disco/stm32h745xx/m7 + - stm32h750b_dk + - stm32f746g_disco integration_platforms: - qemu_cortex_m3 tags: linker diff --git a/samples/basic/blinky_pwm/boards/beagleconnect_freedom.overlay b/samples/basic/blinky_pwm/boards/beagleconnect_freedom.overlay new file mode 100644 index 00000000000000..a2aeeeefee29fc --- /dev/null +++ b/samples/basic/blinky_pwm/boards/beagleconnect_freedom.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Ayush Singh + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-led0 = &pwm_led0; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 255 PWM_POLARITY_NORMAL>; + label = "PWM MB1"; + }; + }; +}; + +&pinctrl { + pwm0_default: pwm0_default { + pinmux = <17 IOC_PORT_MCU_PORT_EVENT1>; + bias-disable; + drive-strength = <8>; + }; +}; + +&gpt0 { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-names = "default"; +}; diff --git a/samples/basic/blinky_pwm/boards/xiao_rp2040.overlay b/samples/basic/blinky_pwm/boards/xiao_rp2040.overlay new file mode 100644 index 00000000000000..43e054ede94f13 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/xiao_rp2040.overlay @@ -0,0 +1,13 @@ +&{/pwm_leds} { + status = "okay"; +}; + +&pwm_led0 { + status = "okay"; +}; + +&pwm { + status = "okay"; + divider-frac-4 = <15>; + divider-int-4 = <255>; +}; diff --git a/samples/basic/blinky_pwm/sample.yaml b/samples/basic/blinky_pwm/sample.yaml index de2cb234933c2d..d2087f73347f39 100644 --- a/samples/basic/blinky_pwm/sample.yaml +++ b/samples/basic/blinky_pwm/sample.yaml @@ -7,4 +7,13 @@ tests: - drivers - pwm depends_on: pwm - harness: led + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "PWM-based blinky" + - "Calibrating for channel [0-9]+" + - "Done calibrating; maximum/minimum periods [0-9]+/[0-9]+ nsec" + - "Using period [0-9]+" + - "Using period [0-9]+" diff --git a/samples/basic/blinky_pwm/src/main.c b/samples/basic/blinky_pwm/src/main.c index de1f6409c6d293..6539c05d5ccae1 100644 --- a/samples/basic/blinky_pwm/src/main.c +++ b/samples/basic/blinky_pwm/src/main.c @@ -63,6 +63,7 @@ int main(void) printk("Error %d: failed to set pulse width\n", ret); return 0; } + printk("Using period %d\n", period); period = dir ? (period * 2U) : (period / 2U); if (period > max_period) { diff --git a/samples/basic/fade_led/boards/xiao_rp2040.overlay b/samples/basic/fade_led/boards/xiao_rp2040.overlay new file mode 100644 index 00000000000000..62c3a142cd4a63 --- /dev/null +++ b/samples/basic/fade_led/boards/xiao_rp2040.overlay @@ -0,0 +1,4 @@ +&pwm { + status = "okay"; + divider-int-4 = <255>; +}; diff --git a/samples/basic/fade_led/sample.yaml b/samples/basic/fade_led/sample.yaml index eae1afefe5b483..603c5721471911 100644 --- a/samples/basic/fade_led/sample.yaml +++ b/samples/basic/fade_led/sample.yaml @@ -6,7 +6,14 @@ tests: - drivers - pwm depends_on: pwm - harness: led filter: dt_alias_exists("pwm-led0") and dt_compat_enabled("pwm-leds") integration_platforms: - nrf51dk/nrf51822 + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "PWM-based LED fade" + - "Using pulse width [0-9]+%" + - "Using pulse width [0-9]+%" diff --git a/samples/basic/fade_led/src/main.c b/samples/basic/fade_led/src/main.c index ab7b2aca0328f2..c6a49a13a12221 100644 --- a/samples/basic/fade_led/src/main.c +++ b/samples/basic/fade_led/src/main.c @@ -40,6 +40,7 @@ int main(void) printk("Error %d: failed to set pulse width\n", ret); return 0; } + printk("Using pulse width %d%%\n", 100 * pulse_width / pwm_led0.period); if (dir) { pulse_width += step; diff --git a/samples/bluetooth/bap_broadcast_sink/src/main.c b/samples/bluetooth/bap_broadcast_sink/src/main.c index b08c4f96c9afb3..4a2b6ca95696bb 100644 --- a/samples/bluetooth/bap_broadcast_sink/src/main.c +++ b/samples/bluetooth/bap_broadcast_sink/src/main.c @@ -38,7 +38,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD), #endif /* CONFIG_SCAN_SELF */ #define INVALID_BROADCAST_ID (BT_AUDIO_BROADCAST_ID_MAX + 1) -#define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */ +#define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 5 /* Set the timeout relative to interval */ #define PA_SYNC_SKIP 5 #define NAME_LEN sizeof(CONFIG_TARGET_BROADCAST_NAME) + 1 #define BROADCAST_DATA_ELEMENT_SIZE sizeof(int16_t) @@ -345,7 +345,7 @@ static int lc3_enable(struct broadcast_sink_stream *sink_stream) } ret = bt_audio_codec_cfg_get_chan_allocation(sink_stream->stream.codec_cfg, - &sink_stream->chan_allocation); + &sink_stream->chan_allocation, true); if (ret != 0) { printk("Error: Channel allocation not set, invalid configuration for LC3"); return ret; @@ -622,18 +622,11 @@ static bool find_valid_bis_cb(const struct bt_bap_base_subgroup_bis *bis, return true; } - err = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation); + err = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation, true); if (err != 0) { printk("Could not find channel allocation for BIS: %d\n", err); - /* Absence of channel allocation is implicitly mono as per the BAP spec */ - if (CONFIG_TARGET_BROADCAST_CHANNEL == BT_AUDIO_LOCATION_MONO_AUDIO) { - data->bis[0].index = bis->index; - data->bis[0].chan_allocation = chan_allocation; - data->cnt = 1; - - return false; - } else if (err == -ENODATA && strlen(CONFIG_TARGET_BROADCAST_NAME) > 0U) { + if (err == -ENODATA && strlen(CONFIG_TARGET_BROADCAST_NAME) > 0U) { /* Accept no channel allocation data available * if TARGET_BROADCAST_NAME defined. Use current index. */ @@ -742,7 +735,7 @@ static bool find_valid_bis_in_subgroup_cb(const struct bt_bap_base_subgroup *sub return true; } - err = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation); + err = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation, false); if (err != 0) { printk("Could not find subgroup channel allocation: %d - Looking in the BISes\n", err); @@ -1248,10 +1241,32 @@ static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, const struct bt_le_per_adv_sync_term_info *info) { if (sync == pa_sync) { - printk("PA sync %p lost with reason %u\n", sync, info->reason); + printk("PA sync %p lost with reason 0x%02X\n", sync, info->reason); pa_sync = NULL; k_sem_give(&sem_pa_sync_lost); + + if (info->reason != BT_HCI_ERR_LOCALHOST_TERM_CONN && req_recv_state != NULL) { + int err; + + if (k_sem_count_get(&sem_stream_connected) > 0) { + err = bt_bap_broadcast_sink_stop(broadcast_sink); + if (err != 0) { + printk("Failed to stop Broadcast Sink: %d\n", err); + + return; + } + } + + err = bt_bap_scan_delegator_rem_src(req_recv_state->src_id); + if (err != 0) { + printk("Failed to remove source: %d\n", err); + + return; + } + + k_sem_give(&sem_broadcast_sink_stopped); + } } } @@ -1634,7 +1649,7 @@ int main(void) printk("Waiting for PA disconnected\n"); k_sem_take(&sem_pa_sync_lost, K_FOREVER); - printk("Wainting for sink to stop\n"); + printk("Waiting for sink to stop\n"); err = k_sem_take(&sem_broadcast_sink_stopped, SEM_TIMEOUT); if (err != 0) { printk("sem_broadcast_sink_stopped timed out, resetting\n"); diff --git a/samples/bluetooth/bap_unicast_client/CMakeLists.txt b/samples/bluetooth/bap_unicast_client/CMakeLists.txt index 4d9f15c0a60618..125a189a61b14c 100644 --- a/samples/bluetooth/bap_unicast_client/CMakeLists.txt +++ b/samples/bluetooth/bap_unicast_client/CMakeLists.txt @@ -8,4 +8,7 @@ target_sources(app PRIVATE src/main.c ) +zephyr_sources_ifdef(CONFIG_LIBLC3 src/stream_lc3.c) +zephyr_sources_ifdef(CONFIG_BT_AUDIO_TX src/stream_tx.c) + zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) diff --git a/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 76df8dba27a4f4..f28300b84c50e9 100644 --- a/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,9 +1,9 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence -# inctease stack size for that thread. -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +# The LC3 codec uses a large amount of stack. This app runs the decoding codec in the RX thread, +# hence increase the stack size for that thread. +CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/bap_unicast_client/src/main.c b/samples/bluetooth/bap_unicast_client/src/main.c index 96b36094b6ccd4..cc8e5d7d6d8f3e 100644 --- a/samples/bluetooth/bap_unicast_client/src/main.c +++ b/samples/bluetooth/bap_unicast_client/src/main.c @@ -4,18 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include -#include -#include -#include -#include #include #include #include +#include +#include +#include #include +#include +#include +#include + +#include "stream_tx.h" static void start_scan(void); @@ -23,16 +26,12 @@ uint64_t unicast_audio_recv_ctr; /* This value is exposed to test code */ static struct bt_bap_unicast_client_cb unicast_client_cbs; static struct bt_conn *default_conn; -static struct k_work_delayable audio_send_work; static struct bt_bap_unicast_group *unicast_group; static struct audio_sink { struct bt_bap_ep *ep; uint16_t seq_num; } sinks[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT]; static struct bt_bap_ep *sources[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT]; -NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT, - BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), - CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); static struct bt_bap_stream streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT + CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT]; @@ -61,302 +60,6 @@ static K_SEM_DEFINE(sem_stream_enabled, 0, 1); static K_SEM_DEFINE(sem_stream_started, 0, 1); static K_SEM_DEFINE(sem_stream_connected, 0, 1); -#define AUDIO_DATA_TIMEOUT_US 1000000UL /* Send data every 1 second */ - -static uint16_t get_and_incr_seq_num(const struct bt_bap_stream *stream) -{ - for (size_t i = 0U; i < configured_sink_stream_count; i++) { - if (stream->ep == sinks[i].ep) { - uint16_t seq_num; - - seq_num = sinks[i].seq_num; - - if (IS_ENABLED(CONFIG_LIBLC3)) { - sinks[i].seq_num++; - } else { - sinks[i].seq_num += (AUDIO_DATA_TIMEOUT_US / - codec_configuration.qos.interval); - } - - return seq_num; - } - } - - printk("Could not find endpoint from stream %p\n", stream); - - return 0; -} - -#if defined(CONFIG_LIBLC3) - -#include "lc3.h" -#include "math.h" - -#define MAX_SAMPLE_RATE 48000 -#define MAX_FRAME_DURATION_US 10000 -#define MAX_NUM_SAMPLES ((MAX_FRAME_DURATION_US * MAX_SAMPLE_RATE) / USEC_PER_SEC) -#define AUDIO_VOLUME (INT16_MAX - 3000) /* codec does clipping above INT16_MAX - 3000 */ -#define AUDIO_TONE_FREQUENCY_HZ 400 - -static int16_t audio_buf[MAX_NUM_SAMPLES]; -static lc3_encoder_t lc3_encoder; -static lc3_encoder_mem_48k_t lc3_encoder_mem; -static int freq_hz; -static int frame_duration_us; -static int frame_duration_100us; -static int frames_per_sdu; -static int octets_per_frame; - -/** - * Use the math lib to generate a sine-wave using 16 bit samples into a buffer. - * - * @param buf Destination buffer - * @param length_us Length of the buffer in microseconds - * @param frequency_hz frequency in Hz - * @param sample_rate_hz sample-rate in Hz. - */ -static void fill_audio_buf_sin(int16_t *buf, int length_us, int frequency_hz, int sample_rate_hz) -{ - const int sine_period_samples = sample_rate_hz / frequency_hz; - const unsigned int num_samples = (length_us * sample_rate_hz) / USEC_PER_SEC; - const float step = 2 * 3.1415f / sine_period_samples; - - for (unsigned int i = 0; i < num_samples; i++) { - const float sample = sinf(i * step); - - buf[i] = (int16_t)(AUDIO_VOLUME * sample); - } -} - -static void lc3_audio_timer_timeout(struct k_work *work) -{ - /* For the first call-back we push multiple audio frames to the buffer to use the - * controller ISO buffer to handle jitter. - */ - const uint8_t prime_count = 2; - static int64_t start_time; - static int32_t sdu_cnt; - int32_t sdu_goal_cnt; - int64_t uptime, run_time_ms, run_time_100us; - - k_work_schedule(&audio_send_work, K_USEC(codec_configuration.qos.interval)); - - if (lc3_encoder == NULL) { - printk("LC3 encoder not setup, cannot encode data.\n"); - return; - } - - if (start_time == 0) { - /* Read start time and produce the number of frames needed to catch up with any - * inaccuracies in the timer. by calculating the number of frames we should - * have sent and compare to how many were actually sent. - */ - start_time = k_uptime_get(); - } - - uptime = k_uptime_get(); - run_time_ms = uptime - start_time; - - /* PDU count calculations done in 100us units to allow 7.5ms framelength in fixed-point */ - run_time_100us = run_time_ms * 10; - sdu_goal_cnt = run_time_100us / (frame_duration_100us * frames_per_sdu); - - /* Add primer value to ensure the controller do not run low on data due to jitter */ - sdu_goal_cnt += prime_count; - - printk("LC3 encode %d frames in %d SDUs\n", (sdu_goal_cnt - sdu_cnt) * frames_per_sdu, - (sdu_goal_cnt - sdu_cnt)); - - while (sdu_cnt < sdu_goal_cnt) { - const uint16_t tx_sdu_len = frames_per_sdu * octets_per_frame; - struct net_buf *buf; - uint8_t *net_buffer; - off_t offset = 0; - - buf = net_buf_alloc(&tx_pool, K_FOREVER); - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - - net_buffer = net_buf_tail(buf); - buf->len += tx_sdu_len; - - for (int i = 0; i < frames_per_sdu; i++) { - int lc3_ret; - - lc3_ret = lc3_encode(lc3_encoder, LC3_PCM_FORMAT_S16, - audio_buf, 1, octets_per_frame, - net_buffer + offset); - offset += octets_per_frame; - - if (lc3_ret == -1) { - printk("LC3 encoder failed - wrong parameters?: %d", - lc3_ret); - net_buf_unref(buf); - return; - } - } - - for (size_t i = 0U; i < configured_sink_stream_count; i++) { - struct bt_bap_stream *stream = &streams[i]; - struct net_buf *buf_to_send; - int ret; - - /* Clone the buffer if sending on more than 1 stream */ - if (i == configured_sink_stream_count - 1) { - buf_to_send = buf; - } else { - buf_to_send = net_buf_clone(buf, K_FOREVER); - } - - ret = bt_bap_stream_send(stream, buf_to_send, get_and_incr_seq_num(stream)); - if (ret < 0) { - printk(" Failed to send LC3 audio data on streams[%zu] (%d)\n", - i, ret); - net_buf_unref(buf_to_send); - } else { - printk(" TX LC3 l on streams[%zu]: %zu\n", - tx_sdu_len, i); - sdu_cnt++; - } - } - } -} - -static int init_lc3(void) -{ - const struct bt_audio_codec_cfg *codec_cfg = &codec_configuration.codec_cfg; - unsigned int num_samples; - int ret; - - ret = bt_audio_codec_cfg_get_freq(codec_cfg); - if (ret > 0) { - freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); - } else { - return ret; - } - - ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); - if (ret > 0) { - frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); - } - - octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); - frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); - octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); - - if (freq_hz < 0) { - printk("Error: Codec frequency not set, cannot start codec."); - return -1; - } - - if (frame_duration_us < 0) { - printk("Error: Frame duration not set, cannot start codec."); - return -1; - } - - if (octets_per_frame < 0) { - printk("Error: Octets per frame not set, cannot start codec."); - return -1; - } - - frame_duration_100us = frame_duration_us / 100; - - - /* Fill audio buffer with Sine wave only once and repeat encoding the same tone frame */ - fill_audio_buf_sin(audio_buf, frame_duration_us, AUDIO_TONE_FREQUENCY_HZ, freq_hz); - - num_samples = ((frame_duration_us * freq_hz) / USEC_PER_SEC); - for (unsigned int i = 0; i < num_samples; i++) { - printk("%3i: %6i\n", i, audio_buf[i]); - } - - /* Create the encoder instance. This shall complete before stream_started() is called. */ - lc3_encoder = lc3_setup_encoder(frame_duration_us, - freq_hz, - 0, /* No resampling */ - &lc3_encoder_mem); - - if (lc3_encoder == NULL) { - printk("ERROR: Failed to setup LC3 encoder - wrong parameters?\n"); - return -1; - } - return 0; -} - -#else - -#define init_lc3(...) 0 - -/** - * @brief Send audio data on timeout - * - * This will send an increasing amount of audio data, starting from 1 octet. - * The data is just mock data, and does not actually represent any audio. - * - * First iteration : 0x00 - * Second iteration: 0x00 0x01 - * Third iteration : 0x00 0x01 0x02 - * - * And so on, until it wraps around the configured MTU (CONFIG_BT_ISO_TX_MTU) - * - * @param work Pointer to the work structure - */ -static void audio_timer_timeout(struct k_work *work) -{ - static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU]; - static bool data_initialized; - struct net_buf *buf; - static size_t len_to_send = 1; - - if (!data_initialized) { - /* TODO: Actually encode some audio data */ - for (int i = 0; i < ARRAY_SIZE(buf_data); i++) { - buf_data[i] = (uint8_t)i; - } - - data_initialized = true; - } - - buf = net_buf_alloc(&tx_pool, K_FOREVER); - net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); - net_buf_add_mem(buf, buf_data, len_to_send); - - /* We configured the sink streams to be first in `streams`, so that - * we can use `stream[i]` to select sink streams (i.e. streams with - * data going to the server) - */ - for (size_t i = 0U; i < configured_sink_stream_count; i++) { - struct bt_bap_stream *stream = &streams[i]; - struct net_buf *buf_to_send; - int ret; - - /* Clone the buffer if sending on more than 1 stream */ - if (i == configured_sink_stream_count - 1) { - buf_to_send = buf; - } else { - buf_to_send = net_buf_clone(buf, K_FOREVER); - } - - ret = bt_bap_stream_send(stream, buf_to_send, get_and_incr_seq_num(stream)); - if (ret < 0) { - printk("Failed to send audio data on streams[%zu]: (%d)\n", - i, ret); - net_buf_unref(buf_to_send); - } else { - printk("Sending mock data with len %zu on streams[%zu]\n", - len_to_send, i); - } - } - - k_work_schedule(&audio_send_work, K_USEC(AUDIO_DATA_TIMEOUT_US)); - - len_to_send++; - if (len_to_send > codec_configuration.qos.sdu) { - len_to_send = 1; - } -} - -#endif - static void print_hex(const uint8_t *ptr, size_t len) { while (len-- != 0) { @@ -519,6 +222,23 @@ static void stream_enabled(struct bt_bap_stream *stream) k_sem_give(&sem_stream_enabled); } +static bool stream_is_tx(const struct bt_bap_stream *stream) +{ + struct bt_bap_ep_info info; + int err; + + if (stream == NULL || stream->ep == NULL) { + return false; + } + + err = bt_bap_ep_get_info(stream->ep, &info); + if (err != 0) { + return false; + } + + return info.can_send; +} + static void stream_connected_cb(struct bt_bap_stream *stream) { printk("Audio Stream %p connected\n", stream); @@ -537,6 +257,14 @@ static void stream_connected_cb(struct bt_bap_stream *stream) static void stream_started(struct bt_bap_stream *stream) { printk("Audio Stream %p started\n", stream); + /* Register the stream for TX if it can send */ + if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_is_tx(stream)) { + const int err = stream_tx_register(stream); + + if (err != 0) { + printk("Failed to register stream %p for TX: %d\n", stream, err); + } + } k_sem_give(&sem_stream_started); } @@ -555,8 +283,14 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) { printk("Audio Stream %p stopped with reason 0x%02X\n", stream, reason); - /* Stop send timer */ - k_work_cancel_delayable(&audio_send_work); + /* Unregister the stream for TX if it can send */ + if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_is_tx(stream)) { + const int err = stream_tx_unregister(stream); + + if (err != 0) { + printk("Failed to unregister stream %p for TX: %d", stream, err); + } + } } static void stream_released(struct bt_bap_stream *stream) @@ -774,11 +508,9 @@ static int init(void) bt_gatt_cb_register(&gatt_callbacks); -#if defined(CONFIG_LIBLC3) - k_work_init_delayable(&audio_send_work, lc3_audio_timer_timeout); -#else - k_work_init_delayable(&audio_send_work, audio_timer_timeout); -#endif + if (IS_ENABLED(CONFIG_BT_AUDIO_TX)) { + stream_tx_init(); + } return 0; } @@ -999,14 +731,6 @@ static int set_stream_qos(void) static int enable_streams(void) { - if (IS_ENABLED(CONFIG_LIBLC3)) { - int err = init_lc3(); - - if (err != 0) { - return err; - } - } - for (size_t i = 0U; i < configured_stream_count; i++) { int err; @@ -1200,11 +924,6 @@ int main(void) } printk("Streams started\n"); - if (CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0) { - /* Start send timer */ - k_work_schedule(&audio_send_work, K_MSEC(0)); - } - /* Wait for disconnect */ err = k_sem_take(&sem_disconnected, K_FOREVER); if (err != 0) { diff --git a/samples/bluetooth/bap_unicast_client/src/stream_lc3.c b/samples/bluetooth/bap_unicast_client/src/stream_lc3.c new file mode 100644 index 00000000000000..fd8c0a1fcd1787 --- /dev/null +++ b/samples/bluetooth/bap_unicast_client/src/stream_lc3.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stream_lc3.h" +#include "stream_tx.h" + +LOG_MODULE_REGISTER(lc3, LOG_LEVEL_INF); + +#define LC3_MAX_SAMPLE_RATE 48000U +#define LC3_MAX_FRAME_DURATION_US 10000U +#define LC3_MAX_NUM_SAMPLES ((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE) / USEC_PER_SEC) +/* codec does clipping above INT16_MAX - 3000 */ +#define AUDIO_VOLUME (INT16_MAX - 3000) +#define AUDIO_TONE_FREQUENCY_HZ 400 + +static int16_t audio_buf[LC3_MAX_NUM_SAMPLES]; +/** + * Use the math lib to generate a sine-wave using 16 bit samples into a buffer. + * + * @param stream The TX stream to generate and fill the sine wave for + */ +static void fill_audio_buf_sin(struct tx_stream *stream) +{ + const unsigned int num_samples = + (stream->lc3_tx.frame_duration_us * stream->lc3_tx.freq_hz) / USEC_PER_SEC; + const int sine_period_samples = stream->lc3_tx.freq_hz / AUDIO_TONE_FREQUENCY_HZ; + const float step = 2 * 3.1415f / sine_period_samples; + + for (unsigned int i = 0; i < num_samples; i++) { + const float sample = sinf(i * step); + + audio_buf[i] = (int16_t)(AUDIO_VOLUME * sample); + } +} + +static int extract_lc3_config(struct tx_stream *stream) +{ + const struct bt_audio_codec_cfg *codec_cfg = stream->bap_stream->codec_cfg; + struct stream_lc3_tx *lc3_tx = &stream->lc3_tx; + int ret; + + LOG_INF("Extracting LC3 configuration values"); + + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret >= 0) { + ret = bt_audio_codec_cfg_freq_to_freq_hz(ret); + if (ret > 0) { + if (LC3_CHECK_SR_HZ(ret)) { + lc3_tx->freq_hz = (uint32_t)ret; + } else { + LOG_ERR("Unsupported sampling frequency for LC3: %d", ret); + + return ret; + } + } else { + LOG_ERR("Invalid frequency: %d", ret); + + return ret; + } + } else { + LOG_ERR("Could not get frequency: %d", ret); + + return ret; + } + + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret >= 0) { + ret = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + if (ret > 0) { + if (LC3_CHECK_DT_US(ret)) { + lc3_tx->frame_duration_us = (uint32_t)ret; + } else { + LOG_ERR("Unsupported frame duration for LC3: %d", ret); + + return ret; + } + } else { + LOG_ERR("Invalid frame duration: %d", ret); + + return ret; + } + } else { + LOG_ERR("Could not get frame duration: %d", ret); + + return ret; + } + + ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &lc3_tx->chan_allocation, false); + if (ret != 0) { + LOG_DBG("Could not get channel allocation: %d", ret); + lc3_tx->chan_allocation = BT_AUDIO_LOCATION_MONO_AUDIO; + } + + lc3_tx->chan_cnt = bt_audio_get_chan_count(lc3_tx->chan_allocation); + + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); + if (ret >= 0) { + lc3_tx->frame_blocks_per_sdu = (uint8_t)ret; + } + + ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); + if (ret >= 0) { + lc3_tx->octets_per_frame = (uint16_t)ret; + } else { + LOG_ERR("Could not get octets per frame: %d", ret); + + return ret; + } + + return 0; +} + +static bool encode_frame(struct tx_stream *stream, uint8_t index, struct net_buf *out_buf) +{ + const uint16_t octets_per_frame = stream->lc3_tx.octets_per_frame; + int lc3_ret; + + /* Generate sine wave */ + fill_audio_buf_sin(stream); + + lc3_ret = lc3_encode(stream->lc3_tx.encoder, LC3_PCM_FORMAT_S16, audio_buf, 1, + octets_per_frame, net_buf_tail(out_buf)); + if (lc3_ret < 0) { + LOG_ERR("LC3 encoder failed - wrong parameters?: %d", lc3_ret); + + return false; + } + + out_buf->len += octets_per_frame; + + return true; +} + +static bool encode_frame_block(struct tx_stream *stream, struct net_buf *out_buf) +{ + for (uint8_t i = 0U; i < stream->lc3_tx.chan_cnt; i++) { + /* We provide the total number of decoded frames to `decode_frame` for logging + * purposes + */ + if (!encode_frame(stream, i, out_buf)) { + return false; + } + } + + return true; +} + +void stream_lc3_add_data(struct tx_stream *stream, struct net_buf *buf) +{ + for (uint8_t i = 0U; i < stream->lc3_tx.frame_blocks_per_sdu; i++) { + if (!encode_frame_block(stream, buf)) { + break; + } + } +} + +int stream_lc3_init(struct tx_stream *stream) +{ + int err; + + err = extract_lc3_config(stream); + if (err != 0) { + memset(&stream->lc3_tx, 0, sizeof(stream->lc3_tx)); + + return err; + } + + /* Fill audio buffer with Sine wave only once and repeat encoding the same tone frame */ + LOG_INF("Initializing sine wave data"); + fill_audio_buf_sin(stream); + + LOG_INF("Setting up LC3 encoder"); + stream->lc3_tx.encoder = + lc3_setup_encoder(stream->lc3_tx.frame_duration_us, stream->lc3_tx.freq_hz, 0, + &stream->lc3_tx.encoder_mem); + + if (stream->lc3_tx.encoder == NULL) { + LOG_ERR("Failed to setup LC3 encoder"); + + memset(&stream->lc3_tx, 0, sizeof(stream->lc3_tx)); + + return -ENOEXEC; + } + + return 0; +} diff --git a/samples/bluetooth/bap_unicast_client/src/stream_lc3.h b/samples/bluetooth/bap_unicast_client/src/stream_lc3.h new file mode 100644 index 00000000000000..28e921e7e05aa9 --- /dev/null +++ b/samples/bluetooth/bap_unicast_client/src/stream_lc3.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef STREAM_LC3_H +#define STREAM_LC3_H + +#include + +#include +#include +#include + +/* Since the lc3.h header file is not available when CONFIG_LIBLC3=n, we need to guard the include + * and use of it + */ +#if defined(CONFIG_LIBLC3) +/* Header file for the liblc3 */ +#include + +struct stream_lc3_tx { + uint32_t freq_hz; + uint32_t frame_duration_us; + uint16_t octets_per_frame; + uint8_t frame_blocks_per_sdu; + uint8_t chan_cnt; + enum bt_audio_location chan_allocation; + lc3_encoder_t encoder; + lc3_encoder_mem_48k_t encoder_mem; +}; +#endif /* CONFIG_LIBLC3 */ + +/* Opaque definition to avoid including stream_tx.h */ +struct tx_stream; + +/* + * @brief Initialize LC3 encoder for a stream + * + * This will initialize the encoder for the provided TX stream + */ +int stream_lc3_init(struct tx_stream *stream); + +/** + * Add LC3 encoded data to the provided buffer from the provided stream + * + * @param stream The TX stream to add data from + * @param buf The buffer to store the encoded audio data in + */ +void stream_lc3_add_data(struct tx_stream *stream, struct net_buf *buf); + +#endif /* STREAM_LC3_H */ diff --git a/samples/bluetooth/bap_unicast_client/src/stream_tx.c b/samples/bluetooth/bap_unicast_client/src/stream_tx.c new file mode 100644 index 00000000000000..91f668db17a1b4 --- /dev/null +++ b/samples/bluetooth/bap_unicast_client/src/stream_tx.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stream_lc3.h" +#include "stream_tx.h" + +LOG_MODULE_REGISTER(stream_tx, LOG_LEVEL_INF); + +static struct tx_stream tx_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT]; + +static bool stream_is_streaming(const struct bt_bap_stream *bap_stream) +{ + struct bt_bap_ep_info ep_info; + int err; + + if (bap_stream == NULL) { + return false; + } + + /* No-op if stream is not configured */ + if (bap_stream->ep == NULL) { + return false; + } + + err = bt_bap_ep_get_info(bap_stream->ep, &ep_info); + if (err != 0) { + false; + } + + return ep_info.state == BT_BAP_EP_STATE_STREAMING; +} + +static void tx_thread_func(void *arg1, void *arg2, void *arg3) +{ + NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, + BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + static uint8_t mock_data[CONFIG_BT_ISO_TX_MTU]; + + for (size_t i = 0U; i < ARRAY_SIZE(mock_data); i++) { + mock_data[i] = (uint8_t)i; + } + + /* This loop will attempt to send on all streams in the streaming state in a round robin + * fashion. + * The TX is controlled by the number of buffers configured, and increasing + * CONFIG_BT_ISO_TX_BUF_COUNT will allow for more streams in parallel, or to submit more + * buffers per stream. + * Once a buffer has been freed by the stack, it triggers the next TX. + */ + while (true) { + int err = -ENOEXEC; + + for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) { + struct bt_bap_stream *bap_stream = tx_streams[i].bap_stream; + + if (stream_is_streaming(bap_stream)) { + struct net_buf *buf; + + buf = net_buf_alloc(&tx_pool, K_FOREVER); + net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE); + + if (IS_ENABLED(CONFIG_LIBLC3) && + bap_stream->codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { + stream_lc3_add_data(&tx_streams[i], buf); + } else { + net_buf_add_mem(buf, mock_data, bap_stream->qos->sdu); + } + + err = bt_bap_stream_send(bap_stream, buf, tx_streams[i].seq_num); + if (err == 0) { + tx_streams[i].seq_num++; + } else { + LOG_ERR("Unable to send: %d", err); + net_buf_unref(buf); + } + } /* No-op if stream is not streaming */ + } + + if (err != 0) { + /* In case of any errors, retry with a delay */ + k_sleep(K_MSEC(10)); + } + } +} + +int stream_tx_register(struct bt_bap_stream *bap_stream) +{ + if (bap_stream == NULL) { + return -EINVAL; + } + + for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) { + if (tx_streams[i].bap_stream == NULL) { + tx_streams[i].bap_stream = bap_stream; + tx_streams[i].seq_num = 0U; + + if (IS_ENABLED(CONFIG_LIBLC3) && + bap_stream->codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { + const int err = stream_lc3_init(&tx_streams[i]); + + if (err != 0) { + tx_streams[i].bap_stream = NULL; + + return err; + } + } + + LOG_INF("Registered %p for TX", bap_stream); + + return 0; + } + } + + return -ENOMEM; +} + +int stream_tx_unregister(struct bt_bap_stream *bap_stream) +{ + if (bap_stream == NULL) { + return -EINVAL; + } + + for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) { + if (tx_streams[i].bap_stream == bap_stream) { + tx_streams[i].bap_stream = NULL; + + LOG_INF("Unregistered %p for TX", bap_stream); + + return 0; + } + } + + return -ENODATA; +} + +void stream_tx_init(void) +{ + static bool thread_started; + + if (!thread_started) { + static K_KERNEL_STACK_DEFINE(tx_thread_stack, + IS_ENABLED(CONFIG_LIBLC3) ? 4096U : 1024U); + const int tx_thread_prio = K_PRIO_PREEMPT(5); + static struct k_thread tx_thread; + + k_thread_create(&tx_thread, tx_thread_stack, K_KERNEL_STACK_SIZEOF(tx_thread_stack), + tx_thread_func, NULL, NULL, NULL, tx_thread_prio, 0, K_NO_WAIT); + k_thread_name_set(&tx_thread, "TX thread"); + thread_started = true; + } +} diff --git a/samples/bluetooth/bap_unicast_client/src/stream_tx.h b/samples/bluetooth/bap_unicast_client/src/stream_tx.h new file mode 100644 index 00000000000000..d5b17ccc796b36 --- /dev/null +++ b/samples/bluetooth/bap_unicast_client/src/stream_tx.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef STREAM_TX_H +#define STREAM_TX_H + +#include +#include +#include +#include + +#include "stream_lc3.h" + +struct tx_stream { + struct bt_bap_stream *bap_stream; + uint16_t seq_num; + +#if defined(CONFIG_LIBLC3) + struct stream_lc3_tx lc3_tx; +#endif /* CONFIG_LIBLC3 */ +}; + +/** + * @brief Initialize TX + * + * This will initialize TX if not already initialized. This creates and starts a thread that + * will attempt to send data on all streams registered with stream_tx_register(). + */ +void stream_tx_init(void); + +/** + * @brief Register a stream for TX + * + * This will add it to the list of streams the TX thread will attempt to send on. + * + * @retval 0 on success + * @retval -EINVAL if @p bap_stream is NULL + * @retval -EINVAL if @p bap_stream.codec_cfg contains invalid values + * @retval -ENOEXEC if the LC3 encoder failed to initialize + * @retval -ENOMEM if not more streams can be registered + */ +int stream_tx_register(struct bt_bap_stream *bap_stream); + +/** + * @brief Unregister a stream for TX + * + * This will remove it to the list of streams the TX thread will attempt to send on. + * + * @retval 0 on success + * @retval -EINVAL if @p bap_stream is NULL + * @retval -EALREADY if the stream is currently not registered + */ +int stream_tx_unregister(struct bt_bap_stream *bap_stream); + +#endif /* STREAM_TX_H */ diff --git a/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 76df8dba27a4f4..7c6a3aecc26875 100644 --- a/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,9 +1,6 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence -# inctease stack size for that thread. -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/bap_unicast_server/src/main.c b/samples/bluetooth/bap_unicast_server/src/main.c index 6a39afb6879a72..7763484d1a5a73 100644 --- a/samples/bluetooth/bap_unicast_server/src/main.c +++ b/samples/bluetooth/bap_unicast_server/src/main.c @@ -154,7 +154,8 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); } - if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { + ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false); + if (ret == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/beacon/sample.yaml b/samples/bluetooth/beacon/sample.yaml index 9073de8c1fc0fb..d76a16eb566f0c 100644 --- a/samples/bluetooth/beacon/sample.yaml +++ b/samples/bluetooth/beacon/sample.yaml @@ -6,13 +6,20 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - nrf51dk/nrf51822 - nrf52dk/nrf52832 + - nrf54l15pdk/nrf54l15/cpuapp tags: bluetooth integration_platforms: - qemu_cortex_m3 - + - nrf51dk/nrf51822 + - nrf52dk/nrf52832 + - nrf54l15pdk/nrf54l15/cpuapp sample.bluetooth.beacon-coex: extra_args: CONF_FILE="prj-coex.conf" harness: bluetooth - platform_allow: nrf52840dk/nrf52840 + platform_allow: + - nrf52840dk/nrf52840 + integration_platforms: + - nrf52840dk/nrf52840 tags: bluetooth diff --git a/samples/bluetooth/ibeacon/boards/efr32bg22_brd4184a.conf b/samples/bluetooth/central_ht/boards/frdm_rw612.conf similarity index 100% rename from samples/bluetooth/ibeacon/boards/efr32bg22_brd4184a.conf rename to samples/bluetooth/central_ht/boards/frdm_rw612.conf diff --git a/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf b/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf new file mode 100644 index 00000000000000..2df782efc71152 --- /dev/null +++ b/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf @@ -0,0 +1 @@ +CONFIG_PM=y diff --git a/samples/bluetooth/central_ht/sample.yaml b/samples/bluetooth/central_ht/sample.yaml index f59d207a59fed3..48d2803dde5612 100644 --- a/samples/bluetooth/central_ht/sample.yaml +++ b/samples/bluetooth/central_ht/sample.yaml @@ -8,8 +8,14 @@ tests: - qemu_x86 - nrf51dk/nrf51822 - nrf52dk/nrf52832 - - rd_rw612_bga tags: bluetooth integration_platforms: - qemu_cortex_m3 + sample.bluetooth.central_ht.nxp: + # Disabling monolithic since CI environment doesn't use blobs + harness: bluetooth + platform_allow: - rd_rw612_bga + - frdm_rw612 + extra_configs: + - CONFIG_NXP_MONOLITHIC_BT=n diff --git a/samples/bluetooth/direction_finding_connectionless_tx/src/main.c b/samples/bluetooth/direction_finding_connectionless_tx/src/main.c index ef6a89b885239c..f827e39a6573c1 100644 --- a/samples/bluetooth/direction_finding_connectionless_tx/src/main.c +++ b/samples/bluetooth/direction_finding_connectionless_tx/src/main.c @@ -42,8 +42,8 @@ static struct bt_le_ext_adv_start_param ext_adv_start_param = { }; static struct bt_le_per_adv_param per_adv_param = { - .interval_min = BT_GAP_ADV_SLOW_INT_MIN, - .interval_max = BT_GAP_ADV_SLOW_INT_MAX, + .interval_min = BT_GAP_PER_ADV_SLOW_INT_MIN, + .interval_max = BT_GAP_PER_ADV_SLOW_INT_MAX, .options = BT_LE_ADV_OPT_USE_TX_POWER, }; diff --git a/samples/bluetooth/encrypted_advertising/central/src/central_ead.c b/samples/bluetooth/encrypted_advertising/central/src/central_ead.c index a3215920071724..ddfb98cad8aa73 100644 --- a/samples/bluetooth/encrypted_advertising/central/src/central_ead.c +++ b/samples/bluetooth/encrypted_advertising/central/src/central_ead.c @@ -38,7 +38,6 @@ static struct bt_conn_cb central_cb; static struct bt_conn_auth_cb central_auth_cb; static struct k_poll_signal conn_signal; -static struct k_poll_signal sec_update_signal; static struct k_poll_signal passkey_enter_signal; static struct k_poll_signal device_found_cb_completed; @@ -348,7 +347,6 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_ if (!err) { LOG_DBG("Security changed: %s level %u", addr, level); - k_poll_signal_raise(&sec_update_signal, 0); } else { LOG_DBG("Security failed: %s level %u err %d", addr, level, err); } @@ -411,7 +409,6 @@ static int init_bt(void) k_poll_signal_init(&conn_signal); k_poll_signal_init(&passkey_enter_signal); - k_poll_signal_init(&sec_update_signal); k_poll_signal_init(&gatt_disc_signal); k_poll_signal_init(&gatt_read_signal); k_poll_signal_init(&device_found_cb_completed); diff --git a/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf new file mode 100644 index 00000000000000..9e8851c73af1b3 --- /dev/null +++ b/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -0,0 +1,2 @@ +#select NXP NW612 Chipset +CONFIG_BT_NXP_NW612=y diff --git a/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay new file mode 100644 index 00000000000000..96ef63ad60b2e7 --- /dev/null +++ b/samples/bluetooth/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -0,0 +1,11 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sram = &dtcm; + }; +}; diff --git a/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf new file mode 100644 index 00000000000000..9e8851c73af1b3 --- /dev/null +++ b/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -0,0 +1,2 @@ +#select NXP NW612 Chipset +CONFIG_BT_NXP_NW612=y diff --git a/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay new file mode 100644 index 00000000000000..96ef63ad60b2e7 --- /dev/null +++ b/samples/bluetooth/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -0,0 +1,11 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sram = &dtcm; + }; +}; diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 3fe6948e63dd78..e2b4b3022de790 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -93,7 +93,8 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); } - if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { + ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false); + if (ret == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/hci_ipc/src/main.c b/samples/bluetooth/hci_ipc/src/main.c index 814001646e46c1..6e1f275ffd03c3 100644 --- a/samples/bluetooth/hci_ipc/src/main.c +++ b/samples/bluetooth/hci_ipc/src/main.c @@ -320,7 +320,7 @@ void bt_ctlr_assert_handle(char *file, uint32_t line) #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ #if defined(CONFIG_BT_HCI_VS_FATAL_ERROR) -void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) +void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *esf) { /* Disable interrupts, this is unrecoverable */ (void)irq_lock(); diff --git a/samples/bluetooth/hci_uart/README.rst b/samples/bluetooth/hci_uart/README.rst index a7a82fc8d01d0e..84fc12080992b1 100644 --- a/samples/bluetooth/hci_uart/README.rst +++ b/samples/bluetooth/hci_uart/README.rst @@ -177,9 +177,9 @@ driver instead of the built-in controller: CONFIG_BT_HCI=y CONFIG_BT_CTLR=n - CONFIG_BT_H4=y -Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: +Similarly, the `zephyr,bt-hci` DTS property selects which HCI instance to use. +The UART needs to have as its child node a HCI UART node: .. code-block:: dts @@ -187,6 +187,14 @@ Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; + zephyr,bt-hci = &bt_hci_uart; + }; + }; + + &uart1 { + status = "okay"; + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; }; }; diff --git a/samples/drivers/spi_flash/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/bluetooth/hci_uart/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay similarity index 56% rename from samples/drivers/spi_flash/boards/nrf54h20dk_nrf54h20_cpuapp.overlay rename to samples/bluetooth/hci_uart/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay index d03419690bdf61..7ba5755c681330 100644 --- a/samples/drivers/spi_flash/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/samples/bluetooth/hci_uart/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -4,13 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -&mx25uw63 { + &uart20 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; status = "okay"; -}; - - -/ { - aliases { - spi-flash0 = &mx25uw63; - }; + hw-flow-control; }; diff --git a/samples/bluetooth/hci_uart/dts/arm/nordic/override.dtsi b/samples/bluetooth/hci_uart/dts/arm/nordic/override.dtsi new file mode 100644 index 00000000000000..882f70755d59d5 --- /dev/null +++ b/samples/bluetooth/hci_uart/dts/arm/nordic/override.dtsi @@ -0,0 +1,7 @@ +/* Keep default IRQ priority low for peripherals to reduce Radio ISR latency. + * ARM Cortex-M4 lowest priority value of 5, i.e. considering Zephyr reserved 2 + * levels for Exceptions and ZLI (if enabled). + * ARM Cortex-M0 lowest priority value of 3, i.e. we use it as Zephyr has no + * support for ZLI on Cortex-M0. + */ +#define NRF_DEFAULT_IRQ_PRIORITY 3 diff --git a/samples/bluetooth/hci_uart/sample.yaml b/samples/bluetooth/hci_uart/sample.yaml index 033a16c0cb143c..7aa49e1eba5927 100644 --- a/samples/bluetooth/hci_uart/sample.yaml +++ b/samples/bluetooth/hci_uart/sample.yaml @@ -58,3 +58,13 @@ tests: tags: - uart - bluetooth + sample.bluetooth.hci_uart.nrf54l15.all: + harness: bluetooth + platform_allow: nrf54l15pdk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15pdk/nrf54l15/cpuapp + extra_args: + - OVERLAY_CONFIG=overlay-all-bt_ll_sw_split.conf + tags: + - uart + - bluetooth diff --git a/samples/bluetooth/hci_uart_3wire/README.rst b/samples/bluetooth/hci_uart_3wire/README.rst index 2b664d499d6389..43e9ea0c6d9a8d 100644 --- a/samples/bluetooth/hci_uart_3wire/README.rst +++ b/samples/bluetooth/hci_uart_3wire/README.rst @@ -177,9 +177,9 @@ driver instead of the built-in controller: CONFIG_BT_HCI=y CONFIG_BT_CTLR=n - CONFIG_BT_H5=y -Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: +Similarly, the `zephyr,bt-hci` DTS property selects which HCI instance to use. +The UART needs to have as its child node a HCI UART node: .. code-block:: dts @@ -187,6 +187,14 @@ Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; + zephyr,bt-hci = &bt_hci_uart; + }; + }; + + &uart1 { + status = "okay"; + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-3wire-uart"; + status = "okay"; }; }; diff --git a/samples/bluetooth/hci_uart_async/README.rst b/samples/bluetooth/hci_uart_async/README.rst index 7dbb4bbbdb63c7..065231e926c3c4 100644 --- a/samples/bluetooth/hci_uart_async/README.rst +++ b/samples/bluetooth/hci_uart_async/README.rst @@ -143,9 +143,9 @@ driver instead of the built-in controller: CONFIG_BT_HCI=y CONFIG_BT_CTLR=n - CONFIG_BT_H4=y -Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: +Similarly, the `zephyr,bt-hci` DTS property selects which HCI instance to use. +The UART needs to have as its child node a HCI UART node: .. code-block:: dts @@ -153,6 +153,14 @@ Similarly, the `zephyr,bt-uart` DTS property selects which uart to use: chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,bt-uart = &uart1; + zephyr,bt-hci = &bt_hci_uart; + }; + }; + + &uart1 { + status = "okay"; + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; }; }; diff --git a/samples/bluetooth/hci_uart_async/boards/nrf52_bsim.overlay b/samples/bluetooth/hci_uart_async/boards/nrf52_bsim.overlay index adef7109b3c9f9..e3745738a19c8b 100644 --- a/samples/bluetooth/hci_uart_async/boards/nrf52_bsim.overlay +++ b/samples/bluetooth/hci_uart_async/boards/nrf52_bsim.overlay @@ -1 +1,3 @@ -/* Purposely empty. To avoid using the one provided by the application */ +&bt_hci_uart { + status = "disabled"; +}; diff --git a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c index e3e32eba4af1f8..856ebc47524862 100644 --- a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c +++ b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c @@ -151,10 +151,11 @@ static void send_hw_error(void) struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); + net_buf_add_u8(buf, BT_HCI_H4_EVT); net_buf_add_mem(buf, hci_evt_hw_err, sizeof(hci_evt_hw_err)); /* Inject the message into the c2h queue. */ - bt_recv(buf); + net_buf_put(&c2h_queue, buf); /* The c2h thread will send the message at some point. The host * will receive it and reset the controller. diff --git a/samples/bluetooth/ibeacon/boards/sltb010a.conf b/samples/bluetooth/ibeacon/boards/sltb010a.conf new file mode 100644 index 00000000000000..2df782efc71152 --- /dev/null +++ b/samples/bluetooth/ibeacon/boards/sltb010a.conf @@ -0,0 +1 @@ +CONFIG_PM=y diff --git a/samples/bluetooth/periodic_adv_conn/sample.yaml b/samples/bluetooth/periodic_adv_conn/sample.yaml index cfc9d0522f4925..cc3ea8e24e902a 100644 --- a/samples/bluetooth/periodic_adv_conn/sample.yaml +++ b/samples/bluetooth/periodic_adv_conn/sample.yaml @@ -6,10 +6,6 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 - - nrf52840dk/nrf52840 tags: bluetooth integration_platforms: - - nrf52840dk/nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y + - qemu_cortex_m3 diff --git a/samples/bluetooth/periodic_adv_rsp/sample.yaml b/samples/bluetooth/periodic_adv_rsp/sample.yaml index dcb37b9fe4a834..fd22311303b16b 100644 --- a/samples/bluetooth/periodic_adv_rsp/sample.yaml +++ b/samples/bluetooth/periodic_adv_rsp/sample.yaml @@ -6,10 +6,6 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 - - nrf52840dk/nrf52840 tags: bluetooth integration_platforms: - - nrf52840dk/nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y + - qemu_cortex_m3 diff --git a/samples/bluetooth/periodic_sync_conn/sample.yaml b/samples/bluetooth/periodic_sync_conn/sample.yaml index e7aca788eea6bc..a13d15c8ff0c3f 100644 --- a/samples/bluetooth/periodic_sync_conn/sample.yaml +++ b/samples/bluetooth/periodic_sync_conn/sample.yaml @@ -6,10 +6,6 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 - - nrf52840dk/nrf52840 tags: bluetooth integration_platforms: - - nrf52840dk/nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y + - qemu_cortex_m3 diff --git a/samples/bluetooth/periodic_sync_rsp/sample.yaml b/samples/bluetooth/periodic_sync_rsp/sample.yaml index c0f073b19e01ba..e31e7f61badd2b 100644 --- a/samples/bluetooth/periodic_sync_rsp/sample.yaml +++ b/samples/bluetooth/periodic_sync_rsp/sample.yaml @@ -6,10 +6,6 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 - - nrf52840dk/nrf52840 tags: bluetooth integration_platforms: - - nrf52840dk/nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y + - qemu_cortex_m3 diff --git a/samples/bluetooth/peripheral_hr/sample.yaml b/samples/bluetooth/peripheral_hr/sample.yaml index 87442dd3e59789..6a4f2edead0295 100644 --- a/samples/bluetooth/peripheral_hr/sample.yaml +++ b/samples/bluetooth/peripheral_hr/sample.yaml @@ -7,8 +7,22 @@ tests: platform_allow: - qemu_cortex_m3 - qemu_x86 + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf51dk/nrf51822 + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp integration_platforms: - qemu_cortex_m3 + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf51dk/nrf51822 + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp tags: bluetooth sample.bluetooth.peripheral_hr.minimal: harness: bluetooth diff --git a/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf b/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf new file mode 100644 index 00000000000000..2df782efc71152 --- /dev/null +++ b/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf @@ -0,0 +1 @@ +CONFIG_PM=y diff --git a/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf b/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf new file mode 100644 index 00000000000000..2df782efc71152 --- /dev/null +++ b/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf @@ -0,0 +1 @@ +CONFIG_PM=y diff --git a/samples/bluetooth/peripheral_ht/sample.yaml b/samples/bluetooth/peripheral_ht/sample.yaml index 4243914b57178b..be53ecd851908a 100644 --- a/samples/bluetooth/peripheral_ht/sample.yaml +++ b/samples/bluetooth/peripheral_ht/sample.yaml @@ -9,11 +9,9 @@ tests: - qemu_x86 - nrf51dk/nrf51822 - nrf52dk/nrf52832 - - rd_rw612_bga tags: bluetooth integration_platforms: - qemu_cortex_m3 - - rd_rw612_bga sample.bluetooth.peripheral_ht.frdm_kw41z_shield: harness: bluetooth platform_allow: @@ -25,3 +23,11 @@ tests: extra_args: SHIELD=frdm_kw41z integration_platforms: - mimxrt1020_evk + sample.bluetooth.peripheral_ht.nxp: + # Disabling monolithic since CI environment doesn't use blobs + harness: bluetooth + platform_allow: + - rd_rw612_bga + - frdm_rw612 + extra_configs: + - CONFIG_NXP_MONOLITHIC_BT=n diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index 5e3ce9566f167c..8e325855e655a1 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -82,7 +82,8 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); } - if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { + ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false); + if (ret == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/boards/arc_secure_services/nsim_sem_normal_defconfig b/samples/boards/arc_secure_services/nsim_sem_normal_defconfig index 91b9775a7dd6be..80e70c38a35ed0 100644 --- a/samples/boards/arc_secure_services/nsim_sem_normal_defconfig +++ b/samples/boards/arc_secure_services/nsim_sem_normal_defconfig @@ -1,4 +1,4 @@ -CONFIG_SOC_NSIM=y +CONFIG_SOC_FAMILY_NSIM_ARC_CLASSIC=y CONFIG_SOC_NSIM_SEM=y CONFIG_BOARD_NSIM=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 diff --git a/samples/boards/stm32/backup_sram/boards/nucleo_h563zi.overlay b/samples/boards/stm32/backup_sram/boards/nucleo_h563zi.overlay new file mode 100644 index 00000000000000..377726bbd4ccf9 --- /dev/null +++ b/samples/boards/stm32/backup_sram/boards/nucleo_h563zi.overlay @@ -0,0 +1,9 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Thorsten Spätling + */ + +&backup_sram{ + status = "okay"; +}; diff --git a/samples/boards/stm32/bluetooth/interactive_gui/CMakeLists.txt b/samples/boards/stm32/bluetooth/interactive_gui/CMakeLists.txt new file mode 100644 index 00000000000000..37dc403fcca8a2 --- /dev/null +++ b/samples/boards/stm32/bluetooth/interactive_gui/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(st_interactive_gui) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/bluetooth/interactive_gui/README.rst b/samples/boards/stm32/bluetooth/interactive_gui/README.rst new file mode 100644 index 00000000000000..e086eec0c8e4e6 --- /dev/null +++ b/samples/boards/stm32/bluetooth/interactive_gui/README.rst @@ -0,0 +1,37 @@ +.. _samples_boards_stm32_bluetooth_interactive-gui: +.. zephyr:code-sample:: st_bluetooth_interactive_gui + :name: Bluetooth: ST Interactive GUI + :relevant-api: bluenrg_hci_driver bluetooth + +Expose ST BlueNRG Bluetooth network coprocessor over UART + +Overview +********* + +Expose the Bluetooth network coprocessor via UART to a PC to be used +with the ST BlueNRG GUI app. In this case, the main MCU becomes an intermediate level, +and it passes the data between the host (PC) and controller. + +Requirements +************ + +* A board based on BlueNRG BLE module such as :ref:`disco_l475_iot1_board` +* `BlueNRG GUI`_ application installed on your PC + +Default UART settings +********************* + +It depends on the board default settings for ``zephyr,bt-c2h-uart`` DTS property. +The UART default settings are: + +* Baudrate: 115200 bps +* 8 bits, no parity, 1 stop bit + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/boards/stm32/bluetooth/interactive_gui` in the +Zephyr tree. + +.. _BlueNRG GUI: + https://www.st.com/en/embedded-software/stsw-bnrgui.html diff --git a/samples/boards/stm32/bluetooth/interactive_gui/prj.conf b/samples/boards/stm32/bluetooth/interactive_gui/prj.conf new file mode 100644 index 00000000000000..74ce94a7cc53d3 --- /dev/null +++ b/samples/boards/stm32/bluetooth/interactive_gui/prj.conf @@ -0,0 +1,15 @@ +CONFIG_CONSOLE=n +CONFIG_STDOUT_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_HCI_RAW_H4=y +CONFIG_BT_HCI_RAW_H4_ENABLE=y +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_CMD_TX_SIZE=255 +CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 +CONFIG_BT_BLUENRG_ACI=n +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 +CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y diff --git a/samples/boards/stm32/bluetooth/interactive_gui/sample.yaml b/samples/boards/stm32/bluetooth/interactive_gui/sample.yaml new file mode 100644 index 00000000000000..695c6e93a6f8b7 --- /dev/null +++ b/samples/boards/stm32/bluetooth/interactive_gui/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Bluetooth ST Interactive GUI + description: Allows BlueNRG-based boards to connect to BlueNRG GUI application via UART +tests: + sample.boards.stm32.bluetooth.interactive_gui: + harness: bluetooth + platform_allow: + - sensortile_box_pro + - disco_l475_iot1 + tags: + - uart + - bluetooth diff --git a/samples/boards/stm32/bluetooth/interactive_gui/src/main.c b/samples/boards/stm32/bluetooth/interactive_gui/src/main.c new file mode 100644 index 00000000000000..82d008e4d6c9aa --- /dev/null +++ b/samples/boards/stm32/bluetooth/interactive_gui/src/main.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE_NAME gui_hci_uart +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +static const struct device *const hci_uart_dev = + DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart)); +static K_THREAD_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); +static struct k_thread tx_thread_data; +static K_FIFO_DEFINE(tx_queue); + +/* RX in terms of bluetooth communication */ +static K_FIFO_DEFINE(uart_tx_queue); + +#define H4_ST_EXT_CMD 0x81 +#define H4_ST_VND_CMD 0xFF + +#define ST_IDLE 0 /* Waiting for packet type. */ +#define ST_HDR 1 /* Receiving packet header. */ +#define ST_PAYLOAD 2 /* Receiving packet payload. */ +#define ST_DISCARD 3 /* Dropping packet. */ + +/* Length of a discard/flush buffer. + * This is sized to align with a BLE HCI packet: + * 1 byte H:4 header + 32 bytes ACL/event data + * Bigger values might overflow the stack since this is declared as a local + * variable, smaller ones will force the caller to call into discard more + * often. + */ +#define H4_DISCARD_LEN 33 + +#define RESP_VENDOR_CODE_OFFSET 1 +#define RESP_LEN_OFFSET_LSB 2 +#define RESP_LEN_OFFSET_MSB 3 +#define RESP_CMDCODE_OFFSET 4 +#define RESP_STATUS_OFFSET 5 +#define RESP_PARAM_OFFSET 6 + +/* Types of vendor codes */ +#define VENDOR_CODE_ERROR 0 +#define VENDOR_CODE_RESPONSE 1 + +/* Commands */ +#define VENDOR_CMD_READ_VERSION 0x01 +#define VENDOR_CMD_BLUENRG_RESET 0x04 +#define VENDOR_CMD_HW_BOOTLOADER 0x05 + +struct bt_hci_ext_cmd_hdr { + uint16_t opcode; + uint16_t param_len; +} __packed; + +struct bt_vendor_cmd_hdr { + uint8_t opcode; + uint16_t param_len; +} __packed; + +struct bt_vendor_rsp_hdr { + uint8_t vendor_code; + uint16_t param_len; + uint8_t opcode; + uint8_t status; + uint8_t params[2]; +} __packed; + +static int h4_send(struct net_buf *buf); + +static uint16_t parse_cmd(uint8_t *hci_buffer, uint16_t hci_pckt_len, uint8_t *buffer_out) +{ + uint16_t len = 0; + struct bt_vendor_cmd_hdr *hdr = (struct bt_vendor_cmd_hdr *) hci_buffer; + struct bt_vendor_rsp_hdr *rsp = (struct bt_vendor_rsp_hdr *) (buffer_out + 1); + + buffer_out[0] = H4_ST_VND_CMD; + rsp->vendor_code = VENDOR_CODE_RESPONSE; + rsp->opcode = hdr->opcode; + rsp->status = 0; + + switch (hdr->opcode) { + case VENDOR_CMD_READ_VERSION: + rsp->params[0] = KERNEL_VERSION_MAJOR; + if (KERNEL_PATCHLEVEL >= 9) { + rsp->params[1] = (KERNEL_VERSION_MINOR * 10) + 9; + } else { + rsp->params[1] = (KERNEL_VERSION_MINOR * 10) + KERNEL_PATCHLEVEL; + } + len = 2; + break; +#if DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) || DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2) + case VENDOR_CMD_BLUENRG_RESET: + bluenrg_bt_reset(0); + break; + case VENDOR_CMD_HW_BOOTLOADER: + bluenrg_bt_reset(1); + break; +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v1) || DT_HAS_COMPAT_STATUS_OKAY(st_hci_spi_v2) */ + default: + rsp->vendor_code = VENDOR_CODE_ERROR; + rsp->status = BT_HCI_ERR_UNKNOWN_CMD; + } + + len += 2; /* Status and Command code */ + rsp->param_len = sys_cpu_to_le16(len); + len += RESP_CMDCODE_OFFSET; + + return len; +} + +static int send_evt(uint8_t *response, uint8_t len) +{ + struct net_buf *buf; + + buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT); + + if (!buf) { + LOG_ERR("EVT no buffer"); + return -ENOMEM; + } + if (len > net_buf_tailroom(buf)) { + LOG_ERR("EVT too long: %d", len); + net_buf_unref(buf); + return -ENOMEM; + } + net_buf_add_mem(buf, response, len); + + return h4_send(buf); +} + +static int h4_read(const struct device *uart, uint8_t *buf, size_t len) +{ + int rx = uart_fifo_read(uart, buf, len); + + LOG_DBG("read %d req %d", rx, len); + return rx; +} + +static bool valid_type(uint8_t type) +{ + return (type == BT_HCI_H4_CMD) | (type == H4_ST_EXT_CMD) | + (type == BT_HCI_H4_ACL) | (type == BT_HCI_H4_ISO) | (type == H4_ST_VND_CMD); +} + +/* Function expects that type is validated and only CMD, ISO or ACL are used. */ +static uint32_t get_len(const uint8_t *hdr_buf, uint8_t type) +{ + switch (type) { + case BT_HCI_H4_CMD: + return ((const struct bt_hci_cmd_hdr *)hdr_buf)->param_len; + case H4_ST_EXT_CMD: + return ((const struct bt_hci_ext_cmd_hdr *)hdr_buf)->param_len; + case H4_ST_VND_CMD: + return ((const struct bt_vendor_cmd_hdr *)hdr_buf)->param_len; + case BT_HCI_H4_ISO: + return bt_iso_hdr_len( + sys_le16_to_cpu(((const struct bt_hci_iso_hdr *)hdr_buf)->len)); + case BT_HCI_H4_ACL: + return sys_le16_to_cpu(((const struct bt_hci_acl_hdr *)hdr_buf)->len); + default: + LOG_ERR("Invalid type: %u", type); + return 0; + } +} + +/* Function expects that type is validated and only CMD, ISO or ACL are used. */ +static int hdr_len(uint8_t type) +{ + switch (type) { + case BT_HCI_H4_CMD: + return sizeof(struct bt_hci_cmd_hdr); + case H4_ST_EXT_CMD: + return sizeof(struct bt_hci_ext_cmd_hdr); + case H4_ST_VND_CMD: + return sizeof(struct bt_vendor_cmd_hdr); + case BT_HCI_H4_ISO: + return sizeof(struct bt_hci_iso_hdr); + case BT_HCI_H4_ACL: + return sizeof(struct bt_hci_acl_hdr); + default: + LOG_ERR("Invalid type: %u", type); + return 0; + } +} + +static struct net_buf *alloc_tx_buf(uint8_t type) +{ + uint8_t alloc_type = type; + struct net_buf *buf; + + switch (type) { + case H4_ST_EXT_CMD: + case BT_HCI_H4_CMD: + case H4_ST_VND_CMD: + alloc_type = BT_HCI_H4_CMD; + break; + case BT_HCI_H4_ISO: + case BT_HCI_H4_ACL: + break; + default: + LOG_ERR("Invalid type: %u", type); + return NULL; + } + buf = bt_buf_get_tx(BT_BUF_H4, K_NO_WAIT, &alloc_type, sizeof(alloc_type)); + if (buf && (type == H4_ST_VND_CMD)) { + bt_buf_set_type(buf, type); + } + return buf; +} + +static void rx_isr(void) +{ + static struct net_buf *buf; + static int remaining; + static uint8_t state; + static uint8_t type; + static uint8_t hdr_buf[MAX(sizeof(struct bt_hci_cmd_hdr), sizeof(struct bt_hci_acl_hdr))]; + int read; + + do { + switch (state) { + case ST_IDLE: + /* Get packet type */ + read = h4_read(hci_uart_dev, &type, sizeof(type)); + /* since we read in loop until no data is in the fifo, + * it is possible that read = 0. + */ + if (read) { + if (valid_type(type)) { + /* Get expected header size and switch + * to receiving header. + */ + remaining = hdr_len(type); + state = ST_HDR; + } else { + LOG_WRN("Unknown header %d", type); + } + } + break; + case ST_HDR: + read = h4_read(hci_uart_dev, &hdr_buf[hdr_len(type) - remaining], + remaining); + remaining -= read; + if (remaining == 0) { + /* Header received. Allocate buffer and get + * payload length. If allocation fails leave + * interrupt. On failed allocation state machine + * is reset. + */ + uint8_t header_length; + + buf = alloc_tx_buf(type); + if (!buf) { + LOG_ERR("No available command buffers!"); + state = ST_IDLE; + return; + } + + remaining = get_len(hdr_buf, type); + header_length = hdr_len(type); + if (type == H4_ST_EXT_CMD) { + /* Convert to regular HCI_CMD */ + if (remaining > 255) { + LOG_ERR("len > 255"); + net_buf_unref(buf); + state = ST_DISCARD; + } else { + header_length--; + } + } + net_buf_add_mem(buf, hdr_buf, header_length); + if (remaining > net_buf_tailroom(buf)) { + LOG_ERR("Not enough space in buffer"); + net_buf_unref(buf); + state = ST_DISCARD; + } else { + state = ST_PAYLOAD; + } + + } + break; + case ST_PAYLOAD: + read = h4_read(hci_uart_dev, net_buf_tail(buf), remaining); + buf->len += read; + remaining -= read; + if (remaining == 0) { + /* Packet received */ + LOG_DBG("putting RX packet in queue."); + net_buf_put(&tx_queue, buf); + state = ST_IDLE; + } + break; + case ST_DISCARD: + uint8_t discard[H4_DISCARD_LEN]; + size_t to_read = MIN(remaining, sizeof(discard)); + + read = h4_read(hci_uart_dev, discard, to_read); + remaining -= read; + if (remaining == 0) { + state = ST_IDLE; + } + break; + default: + read = 0; + __ASSERT_NO_MSG(0); + break; + + } + } while (read); +} + +static void tx_isr(void) +{ + static struct net_buf *buf; + int len; + + if (!buf) { + buf = net_buf_get(&uart_tx_queue, K_NO_WAIT); + if (!buf) { + uart_irq_tx_disable(hci_uart_dev); + return; + } + } + len = uart_fifo_fill(hci_uart_dev, buf->data, buf->len); + net_buf_pull(buf, len); + if (!buf->len) { + net_buf_unref(buf); + buf = NULL; + } +} + +static void bt_uart_isr(const struct device *unused, void *user_data) +{ + ARG_UNUSED(unused); + ARG_UNUSED(user_data); + + if (!(uart_irq_rx_ready(hci_uart_dev) || uart_irq_tx_ready(hci_uart_dev))) { + LOG_DBG("spurious interrupt"); + } + if (uart_irq_tx_ready(hci_uart_dev)) { + tx_isr(); + } + if (uart_irq_rx_ready(hci_uart_dev)) { + rx_isr(); + } +} + +static void tx_thread(void *p1, void *p2, void *p3) +{ + enum bt_buf_type buf_type; + + while (1) { + struct net_buf *buf; + int err = 0; + uint8_t len; + uint8_t response[16]; + + /* Wait until a buffer is available */ + buf = net_buf_get(&tx_queue, K_FOREVER); + buf_type = bt_buf_get_type(buf); + if (buf_type == H4_ST_VND_CMD) { + len = parse_cmd(buf->data, buf->len, response); + err = send_evt(response, len); + if (!err) { + net_buf_unref(buf); + } + } else { + /* Pass buffer to the stack */ + err = bt_send(buf); + } + if (err) { + LOG_ERR("Unable to send (err %d)", err); + net_buf_unref(buf); + } + + /* Give other threads a chance to run if tx_queue keeps getting + * new data all the time. + */ + k_yield(); + } +} + +static int h4_send(struct net_buf *buf) +{ + LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); + net_buf_put(&uart_tx_queue, buf); + uart_irq_tx_enable(hci_uart_dev); + return 0; +} + +static int hci_uart_init(void) +{ + LOG_DBG(""); + if (!device_is_ready(hci_uart_dev)) { + LOG_ERR("HCI UART %s is not ready", hci_uart_dev->name); + return -EINVAL; + } + uart_irq_rx_disable(hci_uart_dev); + uart_irq_tx_disable(hci_uart_dev); + uart_irq_callback_set(hci_uart_dev, bt_uart_isr); + uart_irq_rx_enable(hci_uart_dev); + return 0; +} + +int main(void) +{ + /* incoming events and data from the controller */ + static K_FIFO_DEFINE(rx_queue); + int err; + + LOG_DBG("Start"); + __ASSERT(hci_uart_dev, "UART device is NULL"); + + /* Enable the raw interface, this will in turn open the HCI driver */ + bt_enable_raw(&rx_queue); + /* Spawn the TX thread and start feeding commands and data to the controller */ + k_thread_create(&tx_thread_data, tx_thread_stack, + K_THREAD_STACK_SIZEOF(tx_thread_stack), tx_thread, + NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + k_thread_name_set(&tx_thread_data, "HCI uart TX"); + + while (1) { + struct net_buf *buf; + + buf = net_buf_get(&rx_queue, K_FOREVER); + err = h4_send(buf); + if (err) { + LOG_ERR("Failed to send"); + } + } + return 0; +} + +SYS_INIT(hci_uart_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/samples/boards/stm32/i2c_timing/CMakeLists.txt b/samples/boards/stm32/i2c_timing/CMakeLists.txt new file mode 100644 index 00000000000000..e9f2b44191722a --- /dev/null +++ b/samples/boards/stm32/i2c_timing/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(i2c_timing) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/boards/stm32/i2c_timing/README.rst b/samples/boards/stm32/i2c_timing/README.rst new file mode 100644 index 00000000000000..a951a0872e22aa --- /dev/null +++ b/samples/boards/stm32/i2c_timing/README.rst @@ -0,0 +1,81 @@ +.. _i2c_config: + +STM32 I2C V2 timings +#################### + +Overview +******** +This sample simply demonstrate the **get_config** API of the stm32 I2C driver. +The I2C peripheral configuration is checked regarding the I2C bitrate which can be: + + - + - + - + + +In case of the I2C V2, the I2C peripheral of the STM32 microcontrollers have +a TIMING register to write in order to generate the correct I2C clock signal. +This value depends on the peripheral clock input and the I2C speed. +The calculation of that TIMING value can be given by the `STM32CubeMX`_ application +**or** by the present sample. + +Because the code sequence to calculate the I2C V2 TIMING value is heavy, +it is not advised to enable it in production binary. +By enabling CONFIG_I2C_STM32_V2_TIMING flag, this sample allows to +retrieve timing register configuration for the defined ``clock-frequency``. +User can then configure timing in his application by adapting the following dts +snippet with the output of this sample: + + + .. code-block:: c + + &i2c { + timings = <160000000 I2C_BITRATE_STANDARD 0xB0C03E40>, + <160000000 I2C_BITRATE_FAST 0xC041090F>, + <160000000 I2C_BITRATE_FAST_PLUS 0x6021050A>; + } + + +Building and Running +******************** + +In order to run this sample, make sure to + +- enable ``i2c`` node in your board DT file. +- enable the CONFIG_I2C_STM32_V2_TIMING=y in the board **conf** file +- alias the **i2c-0** to your ``i2c`` node of the board **overlay** file + + .. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/i2c_config + :board: b_u585i_iot02a + :goals: build + :compact: + +Sample Output +============= +When setting the b_u585i_iot02a.overlay to + + .. code-block:: c + + / { + aliases { + i2c-0 = &i2c2; + }; + }; + &i2c2 { + /delete-property/ clock-frequency; + clock-frequency = ; + }; + +The sample gives the corresponding TIMING value to report to the Device Tree: + +.. code-block:: console + + I2C timing value, report to the DTS : + timings = <160000000 I2C_BITRATE_FAST 0xC041090F>; + + I2C config : I2C_BITRATE_FAST + + +.. _STM32CubeMX: + https://www.st.com/en/development-tools/stm32cubemx.html diff --git a/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay b/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay new file mode 100644 index 00000000000000..a5e6a1ff1cf156 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay @@ -0,0 +1,10 @@ +/ { + aliases { + i2c-0 = &i2c1; + }; +}; + +&i2c1 { + /delete-property/ clock-frequency; + clock-frequency = ; +}; diff --git a/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay b/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay new file mode 100644 index 00000000000000..a5e6a1ff1cf156 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay @@ -0,0 +1,10 @@ +/ { + aliases { + i2c-0 = &i2c1; + }; +}; + +&i2c1 { + /delete-property/ clock-frequency; + clock-frequency = ; +}; diff --git a/samples/boards/stm32/i2c_timing/prj.conf b/samples/boards/stm32/i2c_timing/prj.conf new file mode 100644 index 00000000000000..f5c70dc8a20476 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/prj.conf @@ -0,0 +1,4 @@ +CONFIG_I2C=y +CONFIG_I2C_STM32_V2_TIMING=y +CONFIG_LOG=y +CONFIG_I2C_LOG_LEVEL_INF=y diff --git a/samples/boards/stm32/i2c_timing/sample.yaml b/samples/boards/stm32/i2c_timing/sample.yaml new file mode 100644 index 00000000000000..aacd13ef98d448 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/sample.yaml @@ -0,0 +1,15 @@ +sample: + name: STM32 I2C V2 timing +tests: + sample.boards.stm32.i2c_timing: + depends_on: i2c + tags: + - drivers + - i2c + filter: dt_compat_enabled("st,stm32-i2c-v2") + platform_allow: nucleo_l476rg nucleo_wb55rg + harness: console + harness_config: + type: one_line + regex: + - "I2C freq. I2C_BITRATE_*" diff --git a/samples/boards/stm32/i2c_timing/src/main.c b/samples/boards/stm32/i2c_timing/src/main.c new file mode 100644 index 00000000000000..41b8dfa2dee25d --- /dev/null +++ b/samples/boards/stm32/i2c_timing/src/main.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + + + +#include +#include + + +#if DT_NODE_HAS_STATUS(DT_ALIAS(i2c_0), okay) +#define I2C_DEV_NODE DT_ALIAS(i2c_0) +#else +#error "Please set the correct I2C device" +#endif + +int main(void) +{ + const struct device *const i2c_dev = DEVICE_DT_GET(I2C_DEV_NODE); + uint32_t i2c_cfg; + + if (!device_is_ready(i2c_dev)) { + printk("I2C device is not ready\n"); + return -1; + } + + /* Verify i2c_get_config() */ + if (i2c_get_config(i2c_dev, (uint32_t *)&i2c_cfg)) { + printk("I2C get_config failed\n"); + return -1; + } + + /* I2C BIT RATE */ + printk("\nI2C freq."); + + if ((I2C_SPEED_GET(i2c_cfg) == 1) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 100000)) { + printk(" I2C_BITRATE_STANDARD\n"); + } else if ((I2C_SPEED_GET(i2c_cfg) == 2) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 400000)) { + printk(" I2C_BITRATE_FAST\n"); + } else if ((I2C_SPEED_GET(i2c_cfg) == 3) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 1000000)) { + printk(" I2C_SPEED_FAST_PLUS\n"); + } else { + printk(" I2C speed mismatch (%d)\n", I2C_SPEED_GET(i2c_cfg)); + } + + return 0; +} diff --git a/samples/boards/stm32/power_mgmt/adc/prj.conf b/samples/boards/stm32/power_mgmt/adc/prj.conf index c5359fe02387d4..6c9650f1dfb2bd 100644 --- a/samples/boards/stm32/power_mgmt/adc/prj.conf +++ b/samples/boards/stm32/power_mgmt/adc/prj.conf @@ -1,6 +1,6 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n +CONFIG_PM_DEVICE_SYSTEM_MANAGED=y CONFIG_ADC=y #CONFIG_DEBUG=y diff --git a/samples/boards/stm32/power_mgmt/blinky/prj.conf b/samples/boards/stm32/power_mgmt/blinky/prj.conf index fa60e82b4f0a47..6888f24a03f9a1 100644 --- a/samples/boards/stm32/power_mgmt/blinky/prj.conf +++ b/samples/boards/stm32/power_mgmt/blinky/prj.conf @@ -1,5 +1,5 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n +CONFIG_PM_DEVICE_SYSTEM_MANAGED=y CONFIG_ASSERT=y diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf b/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf index ca1e6cf73a9df2..526010f5d162d9 100644 --- a/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf @@ -1,7 +1,7 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=y +CONFIG_PM_DEVICE_SYSTEM_MANAGED=n CONFIG_SHELL=y diff --git a/samples/boards/stm32/power_mgmt/suspend_to_ram/prj.conf b/samples/boards/stm32/power_mgmt/suspend_to_ram/prj.conf index 78963168c5a812..ce43f3f936fb5c 100644 --- a/samples/boards/stm32/power_mgmt/suspend_to_ram/prj.conf +++ b/samples/boards/stm32/power_mgmt/suspend_to_ram/prj.conf @@ -1,7 +1,7 @@ CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y -CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n +CONFIG_PM_DEVICE_SYSTEM_MANAGED=y CONFIG_PM_S2RAM=y CONFIG_ADC=y CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/CMakeLists.txt b/samples/boards/stm32/power_mgmt/wkup_pins/CMakeLists.txt new file mode 100644 index 00000000000000..f0d58364d27aa9 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stm32_wkup_pins) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/README.rst b/samples/boards/stm32/power_mgmt/wkup_pins/README.rst new file mode 100644 index 00000000000000..3592ca0da55eed --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/README.rst @@ -0,0 +1,38 @@ +.. _gpio-as-a-wkup-pin-src-sample: + +GPIO As A Wake-up Pin Source +############################ + +Overview +******** + +This sample is a minimum application to demonstrate using a wake-up pin with a GPIO as +a source to power on an STM32 SoC after Poweroff. + +The system will power off automatically ``WAIT_TIME_US`` us after boot. +Press the user button designated in boards's devicetree overlay as "wkup-src" to power it on again. + +.. _gpio-as-a-wkup-pin-src-sample-requirements: + +Requirements +************ + +The SoC should support POWEROFF functionality & have a wake-up pin that corresponds +to the GPIO pin of a user button. +To support another board, add an overlay in boards folder. +Make sure that wake-up pins are configured in SoC dtsi file. + +Building and Running +******************** + +Build and flash wkup_pins as follows, changing ``nucleo_u5a5zj_q`` for your board: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/power_mgmt/wkup_pins + :board: nucleo_u5a5zj_q + :goals: build flash + :compact: + +After flashing, the LED in ON. +The LED will be turned off when the system is powered off. +Press the user button to power on the system again. diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay new file mode 100644 index 00000000000000..1dbe5efeec8025 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u575zi_q.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u575zi_q.overlay new file mode 100644 index 00000000000000..1dbe5efeec8025 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u575zi_q.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay new file mode 100644 index 00000000000000..1dbe5efeec8025 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay new file mode 100644 index 00000000000000..7182d8a10affb9 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button_1; + }; +}; + +&user_button_1 { + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP | STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf b/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf new file mode 100644 index 00000000000000..1c68aa590c2de2 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf @@ -0,0 +1,7 @@ +CONFIG_POWEROFF=y +CONFIG_STM32_WKUP_PINS=y +CONFIG_INPUT=y +CONFIG_INPUT_GPIO_KEYS=y +CONFIG_PM=n +CONFIG_PM_DEVICE=n +CONFIG_PM_DEVICE_RUNTIME=n diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml b/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml new file mode 100644 index 00000000000000..1fb3ead82e7293 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: GPIO As A Wake-up Pin Source +tests: + sample.boards.stm32.power_mgmt.wkup_pins: + build_only: true + filter: dt_enabled_alias_with_parent_compat("wkup-src", + "gpio-keys") and dt_compat_enabled("st,stm32-pwr") + platform_allow: + - nucleo_l4r5zi + - nucleo_u575zi_q + - nucleo_u5a5zj_q + - nucleo_wl55jc diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c b/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c new file mode 100644 index 00000000000000..cd7d672cdf6854 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define WAIT_TIME_US 4000000 + +#define WKUP_SRC_NODE DT_ALIAS(wkup_src) +#if !DT_NODE_HAS_STATUS(WKUP_SRC_NODE, okay) +#error "Unsupported board: wkup_src devicetree alias is not defined" +#endif + +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(WKUP_SRC_NODE, gpios); + +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + +int main(void) +{ + __ASSERT_NO_MSG(gpio_is_ready_dt(&button)); + printk("\nWake-up button set up at %s pin %d\n", button.port->name, button.pin); + + __ASSERT_NO_MSG(gpio_is_ready_dt(&led)); + gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); + gpio_pin_set(led.port, led.pin, 1); + + printk("Device is ready\n"); + + printk("Will wait %ds before powering the system off\n", (WAIT_TIME_US / 1000000)); + k_busy_wait(WAIT_TIME_US); + + printk("Powering off\n"); + printk("Press the user button to power the system on\n\n"); + + sys_poweroff(); + /* Will remain powered off until wake-up or reset button is pressed */ + + return 0; +} diff --git a/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000000..7c78d5891d4bae --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Nordic Semiconductor ASA + */ + +/ { + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 7>; + }; +}; + +&adc { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.01 */ + zephyr,resolution = <10>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.02 */ + zephyr,resolution = <12>; + zephyr,oversampling = <8>; + }; + + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.03 */ + zephyr,input-negative = ; /* P1.07 */ + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/efm32pg_stk3402a.overlay b/samples/drivers/adc/adc_dt/boards/slstk3402a.overlay similarity index 100% rename from samples/drivers/adc/adc_dt/boards/efm32pg_stk3402a.overlay rename to samples/drivers/adc/adc_dt/boards/slstk3402a.overlay diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index 2096ad78eb9b45..c758d27e3ad94e 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -15,6 +15,7 @@ tests: - stm32h735g_disco - nrf51dk/nrf51822 - nrf52840dk/nrf52840 + - nrf54l15pdk/nrf54l15/cpuapp - mec172xevb_assy6906 - gd32f350r_eval - gd32f450i_eval diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index 5f6436c076d696..5afd54ead3a290 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -9,6 +9,7 @@ tests: - cy8cproto_063_ble - cy8cproto_062_4343w - nrf52840dk/nrf52840 + - nrf54l15pdk/nrf54l15/cpuapp integration_platforms: - nrf52840dk/nrf52840 harness: console diff --git a/samples/drivers/clock_control_litex/README.rst b/samples/drivers/clock_control_litex/README.rst index c2fa951bd38038..0a7d7878cb2b59 100644 --- a/samples/drivers/clock_control_litex/README.rst +++ b/samples/drivers/clock_control_litex/README.rst @@ -21,16 +21,22 @@ Configuration Basic configuration of the driver, including default settings for clock outputs, is held in Device Tree clock control nodes. .. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi + :language: dts :start-at: clk0: clock-controller@0 { :end-at: }; + :dedent: .. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi + :language: dts :start-at: clk1: clock-controller@1 { :end-at: }; + :dedent: .. literalinclude:: ../../../dts/riscv/riscv32-litex-vexriscv.dtsi + :language: dts :start-at: clock0: clock@e0004800 { :end-at: }; + :dedent: This configuration defines 2 clock outputs: ``clk0`` and ``clk1`` with default frequency set to 100MHz, 0 degrees phase offset and 50% duty cycle. Special care should be taken when defining values for FPGA-specific configuration (parameters from ``litex,divclk-divide-min`` to ``litex,vco-margin``). diff --git a/samples/drivers/counter/maxim_ds3231/README.rst b/samples/drivers/counter/maxim_ds3231/README.rst index ee870006b4b3c7..b0534c806c55f8 100644 --- a/samples/drivers/counter/maxim_ds3231/README.rst +++ b/samples/drivers/counter/maxim_ds3231/README.rst @@ -145,7 +145,7 @@ corresponding devicetree overlay. .. zephyr-app-commands:: :zephyr-app: samples/drivers/counter/maxim_ds3231 - :board: efr32mg_sltb004a + :board: sltb004a :goals: build :compact: diff --git a/samples/drivers/counter/maxim_ds3231/boards/efr32mg_sltb004a.overlay b/samples/drivers/counter/maxim_ds3231/boards/sltb004a.overlay similarity index 100% rename from samples/drivers/counter/maxim_ds3231/boards/efr32mg_sltb004a.overlay rename to samples/drivers/counter/maxim_ds3231/boards/sltb004a.overlay diff --git a/samples/drivers/counter/maxim_ds3231/sample.yaml b/samples/drivers/counter/maxim_ds3231/sample.yaml index bf32d825e7a4c1..238b7a2c816e33 100644 --- a/samples/drivers/counter/maxim_ds3231/sample.yaml +++ b/samples/drivers/counter/maxim_ds3231/sample.yaml @@ -6,10 +6,10 @@ tests: sample.basic.maxim_ds3231: build_only: true platform_allow: - - efr32mg_sltb004a + - sltb004a - frdm_k64f - nrf51dk/nrf51822 - nucleo_l476rg - particle_xenon integration_platforms: - - efr32mg_sltb004a + - sltb004a diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index 50038edf939362..33d72e11c740ba 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -88,12 +88,6 @@ tests: harness: console harness_config: fixture: fixture_display - sample.display.mcux_elcdif: - platform_allow: mimxrt1050_evk - tags: display - harness: console - harness_config: - fixture: fixture_display sample.display.mcux_dcnano_lcdif: platform_allow: mimxrt595_evk/mimxrt595s/cm33 tags: display @@ -175,3 +169,25 @@ tests: harness: console harness_config: fixture: fixture_display + sample.display.rk043fn66hs_ctg: + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk + - mimxrt1050_evk + - mimxrt1040_evk + tags: display + harness: console + extra_args: SHIELD=rk043fn66hs_ctg + harness_config: + fixture: fixture_display + sample.display.rk043fn02h_ct: + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk + - mimxrt1050_evk + - mimxrt1040_evk + tags: display + harness: console + extra_args: SHIELD=rk043fn02h_ct + harness_config: + fixture: fixture_display diff --git a/samples/drivers/espi/boards/mec15xxevb_assy6853.conf b/samples/drivers/espi/boards/mec15xxevb_assy6853.conf index 62985ba39b6f02..fe4958b7645c3a 100644 --- a/samples/drivers/espi/boards/mec15xxevb_assy6853.conf +++ b/samples/drivers/espi/boards/mec15xxevb_assy6853.conf @@ -5,7 +5,7 @@ CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE=n # Sample code doesn't handle ACPI host communication CONFIG_ESPI_PERIPHERAL_HOST_IO=n -# Test SAF flash portal read/erase/write on EVB -CONFIG_ESPI_SAF=y +# Test TAF flash portal read/erase/write on EVB +CONFIG_ESPI_TAF=y CONFIG_SPI=y CONFIG_SPI_XEC_QMSPI=y diff --git a/samples/drivers/espi/boards/mec172xevb_assy6906.conf b/samples/drivers/espi/boards/mec172xevb_assy6906.conf index ecdb27d5f61e9b..de64ab5da46354 100644 --- a/samples/drivers/espi/boards/mec172xevb_assy6906.conf +++ b/samples/drivers/espi/boards/mec172xevb_assy6906.conf @@ -7,7 +7,7 @@ CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE=n # Sample code doesn't handle ACPI host communication CONFIG_ESPI_PERIPHERAL_HOST_IO=n -# Test SAF flash portal read/erase/write on EVB -CONFIG_ESPI_SAF=y +# Test TAF flash portal read/erase/write on EVB +CONFIG_ESPI_TAF=y CONFIG_SPI=y CONFIG_SPI_XEC_QMSPI_LDMA=y diff --git a/samples/drivers/espi/src/main.c b/samples/drivers/espi/src/main.c index a51b79776af66f..fff0998459dbb9 100644 --- a/samples/drivers/espi/src/main.c +++ b/samples/drivers/espi/src/main.c @@ -16,7 +16,7 @@ /* OOB operations will be attempted regardless of channel enabled or not */ #include "espi_oob_handler.h" -#ifdef CONFIG_ESPI_SAF +#ifdef CONFIG_ESPI_TAF #include #endif @@ -65,7 +65,7 @@ static uint8_t flash_write_buf[MAX_TEST_BUF_SIZE]; static uint8_t flash_read_buf[MAX_TEST_BUF_SIZE]; #endif -#ifdef CONFIG_ESPI_SAF +#ifdef CONFIG_ESPI_TAF #define SAF_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(espi_saf0)) #define SAF_TEST_FREQ_HZ 24000000U @@ -128,7 +128,7 @@ static const struct espi_saf_flash_cfg flash_w25q128 = { * by QMSPI driver. * Use SAF hardware default TAG map. */ -#ifdef CONFIG_ESPI_SAF_XEC_V2 +#ifdef CONFIG_ESPI_TAF_XEC_V2 static const struct espi_saf_cfg saf_cfg1 = { .nflash_devices = 1U, .hwcfg = {.version = 2U, /* TODO */ @@ -757,7 +757,7 @@ int espi_saf_test1(uint32_t spi_addr) return rc; } -#endif /* CONFIG_ESPI_SAF */ +#endif /* CONFIG_ESPI_TAF */ static void host_warn_handler(uint32_t signal, uint32_t status) { @@ -1187,7 +1187,7 @@ int espi_test(void) return -ENODEV; } -#ifdef CONFIG_ESPI_SAF +#ifdef CONFIG_ESPI_TAF if (!device_is_ready(qspi_dev)) { LOG_ERR("%s: device not ready.", qspi_dev->name); return -ENODEV; @@ -1223,7 +1223,7 @@ int espi_test(void) espi_init(); -#ifdef CONFIG_ESPI_SAF +#ifdef CONFIG_ESPI_TAF /* * eSPI SAF configuration must be after eSPI configuration. * eSPI SAF EC portal flash tests before EC releases RSMRST# and diff --git a/samples/drivers/flash_shell/sample.yaml b/samples/drivers/flash_shell/sample.yaml index cd19cdad656fc7..2481013c2f5a10 100644 --- a/samples/drivers/flash_shell/sample.yaml +++ b/samples/drivers/flash_shell/sample.yaml @@ -9,6 +9,8 @@ tests: filter: CONFIG_FLASH_HAS_DRIVER_ENABLED platform_exclude: - nucleo_h745zi_q/stm32h745xx/m4 + - stm32h7s78_dk + - stm32h745i_disco/stm32h745xx/m4 - stm32h747i_disco/stm32h747xx/m4 - gd32f350r_eval - arduino_portenta_h7/stm32h747xx/m4 diff --git a/samples/drivers/jesd216/README.rst b/samples/drivers/jesd216/README.rst index 71887480a58ee0..1b9492f619b91b 100644 --- a/samples/drivers/jesd216/README.rst +++ b/samples/drivers/jesd216/README.rst @@ -20,7 +20,7 @@ supports :kconfig:option:`CONFIG_FLASH_JESD216_API`. .. zephyr-app-commands:: :zephyr-app: samples/drivers/jesd216 - :board: efr32mg_sltb004a + :board: sltb004a :goals: build flash :compact: diff --git a/samples/drivers/jesd216/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/jesd216/boards/nrf54h20dk_nrf54h20_cpuapp.overlay deleted file mode 100644 index b8f138ad2b2e21..00000000000000 --- a/samples/drivers/jesd216/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&mx25uw63 { - status = "okay"; -}; diff --git a/samples/drivers/led_is31fl3194/CMakeLists.txt b/samples/drivers/led_is31fl3194/CMakeLists.txt new file mode 100644 index 00000000000000..ed52c77a3fd0e4 --- /dev/null +++ b/samples/drivers/led_is31fl3194/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(led_is31fl3194) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/led_is31fl3194/README.rst b/samples/drivers/led_is31fl3194/README.rst new file mode 100644 index 00000000000000..0773587a4f80e0 --- /dev/null +++ b/samples/drivers/led_is31fl3194/README.rst @@ -0,0 +1,28 @@ +.. zephyr:code-sample:: is31fl3194 + :name: IS31FL3194 RGB LED + :relevant-api: led_interface + + Cycle colors on an RGB LED connected to the IS31FL3194 using the LED API. + +Overview +******** + +This sample cycles several colors on an RGB LED forever using the LED API. + +Building and Running +******************** + +This sample can be built and executed on an Arduino Nicla Sense ME, or on +any board where the devicetree has an I2C device node with compatible +:dtcompatible:`issi,is31fl3194` enabled, along with the relevant bus +controller node also being enabled. + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/led/issi_is31fl3194 + :board: arduino_nicla_sense_me + :goals: build flash + :compact: + +After flashing, the LED starts to switch colors and messages with the current +LED color are printed on the console. If a runtime error occurs, the sample +exits without printing to the console. diff --git a/samples/drivers/led_is31fl3194/prj.conf b/samples/drivers/led_is31fl3194/prj.conf new file mode 100644 index 00000000000000..555740ded902d5 --- /dev/null +++ b/samples/drivers/led_is31fl3194/prj.conf @@ -0,0 +1,2 @@ +CONFIG_LED=y +CONFIG_LOG=y diff --git a/samples/drivers/led_is31fl3194/sample.yaml b/samples/drivers/led_is31fl3194/sample.yaml new file mode 100644 index 00000000000000..0cb932b05d2ee7 --- /dev/null +++ b/samples/drivers/led_is31fl3194/sample.yaml @@ -0,0 +1,10 @@ +sample: + description: Demonstration of the IS31FL3194 LED driver + name: is31fl3194 sample +tests: + sample.drivers.led.is31fl3194: + filter: dt_compat_enabled("issi,is31fl3194") + tags: LED + depends_on: i2c + integration_platforms: + - arduino_nicla_sense_me diff --git a/samples/drivers/led_is31fl3194/src/main.c b/samples/drivers/led_is31fl3194/src/main.c new file mode 100644 index 00000000000000..335d152101b0f2 --- /dev/null +++ b/samples/drivers/led_is31fl3194/src/main.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* 1000 msec = 1 sec */ +#define SLEEP_TIME_MS 1000 + +/* Structure describing a color by its component values and name */ +struct color_data { + uint8_t r, g, b; + const char *name; +}; + +/* The sequence of colors the RGB LED will display */ +static const struct color_data color_sequence[] = { + { 0xFF, 0x00, 0x00, "Red" }, + { 0x00, 0xFF, 0x00, "Green" }, + { 0x00, 0x00, 0xFF, "Blue" }, + { 0xFF, 0xFF, 0xFF, "White" }, + { 0xFF, 0xFF, 0x00, "Yellow" }, + { 0xFF, 0x00, 0xFF, "Purple" }, + { 0x00, 0xFF, 0xFF, "Cyan" }, + { 0xF4, 0x79, 0x20, "Orange" }, +}; + +/* + * A build error on this line means your board is unsupported. + */ +const struct device *led = DEVICE_DT_GET_ANY(issi_is31fl3194); + +int main(void) +{ + int ret; + int i = 0; + + if (!device_is_ready(led)) { + return 0; + } + + while (1) { + ret = led_set_color(led, 0, 3, &(color_sequence[i].r)); + if (ret < 0) { + return 0; + } + + printk("LED color: %s\n", color_sequence[i].name); + k_msleep(SLEEP_TIME_MS); + i = (i + 1) % ARRAY_SIZE(color_sequence); + } + + return 0; +} diff --git a/samples/drivers/led_strip/boards/xiao_rp2040.conf b/samples/drivers/led_strip/boards/xiao_rp2040.conf new file mode 100644 index 00000000000000..8230eb9896b4f5 --- /dev/null +++ b/samples/drivers/led_strip/boards/xiao_rp2040.conf @@ -0,0 +1,2 @@ +CONFIG_GPIO=y +CONFIG_GPIO_HOGS=y diff --git a/samples/drivers/soc_flash_nrf/README.rst b/samples/drivers/soc_flash_nrf/README.rst index 2b69d8d6cb6390..9f34ee631b6e98 100644 --- a/samples/drivers/soc_flash_nrf/README.rst +++ b/samples/drivers/soc_flash_nrf/README.rst @@ -1,5 +1,5 @@ .. zephyr:code-sample:: soc-flash-nrf - :name: nRF SoC flash + :name: nRF SoC Internal Storage :relevant-api: flash_interface flash_area_api Use the flash API to interact with the SoC flash. @@ -7,10 +7,11 @@ Overview ******** -This sample demonstrates using the :ref:`Flash API ` on an SoC internal flash. -The sample uses :ref:`Flash map API ` to obtain device for flash, using -DTS node label, and then directly uses :ref:`Flash API ` to perform -flash operations. +This sample demonstrates using the :ref:`Flash API ` on an SoC internal storage. +The sample uses :ref:`Flash map API ` to obtain a device that has +partition defined with label `storage_partition`, then uses :ref:`Flash API ` +to directly access and modify contents of a device, within area defined for said +partition. Within the sample, user may observe how read/write/erase operations are performed on a device, and how to first check whether device is @@ -19,11 +20,9 @@ ready for operation. Building and Running ******************** -The application will build for any SoC with internal flash memory -access enabled, as it is default for SoC devices, and fixed-partition -defined over that internal flash labeled `slot1_partition`, when -:kconfig:option:`CONFIG_TRUSTED_EXECUTION_NONSECURE` is not selected, -or `slot1_ns_partition`, when the Kconfig option is selected. +The application will build for any SoC with internal storage +access enabled, as it is default for SoC devices with defined +fixed-partition, over that internal storage, labeled `storage_partition`. .. zephyr-app-commands:: :zephyr-app: samples/drivers/soc_flash_nrf @@ -38,8 +37,8 @@ Sample Output *** Booting Zephyr OS build v2.7.99-17621-g54832687bcbb *** - Nordic nRF5 Flash Testing - ========================= + Nordic nRF5 Internal Storage Sample + =================================== Test 1: Flash erase page at 0x82000 Flash erase succeeded! diff --git a/samples/drivers/soc_flash_nrf/src/main.c b/samples/drivers/soc_flash_nrf/src/main.c index 29606a9ca5dfeb..d55214afcc515c 100644 --- a/samples/drivers/soc_flash_nrf/src/main.c +++ b/samples/drivers/soc_flash_nrf/src/main.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Linaro Limited * 2016 Intel Corporation. + * Copyright (c) 2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,9 +28,45 @@ #define FLASH_TEST_OFFSET2 0x41234 #define FLASH_TEST_PAGE_IDX 37 +#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \ + IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) +#define FLASH_PE_RUNTIME_CHECK(cond) (cond) +#elif IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) +#define FLASH_PE_RUNTIME_CHECK(cond) (true) +#else +/* Assumed IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) */ +#define FLASH_PE_RUNTIME_CHECK(cond) (false) +#endif + +/** + * Depending on value of condition erase a device or not. The condition + * is supposed to be value of erase_requirement picked up from + * flash_parameters.flags for device. + */ +static void erase_when_needed(const struct device *dev, bool condition, + uint32_t off, uint32_t size) +{ + /* + * Alwayes invoke erase when there are only erase requiring devices, + * never invoke erase when there are no devices requiring erase, + * always check condition if there are both kind of devices. + */ + if (FLASH_PE_RUNTIME_CHECK(condition)) { + if (flash_erase(dev, off, size) != 0) { + printf(" Erase failed!\n"); + } else { + printf(" Erase succeeded!\n"); + } + } else { + (void)condition; + printf(" Erase not required by device\n"); + } +} + int main(void) { const struct device *flash_dev = TEST_PARTITION_DEVICE; + struct flash_parameters flash_params; uint32_t buf_array_1[4] = { TEST_DATA_WORD_0, TEST_DATA_WORD_1, TEST_DATA_WORD_2, TEST_DATA_WORD_3 }; uint32_t buf_array_2[4] = { TEST_DATA_WORD_3, TEST_DATA_WORD_1, @@ -41,35 +78,35 @@ int main(void) uint32_t buf_word = 0U; uint32_t i, offset; - printf("\nNordic nRF5 Flash Testing\n"); - printf("=========================\n"); + memcpy(&flash_params, flash_get_parameters(flash_dev), sizeof(flash_params)); + + printf("\nNordic nRF5 Internal Storage Sample\n"); + printf("=====================================\n"); if (!device_is_ready(flash_dev)) { - printf("Flash device not ready\n"); + printf("Internal storage device not ready\n"); return 0; } - printf("\nTest 1: Flash erase page at 0x%x\n", TEST_PARTITION_OFFSET); - if (flash_erase(flash_dev, TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE) != 0) { - printf(" Flash erase failed!\n"); - } else { - printf(" Flash erase succeeded!\n"); - } + printf("\nTest 1: Internal storage erase page at 0x%x\n", TEST_PARTITION_OFFSET); + erase_when_needed(flash_dev, + flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT, + TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE); - printf("\nTest 2: Flash write (word array 1)\n"); + printf("\nTest 2: Internal storage write (word array 1)\n"); for (i = 0U; i < ARRAY_SIZE(buf_array_1); i++) { offset = TEST_PARTITION_OFFSET + (i << 2); printf(" Attempted to write %x at 0x%x\n", buf_array_1[i], offset); if (flash_write(flash_dev, offset, &buf_array_1[i], sizeof(uint32_t)) != 0) { - printf(" Flash write failed!\n"); + printf(" Write failed!\n"); return 0; } printf(" Attempted to read 0x%x\n", offset); if (flash_read(flash_dev, offset, &buf_word, sizeof(uint32_t)) != 0) { - printf(" Flash read failed!\n"); + printf(" Read failed!\n"); return 0; } printf(" Data read: %x\n", buf_word); @@ -81,27 +118,24 @@ int main(void) } 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"); - } - - printf("\nTest 4: Flash write (word array 2)\n"); + printf("\nTest 3: Internal storage erase (2 pages at 0x%x)\n", offset); + erase_when_needed(flash_dev, + flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT, + offset, FLASH_PAGE_SIZE * 2); + printf("\nTest 4: Internal storage write (word array 2)\n"); for (i = 0U; i < ARRAY_SIZE(buf_array_2); i++) { offset = TEST_PARTITION_OFFSET + (i << 2); printf(" Attempted to write %x at 0x%x\n", buf_array_2[i], offset); if (flash_write(flash_dev, offset, &buf_array_2[i], sizeof(uint32_t)) != 0) { - printf(" Flash write failed!\n"); + printf(" Write failed!\n"); return 0; } printf(" Attempted to read 0x%x\n", offset); if (flash_read(flash_dev, offset, &buf_word, sizeof(uint32_t)) != 0) { - printf(" Flash read failed!\n"); + printf(" Read failed!\n"); return 0; } printf(" Data read: %x\n", buf_word); @@ -112,12 +146,10 @@ int main(void) } } - printf("\nTest 5: Flash erase page at 0x%x\n", TEST_PARTITION_OFFSET); - if (flash_erase(flash_dev, TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE) != 0) { - printf(" Flash erase failed!\n"); - } else { - printf(" Flash erase succeeded!\n"); - } + printf("\nTest 5: Internal storage erase page at 0x%x\n", TEST_PARTITION_OFFSET); + erase_when_needed(flash_dev, + flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT, + TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE); printf("\nTest 6: Non-word aligned write (word array 3)\n"); for (i = 0U; i < ARRAY_SIZE(buf_array_3); i++) { @@ -126,13 +158,13 @@ int main(void) offset); if (flash_write(flash_dev, offset, &buf_array_3[i], sizeof(uint32_t)) != 0) { - printf(" Flash write failed!\n"); + printf(" Write failed!\n"); return 0; } printf(" Attempted to read 0x%x\n", offset); if (flash_read(flash_dev, offset, &buf_word, sizeof(uint32_t)) != 0) { - printf(" Flash read failed!\n"); + printf(" Read failed!\n"); return 0; } printf(" Data read: %x\n", buf_word); @@ -185,8 +217,7 @@ int main(void) #endif printf("\nTest 8: Write block size API\n"); - printf(" write-block-size = %u\n", - flash_get_write_block_size(flash_dev)); + printf(" write-block-size = %u\n", flash_params.write_block_size); printf("\nFinished!\n"); return 0; diff --git a/samples/drivers/spi_flash/README.rst b/samples/drivers/spi_flash/README.rst index 3767444b3a2c8c..1d48c19af11548 100644 --- a/samples/drivers/spi_flash/README.rst +++ b/samples/drivers/spi_flash/README.rst @@ -15,8 +15,8 @@ savings is correctly implemented. Building and Running ******************** -The application will build only for a target that has a :ref:`devicetree ` -``spi-flash0`` alias that refers to an entry with one of the following bindings as a compatible: +The application will build only for a target that has a devicetree node with one of the +following bindings as a compatible: * :dtcompatible:`jedec,spi-nor`, * :dtcompatible:`st,stm32-qspi-nor`, diff --git a/samples/drivers/spi_flash/boards/adp_xc7k_ae350.overlay b/samples/drivers/spi_flash/boards/adp_xc7k_ae350.overlay deleted file mode 100644 index 653722098eacb0..00000000000000 --- a/samples/drivers/spi_flash/boards/adp_xc7k_ae350.overlay +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2023 Andes Technology Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - aliases { - spi-flash0 = &mx25u16; - }; -}; diff --git a/samples/drivers/spi_flash/boards/mec172xevb_assy6906.overlay b/samples/drivers/spi_flash/boards/mec172xevb_assy6906.overlay index f9fdc2e53680af..54f2957791cc30 100644 --- a/samples/drivers/spi_flash/boards/mec172xevb_assy6906.overlay +++ b/samples/drivers/spi_flash/boards/mec172xevb_assy6906.overlay @@ -4,12 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/ { - aliases { - spi-flash0 = &spi1_cs0_flash; - }; -}; - &spi0 { status = "okay"; compatible = "microchip,xec-qmspi-ldma"; diff --git a/samples/drivers/spi_flash/boards/stm32h573i_dk.overlay b/samples/drivers/spi_flash/boards/stm32h573i_dk.overlay new file mode 100644 index 00000000000000..7d534476876322 --- /dev/null +++ b/samples/drivers/spi_flash/boards/stm32h573i_dk.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&xspi1 { + /* request 57 for XSPI1 */ + dmas = <&gpdma1 4 57 STM32_DMA_PERIPH_TX + &gpdma1 5 57 STM32_DMA_PERIPH_RX>; + dma-names = "tx", "rx"; +}; + +&gpdma1 { + status = "okay"; +}; diff --git a/samples/drivers/spi_flash/src/main.c b/samples/drivers/spi_flash/src/main.c index e456b511030903..b84359ae05bb10 100644 --- a/samples/drivers/spi_flash/src/main.c +++ b/samples/drivers/spi_flash/src/main.c @@ -32,6 +32,20 @@ #define SPI_FLASH_MULTI_SECTOR_TEST #endif +#if DT_HAS_COMPAT_STATUS_OKAY(jedec_spi_nor) +#define SPI_FLASH_COMPAT jedec_spi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_qspi_nor) +#define SPI_FLASH_COMPAT st_stm32_qspi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_ospi_nor) +#define SPI_FLASH_COMPAT st_stm32_ospi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_xspi_nor) +#define SPI_FLASH_COMPAT st_stm32_xspi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_qspi_nor) +#define SPI_FLASH_COMPAT nordic_qspi_nor +#else +#define SPI_FLASH_COMPAT invalid +#endif + const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff }; void single_sector_test(const struct device *flash_dev) @@ -192,7 +206,7 @@ void multi_sector_test(const struct device *flash_dev) int main(void) { - const struct device *flash_dev = DEVICE_DT_GET(DT_ALIAS(spi_flash0)); + const struct device *flash_dev = DEVICE_DT_GET_ONE(SPI_FLASH_COMPAT); if (!device_is_ready(flash_dev)) { printk("%s: device not ready.\n", flash_dev->name); diff --git a/samples/modules/canopennode/README.rst b/samples/modules/canopennode/README.rst index 50b53aab99f1f7..4b735f9b5d7b73 100644 --- a/samples/modules/canopennode/README.rst +++ b/samples/modules/canopennode/README.rst @@ -452,10 +452,10 @@ Sheet (EDS) file https://github.com/CANopenNode/CANopenNode .. _EN 50325-4: - https://can-cia.org/groups/international-standardization/ + https://can-cia.org/cia-groups/international-standardization/ .. _CiA 301: - https://can-cia.org/groups/specifications/ + https://can-cia.org/cia-groups/technical-documents/ .. _CANopen for Python: https://github.com/christiansandberg/canopen diff --git a/samples/modules/canopennode/sample.yaml b/samples/modules/canopennode/sample.yaml index f85c50138bda5c..2a9d0bbd147f26 100644 --- a/samples/modules/canopennode/sample.yaml +++ b/samples/modules/canopennode/sample.yaml @@ -24,6 +24,9 @@ tests: - twr_ke18f integration_platforms: - frdm_k64f - extra_args: canopennode_CONF_FILE=prj_img_mgmt.conf + extra_args: + canopennode_CONF_FILE=prj_img_mgmt.conf + SB_CONFIG_BOOTLOADER_MCUBOOT=y + sample.modules.canopennode.no_storage: extra_args: CONF_FILE=prj_no_storage.conf diff --git a/samples/modules/canopennode/src/main.c b/samples/modules/canopennode/src/main.c index 60c3ebaa6dfe6f..e741f569466aee 100644 --- a/samples/modules/canopennode/src/main.c +++ b/samples/modules/canopennode/src/main.c @@ -15,8 +15,9 @@ LOG_MODULE_REGISTER(app); #define CAN_INTERFACE DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)) -#define CAN_BITRATE (DT_PROP_OR(DT_CHOSEN(zephyr_canbus), bus_speed, \ - CONFIG_CAN_DEFAULT_BITRATE) / 1000) +#define CAN_BITRATE (DT_PROP_OR(DT_CHOSEN(zephyr_canbus), bitrate, \ + DT_PROP_OR(DT_CHOSEN(zephyr_canbus), bus_speed, \ + CONFIG_CAN_DEFAULT_BITRATE)) / 1000) static struct gpio_dt_spec led_green_gpio = GPIO_DT_SPEC_GET_OR( DT_ALIAS(green_led), gpios, {0}); diff --git a/samples/modules/canopennode/sysbuild.conf b/samples/modules/canopennode/sysbuild.conf deleted file mode 100644 index 47f00ff3cff85c..00000000000000 --- a/samples/modules/canopennode/sysbuild.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_BOOTLOADER_MCUBOOT=y diff --git a/samples/modules/cmsis_dsp/moving_average/CMakeLists.txt b/samples/modules/cmsis_dsp/moving_average/CMakeLists.txt new file mode 100644 index 00000000000000..64052f8e1c4cad --- /dev/null +++ b/samples/modules/cmsis_dsp/moving_average/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(moving_average) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/modules/cmsis_dsp/moving_average/README.rst b/samples/modules/cmsis_dsp/moving_average/README.rst new file mode 100644 index 00000000000000..dd99f5885e3a5a --- /dev/null +++ b/samples/modules/cmsis_dsp/moving_average/README.rst @@ -0,0 +1,63 @@ +.. zephyr:code-sample:: cmsis-dsp-moving-average + :name: CMSIS-DSP moving average + + Use the CMSIS-DSP library to calculate the moving average of a signal. + +Overview +******** + +This sample demonstrates how to use the CMSIS-DSP library to calculate the moving average of a +signal. + +It can be run on any board supported in Zephyr, but note that CMSIS-DSP is specifically optimized +for ARM Cortex-A and Cortex-M processors. + +A **moving average** filter is a common method used for smoothing noisy data. It can be implemented +as a finite impulse response (FIR) filter where the filter coefficients are all equal to 1/N, where +N is the number of "taps" (i.e. the size of the moving average window). + +The sample uses a very simple input signal of 32 samples, and computes the moving average using a +"window" of 10 samples. The resulting output is computed in one single call to the ``arm_fir_q31()`` +CMSIS-DSP function, and displayed on the console. + +.. note:: + In order to allow an easy comparison of the efficiency of the CMSIS-DSP library when used on ARM + processors vs. other architectures, the sample outputs the time and number of cycles it took to + compute the moving average. + +Requirements +************ + +CMSIS-DSP is an optional module and needs to be added explicitly to your Zephyr workspace: + +.. code-block:: shell + + west config manifest.project-filter -- +cmsis-dsp + west update cmsis-dsp + +Building and Running +********************* + +The demo can be built as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/cmsis-dsp/moving_average + :host-os: unix + :board: qemu_cortex_m0 + :goals: run + :compact: + +The sample will output the number of cycles it took to compute the moving averages, as well as the +computed average for each 10-sample long window of the input signal. + +.. code-block:: console + + *** Booting Zephyr OS build v3.6.0-224-gb55824751d6c *** + Time: 244 us (244 cycles) + Input[00]: 0 0 0 0 0 0 0 0 0 0 | Output[00]: 0.00 + Input[01]: 0 0 0 0 0 0 0 0 0 1 | Output[01]: 0.10 + Input[02]: 0 0 0 0 0 0 0 0 1 2 | Output[02]: 0.30 + Input[03]: 0 0 0 0 0 0 0 1 2 3 | Output[03]: 0.60 + ... + Input[30]: 21 22 23 24 25 26 27 28 29 30 | Output[30]: 25.50 + Input[31]: 22 23 24 25 26 27 28 29 30 31 | Output[31]: 26.50 diff --git a/samples/modules/cmsis_dsp/moving_average/prj.conf b/samples/modules/cmsis_dsp/moving_average/prj.conf new file mode 100644 index 00000000000000..73412a76fb0ad5 --- /dev/null +++ b/samples/modules/cmsis_dsp/moving_average/prj.conf @@ -0,0 +1,5 @@ +CONFIG_REQUIRES_FULL_LIBC=y +CONFIG_REQUIRES_FLOAT_PRINTF=y + +CONFIG_CMSIS_DSP=y +CONFIG_CMSIS_DSP_FILTERING=y diff --git a/samples/modules/cmsis_dsp/moving_average/sample.yaml b/samples/modules/cmsis_dsp/moving_average/sample.yaml new file mode 100644 index 00000000000000..2bcc8359158f8e --- /dev/null +++ b/samples/modules/cmsis_dsp/moving_average/sample.yaml @@ -0,0 +1,48 @@ +sample: + description: Use CMSIS DSP to calculate moving average + name: CMSIS DSP Moving Average +tests: + sample.modules.cmsis_dsp.moving_average: + tags: + - samples + integration_platforms: + - qemu_cortex_m0 + - native_sim + modules: + - cmsis-dsp + harness: console + harness_config: + type: multi_line + regex: + - "Input\\[00\\]: 0 0 0 0 0 0 0 0 0 0 | Output\\[00\\]: 0.00" + - "Input\\[01\\]: 0 0 0 0 0 0 0 0 0 1 | Output\\[01\\]: 0.10" + - "Input\\[02\\]: 0 0 0 0 0 0 0 0 1 2 | Output\\[02\\]: 0.30" + - "Input\\[03\\]: 0 0 0 0 0 0 0 1 2 3 | Output\\[03\\]: 0.60" + - "Input\\[04\\]: 0 0 0 0 0 0 1 2 3 4 | Output\\[04\\]: 1.00" + - "Input\\[05\\]: 0 0 0 0 0 1 2 3 4 5 | Output\\[05\\]: 1.50" + - "Input\\[06\\]: 0 0 0 0 1 2 3 4 5 6 | Output\\[06\\]: 2.10" + - "Input\\[07\\]: 0 0 0 1 2 3 4 5 6 7 | Output\\[07\\]: 2.80" + - "Input\\[08\\]: 0 0 1 2 3 4 5 6 7 8 | Output\\[08\\]: 3.60" + - "Input\\[09\\]: 0 1 2 3 4 5 6 7 8 9 | Output\\[09\\]: 4.50" + - "Input\\[10\\]: 1 2 3 4 5 6 7 8 9 10 | Output\\[10\\]: 5.50" + - "Input\\[11\\]: 2 3 4 5 6 7 8 9 10 11 | Output\\[11\\]: 6.50" + - "Input\\[12\\]: 3 4 5 6 7 8 9 10 11 12 | Output\\[12\\]: 7.50" + - "Input\\[13\\]: 4 5 6 7 8 9 10 11 12 13 | Output\\[13\\]: 8.50" + - "Input\\[14\\]: 5 6 7 8 9 10 11 12 13 14 | Output\\[14\\]: 9.50" + - "Input\\[15\\]: 6 7 8 9 10 11 12 13 14 15 | Output\\[15\\]: 10.50" + - "Input\\[16\\]: 7 8 9 10 11 12 13 14 15 16 | Output\\[16\\]: 11.50" + - "Input\\[17\\]: 8 9 10 11 12 13 14 15 16 17 | Output\\[17\\]: 12.50" + - "Input\\[18\\]: 9 10 11 12 13 14 15 16 17 18 | Output\\[18\\]: 13.50" + - "Input\\[19\\]: 10 11 12 13 14 15 16 17 18 19 | Output\\[19\\]: 14.50" + - "Input\\[20\\]: 11 12 13 14 15 16 17 18 19 20 | Output\\[20\\]: 15.50" + - "Input\\[21\\]: 12 13 14 15 16 17 18 19 20 21 | Output\\[21\\]: 16.50" + - "Input\\[22\\]: 13 14 15 16 17 18 19 20 21 22 | Output\\[22\\]: 17.50" + - "Input\\[23\\]: 14 15 16 17 18 19 20 21 22 23 | Output\\[23\\]: 18.50" + - "Input\\[24\\]: 15 16 17 18 19 20 21 22 23 24 | Output\\[24\\]: 19.50" + - "Input\\[25\\]: 16 17 18 19 20 21 22 23 24 25 | Output\\[25\\]: 20.50" + - "Input\\[26\\]: 17 18 19 20 21 22 23 24 25 26 | Output\\[26\\]: 21.50" + - "Input\\[27\\]: 18 19 20 21 22 23 24 25 26 27 | Output\\[27\\]: 22.50" + - "Input\\[28\\]: 19 20 21 22 23 24 25 26 27 28 | Output\\[28\\]: 23.50" + - "Input\\[29\\]: 20 21 22 23 24 25 26 27 28 29 | Output\\[29\\]: 24.50" + - "Input\\[30\\]: 21 22 23 24 25 26 27 28 29 30 | Output\\[30\\]: 25.50" + - "Input\\[31\\]: 22 23 24 25 26 27 28 29 30 31 | Output\\[31\\]: 26.50" diff --git a/samples/modules/cmsis_dsp/moving_average/src/main.c b/samples/modules/cmsis_dsp/moving_average/src/main.c new file mode 100644 index 00000000000000..bab71912c185b6 --- /dev/null +++ b/samples/modules/cmsis_dsp/moving_average/src/main.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Benjamin Cabé + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "arm_math.h" + +#define NUM_TAPS 10 /* Number of taps in the FIR filter (length of the moving average window) */ +#define BLOCK_SIZE 32 /* Number of samples processed per block */ + +/* + * Filter coefficients are all equal for a moving average filter. Here, 1/NUM_TAPS = 0.1f. + */ +q31_t firCoeffs[NUM_TAPS] = {0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, + 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD}; + +arm_fir_instance_q31 sFIR; +q31_t firState[NUM_TAPS + BLOCK_SIZE - 1]; + +int main(void) +{ + q31_t input[BLOCK_SIZE]; + q31_t output[BLOCK_SIZE]; + uint32_t start, end; + + /* Initialize input data with a ramp from 0 to 31 */ + for (int i = 0; i < BLOCK_SIZE; i++) { + input[i] = i << 24; /* Convert to Q31 format */ + } + + /* Initialize the FIR filter */ + arm_fir_init_q31(&sFIR, NUM_TAPS, firCoeffs, firState, BLOCK_SIZE); + + /* Apply the FIR filter to the input data and measure how many cycles this takes */ + start = k_cycle_get_32(); + arm_fir_q31(&sFIR, input, output, BLOCK_SIZE); + end = k_cycle_get_32(); + + printf("Time: %u us (%u cycles)\n", k_cyc_to_us_floor32(end - start), end - start); + + for (int i = 0; i < BLOCK_SIZE; i++) { + printf("Input[%02d]: ", i); + for (int j = NUM_TAPS - 1; j >= 0; j--) { + if (j <= i) { + printf("%2d ", (int)(input[i - j] >> 24)); + } else { + printf("%2d ", 0); + } + } + printf("| Output[%02d]: %6.2f\n", i, (double)output[i] / (1 << 24)); + } + + return 0; +} diff --git a/samples/modules/thrift/hello/client/prj.conf b/samples/modules/thrift/hello/client/prj.conf index a83715ddfc792c..0f094d14d6c2e2 100644 --- a/samples/modules/thrift/hello/client/prj.conf +++ b/samples/modules/thrift/hello/client/prj.conf @@ -28,7 +28,7 @@ CONFIG_NET_TCP=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONNECTION_MANAGER=y # Kernel options @@ -61,7 +61,7 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # Number of socket descriptors might need adjusting # if there are more than 1 handlers defined. -CONFIG_POSIX_MAX_FDS=16 +CONFIG_ZVFS_OPEN_MAX=16 # Some platforms require relatively large stack sizes. # This can be tuned per-board. diff --git a/samples/modules/thrift/hello/server/prj.conf b/samples/modules/thrift/hello/server/prj.conf index 1aacd9d14d758f..fe78b9a2803a59 100644 --- a/samples/modules/thrift/hello/server/prj.conf +++ b/samples/modules/thrift/hello/server/prj.conf @@ -51,7 +51,7 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # Number of socket descriptors might need adjusting # if there are more than 1 handlers defined. -CONFIG_POSIX_MAX_FDS=16 +CONFIG_ZVFS_OPEN_MAX=16 # Some platforms require relatively large stack sizes. # This can be tuned per-board. diff --git a/samples/net/cellular_modem/prj.conf b/samples/net/cellular_modem/prj.conf index 4656fe52d651bc..d51e0cc7a270e7 100644 --- a/samples/net/cellular_modem/prj.conf +++ b/samples/net/cellular_modem/prj.conf @@ -30,6 +30,11 @@ CONFIG_MODEM_CELLULAR=y CONFIG_MODEM_STATS=y CONFIG_SHELL=y +# Testing +CONFIG_MODEM_AT_SHELL=y +CONFIG_PM_DEVICE_SHELL=y +CONFIG_SHELL_WILDCARD=n + # Logging CONFIG_LOG=y CONFIG_MODEM_MODULES_LOG_LEVEL_DBG=y diff --git a/samples/net/cloud/aws_iot_mqtt/prj.conf b/samples/net/cloud/aws_iot_mqtt/prj.conf index 30277ffb18c187..fbede2f3bf946f 100644 --- a/samples/net/cloud/aws_iot_mqtt/prj.conf +++ b/samples/net/cloud/aws_iot_mqtt/prj.conf @@ -13,7 +13,6 @@ CONFIG_HW_STACK_PROTECTION=y CONFIG_REQUIRES_FULL_LIBC=y CONFIG_SNTP=y CONFIG_JSON_LIBRARY=y -CONFIG_POSIX_CLOCK=y CONFIG_POSIX_API=y # DNS diff --git a/samples/net/cloud/mqtt_azure/prj.conf b/samples/net/cloud/mqtt_azure/prj.conf index 2a88f746f5ff26..b857f7e43176cb 100644 --- a/samples/net/cloud/mqtt_azure/prj.conf +++ b/samples/net/cloud/mqtt_azure/prj.conf @@ -33,6 +33,12 @@ CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=100000 CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=10240 CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y +CONFIG_MBEDTLS_SHA1=y +CONFIG_MBEDTLS_SHA384=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECP_C=y # Network configuration CONFIG_NET_CONFIG_SETTINGS=y diff --git a/samples/net/cloud/mqtt_azure/src/digicert.cer b/samples/net/cloud/mqtt_azure/src/digicert.cer index cb0db66eb25a1c..f019ce68040340 100644 --- a/samples/net/cloud/mqtt_azure/src/digicert.cer +++ b/samples/net/cloud/mqtt_azure/src/digicert.cer @@ -1,3 +1,4 @@ +/* Baltimore CyberTrust Root */ "-----BEGIN CERTIFICATE-----\r\n" "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n" "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n" @@ -19,3 +20,62 @@ "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n" "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n" "-----END CERTIFICATE-----\r\n" + +/* DigiCert Global Root G2 */ +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\r\n" +"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n" +"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\r\n" +"MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\r\n" +"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\n" +"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\r\n" +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\r\n" +"2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\r\n" +"1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\r\n" +"q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\r\n" +"tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\r\n" +"vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\r\n" +"BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\r\n" +"5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\r\n" +"1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\r\n" +"NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\r\n" +"Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\r\n" +"8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\r\n" +"pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\r\n" +"MrY=\r\n" +"-----END CERTIFICATE-----\r\n" + +/* Microsoft RSA Root Certificate Authority 2017 */ +"-----BEGIN CERTIFICATE-----\r\n" +"MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl\r\n" +"MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw\r\n" +"NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\r\n" +"IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG\r\n" +"EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N\r\n" +"aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi\r\n" +"MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ\r\n" +"Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0\r\n" +"ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1\r\n" +"HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm\r\n" +"gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ\r\n" +"jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc\r\n" +"aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG\r\n" +"YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6\r\n" +"W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K\r\n" +"UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH\r\n" +"+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q\r\n" +"W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/\r\n" +"BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC\r\n" +"NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC\r\n" +"LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC\r\n" +"gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6\r\n" +"tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh\r\n" +"SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2\r\n" +"TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3\r\n" +"pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR\r\n" +"xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp\r\n" +"GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9\r\n" +"dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN\r\n" +"AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB\r\n" +"RA+GsCyRxj3qrg+E\r\n" +"-----END CERTIFICATE-----\r\n" diff --git a/samples/net/gptp/sample.yaml b/samples/net/gptp/sample.yaml index b0a49d2413910b..44bf695d628daa 100644 --- a/samples/net/gptp/sample.yaml +++ b/samples/net/gptp/sample.yaml @@ -17,6 +17,7 @@ tests: - native_sim/native/64 - nucleo_f767zi - nucleo_h743zi + - nucleo_h753zi - nucleo_h745zi_q/stm32h745xx/m7 depends_on: eth integration_platforms: diff --git a/samples/net/mqtt_sn_publisher/prj.conf b/samples/net/mqtt_sn_publisher/prj.conf index 367ba8082f489f..efe1a8f3e207ec 100644 --- a/samples/net/mqtt_sn_publisher/prj.conf +++ b/samples/net/mqtt_sn_publisher/prj.conf @@ -5,7 +5,7 @@ CONFIG_NET_IPV4=y CONFIG_NET_IPV6=n CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONNECTION_MANAGER=y # Kernel options diff --git a/samples/net/ptp/CMakeLists.txt b/samples/net/ptp/CMakeLists.txt new file mode 100644 index 00000000000000..edbda19d0c925b --- /dev/null +++ b/samples/net/ptp/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib) + +project(ptp) +target_sources(app PRIVATE src/main.c) diff --git a/samples/net/ptp/Kconfig b/samples/net/ptp/Kconfig new file mode 100644 index 00000000000000..620b26fac4f60d --- /dev/null +++ b/samples/net/ptp/Kconfig @@ -0,0 +1,18 @@ +# Private config options for PTP sample app + +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "PTP sample application" + +if PTP + +config NET_SAMPLE_RUN_DURATION + int "Run the application this many seconds" + default 0 + help + A value of zero means that the sample application is run forever. + +endif + +source "Kconfig.zephyr" diff --git a/samples/net/ptp/README.rst b/samples/net/ptp/README.rst new file mode 100644 index 00000000000000..71343931c550c7 --- /dev/null +++ b/samples/net/ptp/README.rst @@ -0,0 +1,70 @@ +.. zephyr:code-sample:: ptp + :name: PTP + :relevant-api: ptp ptp_time ptp_clock + + Enable PTP support and monitor messages and events via logging. + +Overview +******** + +The PTP sample application for Zephyr will enable PTP support. + +The source code for this sample application can be found at: +:zephyr_file:`samples/net/ptp`. + +Requirements +************ + +For generic host connectivity, that can be used for debugging purposes, see +:ref:`networking_with_native_sim` for details. + +Building and Running +******************** + +A good way to run this sample is to run this PTP application inside +native_sim board as described in :ref:`networking_with_native_sim` or with +embedded device like Nucleo-H743-ZI, Nucleo-H745ZI-Q, Nucleo-F767ZI or +Nucleo-H563ZI. Note that PTP is only supported for +boards that have an Ethernet port and which has support for collecting +timestamps for sent and received Ethernet frames. + +Follow these steps to build the PTP sample application: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/ptp + :board: + :goals: build + :compact: + +Setting up Linux Host +===================== + +By default PTP in Zephyr will not print any PTP debug messages to console. +One can enable debug prints by setting +:kconfig:option:`CONFIG_PTP_LOG_LEVEL_DBG` in the config file. + +Get linuxptp project sources + +.. code-block:: console + + git clone git://git.code.sf.net/p/linuxptp/code + +Compile the ``ptp4l`` daemon and start it like this: + +.. code-block:: console + + sudo ./ptp4l -4 -f -i zeth -m -q -l 6 -S + +Compile Zephyr application. + +.. zephyr-app-commands:: + :zephyr-app: samples/net/ptp + :board: native_sim + :goals: build + :compact: + +When the Zephyr image is build, you can start it like this: + +.. code-block:: console + + build/zephyr/zephyr.exe -attach_uart diff --git a/samples/net/ptp/boards/native_posix.conf b/samples/net/ptp/boards/native_posix.conf new file mode 100644 index 00000000000000..e2f26372eede3d --- /dev/null +++ b/samples/net/ptp/boards/native_posix.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_PTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/ptp/boards/native_posix_native_64.conf b/samples/net/ptp/boards/native_posix_native_64.conf new file mode 100644 index 00000000000000..e2f26372eede3d --- /dev/null +++ b/samples/net/ptp/boards/native_posix_native_64.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_PTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/ptp/boards/native_sim.conf b/samples/net/ptp/boards/native_sim.conf new file mode 100644 index 00000000000000..e2f26372eede3d --- /dev/null +++ b/samples/net/ptp/boards/native_sim.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_PTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/ptp/boards/native_sim_native_64.conf b/samples/net/ptp/boards/native_sim_native_64.conf new file mode 100644 index 00000000000000..e2f26372eede3d --- /dev/null +++ b/samples/net/ptp/boards/native_sim_native_64.conf @@ -0,0 +1,8 @@ +# Settings for native_posix ethernet driver +CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK=y + +#CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC=y +CONFIG_ETH_NATIVE_POSIX_MAC_ADDR="00:00:5e:00:53:2a" + +# Assume 1 ms accuracy for native_posix simulated clock +CONFIG_PTP_CLOCK_ACCURACY_1MS=y diff --git a/samples/net/ptp/boards/qemu_x86.conf b/samples/net/ptp/boards/qemu_x86.conf new file mode 100644 index 00000000000000..e32acfe7b5aa22 --- /dev/null +++ b/samples/net/ptp/boards/qemu_x86.conf @@ -0,0 +1 @@ +CONFIG_USERSPACE=n diff --git a/samples/net/ptp/docker-test.sh b/samples/net/ptp/docker-test.sh new file mode 100644 index 00000000000000..1eb5d2b8beeb80 --- /dev/null +++ b/samples/net/ptp/docker-test.sh @@ -0,0 +1,29 @@ +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +if [ -z "$RUNNING_FROM_MAIN_SCRIPT" ]; then + echo "Do not run this script directly!" + echo "Run $ZEPHYR_BASE/scripts/net/run-sample-tests.sh instead." + exit 1 +fi + +# Running PTP sample using Docker testing + +start_configuration || return $? +start_docker \ + "/usr/local/sbin/ptp4l -4 -f /etc/gptp.cfg -m -q -l 6 -S -i eth0" \ + || return $? + +# For native_sim PTP run, the delay threshold needs to be huge +start_zephyr "$overlay" "-DCONFIG_NET_SAMPLE_RUN_DURATION=15" \ + +wait_zephyr +ptp_result=$? + +if [ $ptp_result -eq 1 -o $ptp_result -eq 2 ]; then + result=0 +else + result=1 +fi + +stop_docker diff --git a/samples/net/ptp/prj.conf b/samples/net/ptp/prj.conf new file mode 100644 index 00000000000000..2c4e13f8389818 --- /dev/null +++ b/samples/net/ptp/prj.conf @@ -0,0 +1,35 @@ +CONFIG_NETWORKING=y +CONFIG_NET_LOG=y +CONFIG_LOG=y +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=n +CONFIG_NET_UDP=y + +CONFIG_TEST_RANDOM_GENERATOR=y + +CONFIG_NET_PKT_RX_COUNT=32 +CONFIG_NET_PKT_TX_COUNT=32 +CONFIG_NET_BUF_RX_COUNT=32 +CONFIG_NET_BUF_TX_COUNT=32 +CONFIG_NET_MAX_CONTEXTS=10 + +CONFIG_INIT_STACKS=y +CONFIG_PRINTK=y +CONFIG_NET_SHELL=y + +# Ethernet is needed for PTP +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_SETTINGS=y + +# First ethernet interface will use these settings +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +# PTP settings +CONFIG_PTP_CLOCK=y +CONFIG_PTP=y +CONFIG_PTP_LOG_LEVEL_DBG=y + +CONFIG_LOG_MODE_DEFERRED=y diff --git a/samples/net/ptp/sample.yaml b/samples/net/ptp/sample.yaml new file mode 100644 index 00000000000000..706a88f03c93cf --- /dev/null +++ b/samples/net/ptp/sample.yaml @@ -0,0 +1,20 @@ +common: + harness: net + tags: + - net + - ptp +sample: + description: Test PTP functionality + name: PTP sample app +tests: + sample.net.ptp: + platform_allow: + - native_sim + - native_sim/native/64 + - nucleo_h563zi + - nucleo_h743zi + - nucleo_h745zi_q/stm32h745xx/m7 + - qemu_x86 + depends_on: eth + integration_platforms: + - nucleo_h563zi diff --git a/samples/net/ptp/src/main.c b/samples/net/ptp/src/main.c new file mode 100644 index 00000000000000..97672dc14f2749 --- /dev/null +++ b/samples/net/ptp/src/main.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 BayLibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_ptp_sample, LOG_LEVEL_DBG); + +#include + +#include +#include + +#include "ptp/clock.h" +#include "ptp/port.h" + +static int run_duration = CONFIG_NET_SAMPLE_RUN_DURATION; +static struct k_work_delayable stop_sample; +static struct k_sem quit_lock; + +static void stop_handler(struct k_work *work) +{ + ARG_UNUSED(work); + + k_sem_give(&quit_lock); +} + +static int get_current_status(void) +{ + struct ptp_port *port; + sys_slist_t *ports_list = ptp_clock_ports_list(); + + if (!ports_list || sys_slist_len(ports_list) == 0) { + return -EINVAL; + } + + port = CONTAINER_OF(sys_slist_peek_head(ports_list), struct ptp_port, node); + + if (!port) { + return -EINVAL; + } + + switch (ptp_port_state(port)) { + case PTP_PS_INITIALIZING: + case PTP_PS_FAULTY: + case PTP_PS_DISABLED: + case PTP_PS_LISTENING: + case PTP_PS_PRE_TIME_TRANSMITTER: + case PTP_PS_PASSIVE: + case PTP_PS_UNCALIBRATED: + printk("FAIL\n"); + return 0; + case PTP_PS_TIME_RECEIVER: + printk("TIME RECEIVER\n"); + return 2; + case PTP_PS_TIME_TRANSMITTER: + case PTP_PS_GRAND_MASTER: + printk("TIME TRANSMITTER\n"); + return 1; + } + + return -1; +} + +void init_testing(void) +{ + uint32_t uptime = k_uptime_get_32(); + int ret; + + if (run_duration == 0) { + return; + } + + k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT); + + k_work_init_delayable(&stop_sample, stop_handler); + k_work_reschedule(&stop_sample, K_SECONDS(run_duration)); + + k_sem_take(&quit_lock, K_FOREVER); + + LOG_INF("Stopping after %u seconds", + (k_uptime_get_32() - uptime) / 1000); + + /* Try to figure out what is the sync state. + * Return: + * <0 - configuration error + * 0 - not time sync + * 1 - we are TimeTransmitter + * 2 - we are TimeReceiver + */ + ret = get_current_status(); + + exit(ret); +} + +int main(void) +{ + init_testing(); + return 0; +} diff --git a/samples/net/sockets/big_http_download/sample.yaml b/samples/net/sockets/big_http_download/sample.yaml index 683b8c5c52c0dd..d27f131836da1e 100644 --- a/samples/net/sockets/big_http_download/sample.yaml +++ b/samples/net/sockets/big_http_download/sample.yaml @@ -4,6 +4,7 @@ sample: common: filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC harness: net + depends_on: netif min_ram: 32 min_flash: 128 tags: diff --git a/samples/net/sockets/dumb_http_server_mt/prj.conf b/samples/net/sockets/dumb_http_server_mt/prj.conf index af851a0406e3ee..7b802e6e8b4824 100644 --- a/samples/net/sockets/dumb_http_server_mt/prj.conf +++ b/samples/net/sockets/dumb_http_server_mt/prj.conf @@ -2,7 +2,7 @@ CONFIG_TEST_RANDOM_GENERATOR=y # POSIX options -CONFIG_POSIX_MAX_FDS=20 +CONFIG_ZVFS_OPEN_MAX=20 CONFIG_POSIX_API=y # Networking config diff --git a/samples/net/sockets/dumb_http_server_mt/sample.yaml b/samples/net/sockets/dumb_http_server_mt/sample.yaml index dc0c81822468e0..4d278431c22416 100644 --- a/samples/net/sockets/dumb_http_server_mt/sample.yaml +++ b/samples/net/sockets/dumb_http_server_mt/sample.yaml @@ -3,6 +3,7 @@ sample: name: socket_dumb_http_server_mt common: harness: net + depends_on: netif min_ram: 128 min_flash: 128 tags: diff --git a/samples/net/sockets/echo_client/overlay-tls.conf b/samples/net/sockets/echo_client/overlay-tls.conf index 8235291cefc194..b6183e9f14daa5 100644 --- a/samples/net/sockets/echo_client/overlay-tls.conf +++ b/samples/net/sockets/echo_client/overlay-tls.conf @@ -12,4 +12,4 @@ CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048 CONFIG_NET_SOCKETS_SOCKOPT_TLS=y CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 CONFIG_NET_SOCKETS_ENABLE_DTLS=y -CONFIG_POSIX_MAX_FDS=8 +CONFIG_ZVFS_OPEN_MAX=8 diff --git a/samples/net/sockets/echo_server/overlay-tls.conf b/samples/net/sockets/echo_server/overlay-tls.conf index f9d650ecd02936..fa91a0f6258b57 100644 --- a/samples/net/sockets/echo_server/overlay-tls.conf +++ b/samples/net/sockets/echo_server/overlay-tls.conf @@ -13,4 +13,4 @@ CONFIG_NET_SOCKETS_SOCKOPT_TLS=y CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 CONFIG_NET_SOCKETS_ENABLE_DTLS=y CONFIG_NET_SOCKETS_DTLS_TIMEOUT=30000 -CONFIG_POSIX_MAX_FDS=16 +CONFIG_ZVFS_OPEN_MAX=16 diff --git a/samples/net/sockets/echo_server/prj.conf b/samples/net/sockets/echo_server/prj.conf index e88c98eda39562..c95e09b71b85fb 100644 --- a/samples/net/sockets/echo_server/prj.conf +++ b/samples/net/sockets/echo_server/prj.conf @@ -6,7 +6,7 @@ CONFIG_NET_IPV6=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONNECTION_MANAGER=y # Kernel options @@ -48,7 +48,7 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # Number of socket descriptors might need adjusting # if there are more than 1 handlers defined. -CONFIG_POSIX_MAX_FDS=12 +CONFIG_ZVFS_OPEN_MAX=12 # How many client can connect to echo-server simultaneously CONFIG_NET_SAMPLE_NUM_HANDLERS=1 diff --git a/samples/net/sockets/echo_service/prj.conf b/samples/net/sockets/echo_service/prj.conf index d7ffe738352806..b9c053c27a2b6d 100644 --- a/samples/net/sockets/echo_service/prj.conf +++ b/samples/net/sockets/echo_service/prj.conf @@ -10,7 +10,7 @@ CONFIG_NET_IPV6=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y CONFIG_NET_IPV4_MAPPING_TO_IPV6=y -CONFIG_POSIX_MAX_FDS=10 +CONFIG_ZVFS_OPEN_MAX=10 CONFIG_NET_MAX_CONN=5 CONFIG_NET_SOCKETS_SERVICE=y CONFIG_NET_SOCKETS_POLL_MAX=20 diff --git a/samples/net/sockets/http_get/sample.yaml b/samples/net/sockets/http_get/sample.yaml index 94f7cd6f8ddd9b..2aba5c7d60d8ce 100644 --- a/samples/net/sockets/http_get/sample.yaml +++ b/samples/net/sockets/http_get/sample.yaml @@ -3,6 +3,7 @@ sample: name: socket_http_get common: filter: CONFIG_FULL_LIBC_SUPPORTED + depends_on: netif min_ram: 32 min_flash: 80 tags: diff --git a/samples/net/sockets/http_server/prj.conf b/samples/net/sockets/http_server/prj.conf index 3d13a55cbf29b4..c9c80be2429dd3 100644 --- a/samples/net/sockets/http_server/prj.conf +++ b/samples/net/sockets/http_server/prj.conf @@ -5,7 +5,7 @@ CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y -CONFIG_POSIX_MAX_FDS=32 +CONFIG_ZVFS_OPEN_MAX=32 CONFIG_POSIX_API=y CONFIG_FDTABLE=y CONFIG_NET_SOCKETS_POLL_MAX=32 @@ -61,6 +61,7 @@ CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=60000 CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048 +CONFIG_MBEDTLS_USE_PSA_CRYPTO=n CONFIG_NET_SOCKETS_SOCKOPT_TLS=y CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 CONFIG_TLS_CREDENTIALS=y diff --git a/samples/net/sockets/http_server/sample.yaml b/samples/net/sockets/http_server/sample.yaml index eeaca47d386eda..8af05127cd4b40 100644 --- a/samples/net/sockets/http_server/sample.yaml +++ b/samples/net/sockets/http_server/sample.yaml @@ -3,6 +3,7 @@ sample: name: http_server_sample common: harness: net + depends_on: netif min_ram: 192 tags: - http diff --git a/samples/net/sockets/net_mgmt/prj.conf b/samples/net/sockets/net_mgmt/prj.conf index 243cce2173552c..a94f5da00948d3 100644 --- a/samples/net/sockets/net_mgmt/prj.conf +++ b/samples/net/sockets/net_mgmt/prj.conf @@ -6,7 +6,7 @@ CONFIG_NET_IPV6=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_SOCKETS_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y diff --git a/samples/net/sockets/packet/prj.conf b/samples/net/sockets/packet/prj.conf index d01c89254e1552..555e824bf58809 100644 --- a/samples/net/sockets/packet/prj.conf +++ b/samples/net/sockets/packet/prj.conf @@ -7,7 +7,7 @@ CONFIG_NET_IPV4=n CONFIG_NET_MAX_CONTEXTS=10 CONFIG_NET_SOCKETS=y CONFIG_POSIX_API=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_NET_CONTEXT_RCVTIMEO=y CONFIG_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y diff --git a/samples/net/zperf/prj.conf b/samples/net/zperf/prj.conf index e355986210bbd6..0bf23e7a7e502d 100644 --- a/samples/net/zperf/prj.conf +++ b/samples/net/zperf/prj.conf @@ -20,7 +20,7 @@ CONFIG_NET_MAX_CONTEXTS=5 CONFIG_NET_TC_TX_COUNT=1 CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_POLL_MAX=9 -CONFIG_POSIX_MAX_FDS=8 +CONFIG_ZVFS_OPEN_MAX=8 CONFIG_POSIX_API=y CONFIG_INIT_STACKS=y diff --git a/samples/net/zperf/sample.yaml b/samples/net/zperf/sample.yaml index 12c0cfd1bf2e30..35260fd723aa63 100644 --- a/samples/net/zperf/sample.yaml +++ b/samples/net/zperf/sample.yaml @@ -98,3 +98,10 @@ tests: depends_on: - arduino_spi - arduino_gpio + sample.net.zperf.nxp_enet1g: + extra_args: EXTRA_DTC_OVERLAY_FILE="nxp,enet1g.overlay" + tags: + - net + - zperf + platform_allow: + - mimxrt1170_evk/mimxrt1176/cm7 diff --git a/samples/posix/philosophers/prj.conf b/samples/posix/philosophers/prj.conf index 0934325aea66b4..2f8c3da16c3007 100644 --- a/samples/posix/philosophers/prj.conf +++ b/samples/posix/philosophers/prj.conf @@ -6,7 +6,7 @@ CONFIG_THREAD_STACK_INFO=y CONFIG_DYNAMIC_THREAD=y CONFIG_DYNAMIC_THREAD_POOL_SIZE=6 -CONFIG_MAX_PTHREAD_COUNT=6 +CONFIG_POSIX_THREAD_THREADS_MAX=6 CONFIG_MAX_PTHREAD_MUTEX_COUNT=6 #Enable thread awareness for debugging tools supporting it diff --git a/samples/posix/philosophers/src/main.c b/samples/posix/philosophers/src/main.c index 29861803aab3ee..bfac15861fd6d6 100644 --- a/samples/posix/philosophers/src/main.c +++ b/samples/posix/philosophers/src/main.c @@ -21,12 +21,12 @@ #define MAX_NAME_LEN 1 #endif -#define NUM_PHIL CONFIG_MAX_PTHREAD_COUNT +#define NUM_PHIL CONFIG_POSIX_THREAD_THREADS_MAX #define obj_init_type "POSIX" #define fork_type_str "mutexes" -BUILD_ASSERT(CONFIG_MAX_PTHREAD_COUNT == CONFIG_MAX_PTHREAD_MUTEX_COUNT); -BUILD_ASSERT(CONFIG_DYNAMIC_THREAD_POOL_SIZE == CONFIG_MAX_PTHREAD_COUNT); +BUILD_ASSERT(CONFIG_POSIX_THREAD_THREADS_MAX == CONFIG_MAX_PTHREAD_MUTEX_COUNT); +BUILD_ASSERT(CONFIG_DYNAMIC_THREAD_POOL_SIZE == CONFIG_POSIX_THREAD_THREADS_MAX); typedef pthread_mutex_t *fork_t; diff --git a/samples/sensor/bme280/prj.conf b/samples/sensor/bme280/prj.conf index 42fcd3c973bcbe..f143196e59a8ed 100644 --- a/samples/sensor/bme280/prj.conf +++ b/samples/sensor/bme280/prj.conf @@ -1 +1,2 @@ CONFIG_SENSOR=y +CONFIG_SENSOR_ASYNC_API=y diff --git a/samples/sensor/bme280/src/main.c b/samples/sensor/bme280/src/main.c index 07fa9a60eb64b3..433339c88055ce 100644 --- a/samples/sensor/bme280/src/main.c +++ b/samples/sensor/bme280/src/main.c @@ -9,15 +9,25 @@ #include #include #include +#include +#include +#include /* * Get a device structure from a devicetree node with compatible * "bosch,bme280". (If there are multiple, just pick one.) */ -static const struct device *get_bme280_device(void) -{ - const struct device *const dev = DEVICE_DT_GET_ANY(bosch_bme280); +const struct device *const dev = DEVICE_DT_GET_ANY(bosch_bme280); + +SENSOR_DT_READ_IODEV(iodev, DT_COMPAT_GET_ANY_STATUS_OKAY(bosch_bme280), + {SENSOR_CHAN_AMBIENT_TEMP, 0}, + {SENSOR_CHAN_HUMIDITY, 0}, + {SENSOR_CHAN_PRESS, 0}); +RTIO_DEFINE(ctx, 1, 1); + +static const struct device *check_bme280_device(void) +{ if (dev == NULL) { /* No such node, or the node does not have status "okay". */ printk("\nError: no device found.\n"); @@ -37,23 +47,56 @@ static const struct device *get_bme280_device(void) int main(void) { - const struct device *dev = get_bme280_device(); + const struct device *dev = check_bme280_device(); if (dev == NULL) { return 0; } while (1) { - struct sensor_value temp, press, humidity; + uint8_t buf[128]; + + int rc = sensor_read(&iodev, &ctx, buf, 128); + + if (rc != 0) { + printk("%s: sensor_read() failed: %d\n", dev->name, rc); + return rc; + } + + const struct sensor_decoder_api *decoder; + + rc = sensor_get_decoder(dev, &decoder); + + if (rc != 0) { + printk("%s: sensor_get_decode() failed: %d\n", dev->name, rc); + return rc; + } + + uint32_t temp_fit = 0; + struct sensor_q31_data temp_data = {0}; + + decoder->decode(buf, + (struct sensor_chan_spec) {SENSOR_CHAN_AMBIENT_TEMP, 0}, + &temp_fit, 1, &temp_data); + + uint32_t press_fit = 0; + struct sensor_q31_data press_data = {0}; + + decoder->decode(buf, + (struct sensor_chan_spec) {SENSOR_CHAN_PRESS, 0}, + &press_fit, 1, &press_data); + + uint32_t hum_fit = 0; + struct sensor_q31_data hum_data = {0}; - sensor_sample_fetch(dev); - sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); - sensor_channel_get(dev, SENSOR_CHAN_PRESS, &press); - sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity); + decoder->decode(buf, + (struct sensor_chan_spec) {SENSOR_CHAN_HUMIDITY, 0}, + &hum_fit, 1, &hum_data); - printk("temp: %d.%06d; press: %d.%06d; humidity: %d.%06d\n", - temp.val1, temp.val2, press.val1, press.val2, - humidity.val1, humidity.val2); + printk("temp: %s%d.%d; press: %s%d.%d; humidity: %s%d.%d\n", + PRIq_arg(temp_data.readings[0].temperature, 6, temp_data.shift), + PRIq_arg(press_data.readings[0].pressure, 6, press_data.shift), + PRIq_arg(hum_data.readings[0].humidity, 6, hum_data.shift)); k_sleep(K_MSEC(1000)); } diff --git a/samples/sensor/ccs811/boards/efr32mg_sltb004a.overlay b/samples/sensor/ccs811/boards/sltb004a.overlay similarity index 100% rename from samples/sensor/ccs811/boards/efr32mg_sltb004a.overlay rename to samples/sensor/ccs811/boards/sltb004a.overlay diff --git a/samples/sensor/ccs811/sample.yaml b/samples/sensor/ccs811/sample.yaml index 838eb82b51438a..755a9648ddc610 100644 --- a/samples/sensor/ccs811/sample.yaml +++ b/samples/sensor/ccs811/sample.yaml @@ -13,7 +13,7 @@ tests: tags: sensors platform_allow: - thingy52/nrf52832 - - efr32mg_sltb004a + - sltb004a integration_platforms: - - efr32mg_sltb004a + - sltb004a depends_on: i2c diff --git a/samples/sensor/dht_polling/prj.conf b/samples/sensor/dht_polling/prj.conf index 7d668be1f0b195..8afa5ea2557f32 100644 --- a/samples/sensor/dht_polling/prj.conf +++ b/samples/sensor/dht_polling/prj.conf @@ -1,2 +1,3 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_SENSOR=y +CONFIG_SENSOR_ASYNC_API=y diff --git a/samples/sensor/dht_polling/src/main.c b/samples/sensor/dht_polling/src/main.c index 8ff26b5ab9b0ac..9055f07cb925c0 100644 --- a/samples/sensor/dht_polling/src/main.c +++ b/samples/sensor/dht_polling/src/main.c @@ -8,17 +8,35 @@ #include #include -#include #include #include +#include +#include +#include +#include #define DHT_ALIAS(i) DT_ALIAS(_CONCAT(dht, i)) -#define DHT_DEVICE(i, _) \ +#define DHT_DEVICE(i, _) \ IF_ENABLED(DT_NODE_EXISTS(DHT_ALIAS(i)), (DEVICE_DT_GET(DHT_ALIAS(i)),)) /* Support up to 10 temperature/humidity sensors */ static const struct device *const sensors[] = {LISTIFY(10, DHT_DEVICE, ())}; +#define DHT_IODEV(i, _) \ + IF_ENABLED(DT_NODE_EXISTS(DHT_ALIAS(i)), \ + (SENSOR_DT_READ_IODEV(_CONCAT(dht_iodev, i), DHT_ALIAS(i), \ + {SENSOR_CHAN_AMBIENT_TEMP, 0}, \ + {SENSOR_CHAN_HUMIDITY, 0}))) + +LISTIFY(10, DHT_IODEV, (;)); + +#define DHT_IODEV_REF(i, _) \ + COND_CODE_1(DT_NODE_EXISTS(DHT_ALIAS(i)), (CONCAT(&dht_iodev, i)), (NULL)) + +static struct rtio_iodev *dht_iodev[] = { LISTIFY(10, DHT_IODEV_REF, (,)) }; + +RTIO_DEFINE(dht_ctx, 1, 1); + int main(void) { int rc; @@ -32,29 +50,43 @@ int main(void) while (1) { for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { - struct device *dev = (struct device *)sensors[i]; + struct device *dev = (struct device *) sensors[i]; + + uint8_t buf[128]; + + rc = sensor_read(dht_iodev[i], &dht_ctx, buf, 128); - rc = sensor_sample_fetch(dev); - if (rc < 0) { - printk("%s: sensor_sample_fetch() failed: %d\n", dev->name, rc); + if (rc != 0) { + printk("%s: sensor_read() failed: %d\n", dev->name, rc); return rc; } - struct sensor_value temp; - struct sensor_value hum; + const struct sensor_decoder_api *decoder; + + rc = sensor_get_decoder(dev, &decoder); - rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); - if (rc == 0) { - rc = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &hum); - } if (rc != 0) { - printf("get failed: %d\n", rc); - break; + printk("%s: sensor_get_decode() failed: %d\n", dev->name, rc); + return rc; } - printk("%16s: temp is %d.%02d °C humidity is %d.%02d %%RH\n", - dev->name, temp.val1, temp.val2 / 10000, - hum.val1, hum.val2 / 10000); + uint32_t temp_fit = 0; + struct sensor_q31_data temp_data = {0}; + + decoder->decode(buf, + (struct sensor_chan_spec) {SENSOR_CHAN_AMBIENT_TEMP, 0}, + &temp_fit, 1, &temp_data); + + uint32_t hum_fit = 0; + struct sensor_q31_data hum_data = {0}; + + decoder->decode(buf, + (struct sensor_chan_spec) {SENSOR_CHAN_HUMIDITY, 0}, + &hum_fit, 1, &hum_data); + + printk("%16s: temp is %s%d.%d °C humidity is %s%d.%d RH\n", dev->name, + PRIq_arg(temp_data.readings[0].temperature, 2, temp_data.shift), + PRIq_arg(hum_data.readings[0].humidity, 2, hum_data.shift)); } k_msleep(1000); } diff --git a/samples/sensor/die_temp_polling/boards/nucleo_h7a3zi_q.overlay b/samples/sensor/die_temp_polling/boards/nucleo_h7a3zi_q.overlay new file mode 100644 index 00000000000000..f2081833b8cc34 --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/nucleo_h7a3zi_q.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024, Aurelien Jarno + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for creating temperature sensor device instance + */ + +/ { + aliases { + die-temp0 = &digi_die_temp; + }; +}; + +&digi_die_temp { + status = "okay"; +}; diff --git a/samples/sensor/die_temp_polling/sample.yaml b/samples/sensor/die_temp_polling/sample.yaml index f64b321c2bdfe4..adf8c4c003e58e 100644 --- a/samples/sensor/die_temp_polling/sample.yaml +++ b/samples/sensor/die_temp_polling/sample.yaml @@ -8,6 +8,7 @@ tests: filter: dt_alias_exists("die-temp0") integration_platforms: - stm32f3_disco + - nucleo_h7a3zi_q harness: console harness_config: type: one_line diff --git a/samples/sensor/sht3xd/boards/efr32mg_sltb004a.overlay b/samples/sensor/sht3xd/boards/sltb004a.overlay similarity index 100% rename from samples/sensor/sht3xd/boards/efr32mg_sltb004a.overlay rename to samples/sensor/sht3xd/boards/sltb004a.overlay diff --git a/samples/sensor/sht3xd/sample.yaml b/samples/sensor/sht3xd/sample.yaml index 0319ba3a7e29cb..be30591c2c6a4e 100644 --- a/samples/sensor/sht3xd/sample.yaml +++ b/samples/sensor/sht3xd/sample.yaml @@ -8,7 +8,7 @@ sample: name: SHT3XD Sensor Sample common: platform_allow: - - efr32mg_sltb004a + - sltb004a - frdm_k64f - nrf51_ble400 - nrf52840dk/nrf52840 diff --git a/samples/shields/npm6001_ek/prj.conf b/samples/shields/npm6001_ek/prj.conf index 94da7cfdaef63f..b0292200688e7a 100644 --- a/samples/shields/npm6001_ek/prj.conf +++ b/samples/shields/npm6001_ek/prj.conf @@ -3,7 +3,7 @@ CONFIG_SHELL=y CONFIG_SHELL_GETOPT=y -CONFIG_GETOPT=y +CONFIG_POSIX_C_LIB_EXT=y CONFIG_GETOPT_LONG=y CONFIG_GPIO=y CONFIG_REGULATOR=y diff --git a/samples/subsys/display/lvgl/sample.yaml b/samples/subsys/display/lvgl/sample.yaml index d8bfb5de9b54b1..94b26bc1087038 100644 --- a/samples/subsys/display/lvgl/sample.yaml +++ b/samples/subsys/display/lvgl/sample.yaml @@ -70,3 +70,25 @@ tests: - shield - lvgl - gui + samples.subsys.display.lvgl.rk043fn66hs_ctg: + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk + - mimxrt1050_evk + - mimxrt1040_evk + tags: display + harness: console + extra_args: SHIELD=rk043fn66hs_ctg + harness_config: + fixture: fixture_display + samples.subsys.display.lvgl.rk043fn02h_ct: + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk + - mimxrt1050_evk + - mimxrt1040_evk + tags: display + harness: console + extra_args: SHIELD=rk043fn02h_ct + harness_config: + fixture: fixture_display diff --git a/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.conf new file mode 100644 index 00000000000000..949237fd4bafd8 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_DISK_DRIVERS=y +CONFIG_DISK_DRIVER_FLASH=y +# There may be no files on internal SoC flash, so this Kconfig +# options has ben enabled to create some if listing does not +# find in the first place. +CONFIG_FS_SAMPLE_CREATE_SOME_ENTRIES=y diff --git a/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000000..391afea75a4047 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Because FAT FS needs at least 64kiB partition and default + * storage_partition is 36kiB for this board, we need to reorganize + * partitions to get at least 64KiB. + */ +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; +/delete-node/ &slot0_ns_partition; +/delete-node/ &slot1_ns_partition; +/delete-node/ &storage_partition; + +&cpuapp_rram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: parition@10000 { + reg = <0x00010000 DT_SIZE_K(300)>; + }; + slot1_partition: partition@5b000 { + reg = <0x0005b000 DT_SIZE_K(300)>; + }; + + storage_partition: partition@a6000 { + label = "storage"; + reg = <0x000a6000 DT_SIZE_K(128)>; + }; + }; +}; + +/ { + msc_disk0 { + status="okay"; + compatible = "zephyr,flash-disk"; + partition = <&storage_partition>; + disk-name = "SD"; + cache-size = <512>; + }; +}; diff --git a/samples/subsys/fs/fs_sample/sample.yaml b/samples/subsys/fs/fs_sample/sample.yaml index 55dc3d8677a088..8041ffb84c45e5 100644 --- a/samples/subsys/fs/fs_sample/sample.yaml +++ b/samples/subsys/fs/fs_sample/sample.yaml @@ -43,6 +43,9 @@ tests: extra_args: - OVERLAY_CONFIG=boards/nrf52840dk_nrf52840_ram_disk.conf - DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840_ram_disk_region.overlay + sample.filesystem.fat_fs.nrf54l15pdk: + build_only: true + platform_allow: nrf54l15pdk/nrf54l15/cpuapp sample.filesystem.fat_fs.nrf52840dk_nrf52840.qspi: build_only: true platform_allow: nrf52840dk/nrf52840 diff --git a/samples/subsys/fs/fs_sample/src/main.c b/samples/subsys/fs/fs_sample/src/main.c index 52c74cc74b1d86..01d935d7e1b503 100644 --- a/samples/subsys/fs/fs_sample/src/main.c +++ b/samples/subsys/fs/fs_sample/src/main.c @@ -48,6 +48,12 @@ static struct fs_mount_t mp = { #endif +#if defined(CONFIG_FAT_FILESYSTEM_ELM) +#define FS_RET_OK FR_OK +#else +#define FS_RET_OK 0 +#endif + LOG_MODULE_REGISTER(main); #define MAX_PATH 128 @@ -107,7 +113,8 @@ int main(void) uint32_t block_count; uint32_t block_size; - if (disk_access_init(disk_pdrv) != 0) { + if (disk_access_ioctl(disk_pdrv, + DISK_IOCTL_CTRL_INIT, NULL) != 0) { LOG_ERR("Storage init ERROR!"); break; } @@ -128,18 +135,32 @@ int main(void) memory_size_mb = (uint64_t)block_count * block_size; printk("Memory Size(MB) %u\n", (uint32_t)(memory_size_mb >> 20)); + + if (disk_access_ioctl(disk_pdrv, + DISK_IOCTL_CTRL_DEINIT, NULL) != 0) { + LOG_ERR("Storage deinit ERROR!"); + break; + } } while (0); mp.mnt_point = disk_mount_pt; int res = fs_mount(&mp); -#if defined(CONFIG_FAT_FILESYSTEM_ELM) - if (res == FR_OK) { -#else - if (res == 0) { -#endif + if (res == FS_RET_OK) { printk("Disk mounted.\n"); + /* Try to unmount and remount the disk */ + res = fs_unmount(&mp); + if (res != FS_RET_OK) { + printk("Error unmounting disk\n"); + return res; + } + res = fs_mount(&mp); + if (res != FS_RET_OK) { + printk("Error remounting disk\n"); + return res; + } + if (lsdir(disk_mount_pt) == 0) { #ifdef CONFIG_FS_SAMPLE_CREATE_SOME_ENTRIES if (create_some_entries(disk_mount_pt)) { diff --git a/samples/subsys/fs/littlefs/sample.yaml b/samples/subsys/fs/littlefs/sample.yaml index 4c53a55d59104e..67231c5cfbdffa 100644 --- a/samples/subsys/fs/littlefs/sample.yaml +++ b/samples/subsys/fs/littlefs/sample.yaml @@ -24,6 +24,7 @@ tests: - stm32f746g_disco - stm32h747i_disco/stm32h747xx/m7 - stm32h750b_dk + - nrf54l15pdk/nrf54l15/cpuapp integration_platforms: - nrf52840dk/nrf52840 sample.filesystem.littlefs.blk: diff --git a/samples/subsys/fs/littlefs/src/main.c b/samples/subsys/fs/littlefs/src/main.c index 35fe1d2b3057b2..7723023013eb7c 100644 --- a/samples/subsys/fs/littlefs/src/main.c +++ b/samples/subsys/fs/littlefs/src/main.c @@ -252,7 +252,7 @@ static int littlefs_flash_erase(unsigned int id) /* Optional wipe flash contents */ if (IS_ENABLED(CONFIG_APP_WIPE_STORAGE)) { - rc = flash_area_erase(pfa, 0, pfa->fa_size); + rc = flash_area_flatten(pfa, 0, pfa->fa_size); LOG_ERR("Erasing flash area ... %d", rc); } diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf5340dk_nrf5340_cpuapp.overlay index 22650211611f02..f782bdd85784c7 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -31,6 +31,11 @@ mboxes = <&mbox 0>, <&mbox 1>; mbox-names = "tx", "rx"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; }; }; diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay index 35cffd8ad350b1..216561b349be0b 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -39,6 +39,11 @@ mboxes = <&mbox 0>, <&mbox 1>; mbox-names = "tx", "rx"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; ipc1: ipc1 { diff --git a/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay index 3db9db032f4c46..2d85fbbf79c1bb 100644 --- a/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay +++ b/samples/subsys/ipc/ipc_service/multi_endpoint/boards/nrf5340dk_nrf5340_cpuapp_icbmsg.overlay @@ -41,6 +41,11 @@ mboxes = <&mbox 0>, <&mbox 1>; mbox-names = "tx", "rx"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; ipc1: ipc1 { diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay index 520f007a82179c..f07f75fc9a1a77 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -33,6 +33,11 @@ mbox-names = "tx", "rx"; role = "host"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + compatible = "zephyr,bt-hci-ipc"; + status = "okay"; + }; }; ipc1: ipc1 { diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.conf b/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.conf deleted file mode 100644 index ae8dba8cc217f1..00000000000000 --- a/samples/subsys/ipc/openamp/boards/mimxrt1170_evkb_cm7.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright 2023, NXP -# -# SPDX-License-Identifier: Apache-2.0 -# -CONFIG_INCLUDE_REMOTE_DIR=y -CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.conf b/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.conf deleted file mode 100644 index 4dfc4a60b76ac7..00000000000000 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1160_evk_cm4.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_BUILD_OUTPUT_INFO_HEADER=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.conf b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.conf deleted file mode 100644 index 4dfc4a60b76ac7..00000000000000 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_BUILD_OUTPUT_INFO_HEADER=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay deleted file mode 100644 index 87159192cf249e..00000000000000 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evk_cm4.overlay +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022-2023 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/ { - /* Switch to lpuart2, since primary core uses lpuart1 */ - chosen { - zephyr,flash = &ocram; - zephyr,console = &lpuart2; - zephyr,shell-uart = &lpuart2; - zephyr,ipc_shm = &ocram2_overlay; - }; - - soc { - /delete-node/ gpt@400f0000; - - /* Replace GPT2 with another GPT kernel timer */ - gpt2_hw_timer:gpt@400f0000 { - compatible = "nxp,gpt-hw-timer"; - reg = <0x400f0000 0x4000>; - interrupts = <120 0>; - status = "okay"; - }; - }; - - /* OpenAMP fails with full 512K OCRAM2 memory region as shared memory. - * Define a subset of the OCRAM2 region for demo to use - * Note that shared memory must have specific MPU attributes set - */ - ocram2_overlay: memory@202c0000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x202c0000 DT_SIZE_K(16)>; - zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; - }; -}; - -/* Enable secondary LPUART */ -&lpuart2 { - status = "okay"; - current-speed = <115200>; -}; - -/* Disable primary GPT timer */ -&gpt_hw_timer { - status = "disabled"; -}; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.conf b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.conf deleted file mode 100644 index 7b43b448c72c27..00000000000000 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright 2023, NXP -# -# SPDX-License-Identifier: Apache-2.0 -# -CONFIG_BUILD_OUTPUT_INFO_HEADER=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay deleted file mode 100644 index 72510d261664a0..00000000000000 --- a/samples/subsys/ipc/openamp/remote/boards/mimxrt1170_evkb_cm4.overlay +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - /* Switch to lpuart2, since primary core uses lpuart1 */ - chosen { - zephyr,flash = &ocram; - zephyr,console = &lpuart2; - zephyr,shell-uart = &lpuart2; - zephyr,ipc_shm = &ocram2_overlay; - }; - - soc { - /delete-node/ gpt@400f0000; - - /* Replace GPT2 with another GPT kernel timer */ - gpt2_hw_timer:gpt@400f0000 { - compatible = "nxp,gpt-hw-timer"; - reg = <0x400f0000 0x4000>; - interrupts = <120 0>; - status = "okay"; - }; - }; - - /* OpenAMP fails with full 512K OCRAM2 memory region as shared memory. - * Define a subset of the OCRAM2 region for demo to use - * Note that shared memory must have specific MPU attributes set - */ - ocram2_overlay: memory@202c0000 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x202c0000 DT_SIZE_K(16)>; - zephyr,memory-region="OCRAM2_OVERLAY"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>; - }; -}; - -/* Enable secondary LPUART */ -&lpuart2 { - status = "okay"; - current-speed = <115200>; -}; - -/* Disable primary GPT timer */ -&gpt_hw_timer { - status = "disabled"; -}; diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.conf b/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.conf new file mode 100644 index 00000000000000..8c960fc2dd342a --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.conf @@ -0,0 +1,12 @@ +CONFIG_IPM=y +CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y +CONFIG_OPENAMP_WITH_DCACHE=y +CONFIG_PLATFORM_SPECIFIC_INIT=n +CONFIG_OPENAMP=y +CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF=32 +CONFIG_OPENAMP_RSC_TABLE=y +CONFIG_OPENAMP_MASTER=n + + +CONFIG_ROMSTART_RELOCATION_ROM=y +CONFIG_BUILD_OUTPUT_BIN=n diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.overlay b/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.overlay new file mode 100644 index 00000000000000..f55dd790c95034 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/boards/colibri_imx7d_mcimx7d_m4.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 MAKEEN Energy A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Follow the board's documentation to modify the Linux DT accordingly */ + +/ { + + chosen { + /* Use OCRAM 128kB because TCM 32kB is too small for the sample */ + zephyr,flash = &ocram_code; + zephyr,ipc_shm = &ddr_shm; + zephyr,ipc = &mub; + }; + + ddr_shm: memory1@90000000 { + compatible = "mmio-sram"; + /* use DDR_SYS area as mmio, 0x90000000 0x10000 */ + reg = <0x90000000 0x10000>; + status = "okay"; + }; +}; + +&mub { + status = "okay"; +}; diff --git a/samples/subsys/llext/edk/app/src/main.c b/samples/subsys/llext/edk/app/src/main.c index 502901d59bdd0e..78f1a664661a0a 100644 --- a/samples/subsys/llext/edk/app/src/main.c +++ b/samples/subsys/llext/edk/app/src/main.c @@ -100,7 +100,7 @@ static void user_function(void *p1, void *p2, void *p3) printk("[app]Thread %p done\n", k_current_get()); } -void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) +void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *esf) { int i; diff --git a/samples/subsys/logging/multidomain/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/logging/multidomain/boards/nrf5340dk_nrf5340_cpuapp.overlay index eac4af423aef7d..75e9f1b57442fc 100644 --- a/samples/subsys/logging/multidomain/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/subsys/logging/multidomain/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -34,6 +34,11 @@ mbox-names = "tx", "rx"; role = "host"; status = "okay"; + + bt_hci_ipc0: bt_hci_ipc0 { + status = "okay"; + compatible = "zephyr,bt-hci-ipc"; + }; }; ipc1: ipc1 { diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index ce5cd64561dbb0..a9ddfcbf4a146c 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -31,18 +31,14 @@ Caveats properly. More information about the Device Firmware Upgrade subsystem and MCUboot can be found in :ref:`mcuboot`. -* The :file:`mcumgr` command-line tool only works with Bluetooth Low Energy (BLE) - on Linux and macOS. On Windows there is no support for Device Firmware - Upgrade over BLE yet. - Prerequisites ************* -Installing the mcumgr cli -========================= +Use of a tool +============= -To interact remotely with the management subsystem on a device, we need to have the -:file:`mcumgr` installed. Follow the instructions in the :ref:`mcumgr_cli` section +To interact remotely with the management subsystem on a device, a tool is required to interact with +it. There are various tools available which are listed on the :ref:`mcumgr_tools_libraries` page of the Management subsystem documentation. Building a BLE Controller @@ -63,7 +59,7 @@ The below steps describe how to build and run the MCUboot bootloader. Detailed instructions can be found in the :ref:`mcuboot` documentation page. The Zephyr port of MCUboot is essentially a normal Zephyr application, which means that -we can build and flash it like normal using ``west``, like so: +it can be built and flashed like normal using ``west``, like so: .. code-block:: console @@ -156,7 +152,7 @@ Signing the sample image A key feature of MCUboot is that images must be signed before they can be successfully uploaded and run on a target. To sign images, the MCUboot tool :file:`imgtool` can be used. -To sign the sample image we built in a previous step: +To sign the sample image built in the previous step: .. code-block:: console @@ -174,65 +170,22 @@ Flashing the sample image Upload the :file:`zephyr.signed.bin` file from the previous to image slot-0 of your board. See :ref:`flash_map_api` for details on flash partitioning. -To upload the initial image file to an empty slot-0, we simply use ``west flash`` -like normal. ``west flash`` will automatically detect slot-0 address and confirm -the image. +To upload the initial image file to an empty slot-0, use ``west flash`` like normal. +``west flash`` will automatically detect slot-0 address and confirm the image. .. code-block:: console west flash --bin-file build/zephyr/zephyr.signed.bin -We need to explicitly specify the *signed* image file, otherwise the non-signed version +The *signed* image file needs to be used specifically, otherwise the non-signed version will be used and the image won't be runnable. Sample image: hello world! ========================== The ``smp_svr`` app is ready to run. Just reset your board and test the app -with the :file:`mcumgr` command-line tool's ``echo`` functionality, which will -send a string to the remote target device and have it echo it back: - -.. tabs:: - - .. group-tab:: Bluetooth - - .. code-block:: console - - sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' echo hello - hello - - .. group-tab:: Shell - - .. code-block:: console - - mcumgr --conntype serial --connstring "/dev/ttyACM0,baud=115200" echo hello - hello - - .. group-tab:: UDP - - Using IPv4: - - .. code-block:: console - - mcumgr --conntype udp --connstring=[192.168.1.1]:1337 echo hello - hello - - And using IPv6 - - .. code-block:: console - - mcumgr --conntype udp --connstring=[2001:db8::1]:1337 echo hello - hello - -.. note:: - The :file:`mcumgr` command-line tool requires a connection string in order - to identify the remote target device. In the BT sample we use a BLE-based - connection string, and you might need to modify it depending on the - BLE controller you are using. - -.. note:: - In the following sections, examples will use ```` to represent - the ``--conntype `` and ``--connstring=`` :file:`mcumgr` parameters. +with your choice of tool's ``echo`` functionality, which will +send a string to the remote target device and have it echo it back. J-Link Virtual MSD Interaction Note *********************************** @@ -269,10 +222,6 @@ Direct image upload and Image mapping to MCUboot slot Currently the mcumgr supports, for direct upload, 4 target images, of which first two are mapped into MCUboot primary (slot-0) and secondary (slot-1) respectively. -The mcumgr ``image upload`` command may be provided optional ``-e -n `` parameter that will -select target image for upload; when parameter is no provided, 0 is assumed, which means "default -behaviour", and it performs upload to the "image-1", the MCUboot secondary slot. - For clarity, here is DTS label to slot to ```` translation table: +-----------+--------+------------+ @@ -287,80 +236,47 @@ For clarity, here is DTS label to slot to ```` translation table: | "image-3" | | 3 | +-----------+--------+------------+ -.. note:: - - The ``-e`` option actually means "no erase", and is provided to the mcumgr - to prevent it from sending erase command to target, before updating image. - The options is always needed when ``-n`` is used for image selection, - as the erase command is hardcoded to erase slot-1 ("image-1"), - regardless of which slot is uploaded at the time. - Upload the signed image ======================= -To upload the signed image, use the following command: - -.. code-block:: console - - sudo mcumgr image upload build/zephyr/zephyr.signed.bin +To upload the signed image, refer to the documentation for your chosen tool, select the new +firmware file to upload and begin the upload. .. note:: At the beginning of the upload process, the target might start erasing - the image slot, taking several dozen seconds for some targets. This might - cause an NMP timeout in the management protocol tool. Use the - ``-t image list - -This should print the status and hash values of each of the images present. +A list of images (slot-0 and slot-1) that are present can now be obtained on the remote target device using +the tool of your choice, which should print the status and hash values of each of the images +present. Test the image ============== -In order to instruct MCUboot to swap the images we need to test the image first, -making sure it boots: - -.. code-block:: console - - sudo mcumgr image test - -Now MCUBoot will swap the image on the next reset. +In order to instruct MCUboot to swap the images, the image needs to be tested first, making sure it +boots, see the instructions in the tool of your choice. Upon reboot, MCUBoot will swap to the new +image. .. note:: There is not yet any way of getting the image hash without actually uploading the - image and getting the hash by using the ``image list`` command of :file:`mcumgr`. + image and getting the hash. Reset remotely ============== -We can reset the device remotely to observe (use the console output) how -MCUboot swaps the images: - -.. code-block:: console - - sudo mcumgr reset - -Upon reset MCUboot will swap slot-0 and slot-1. +The device can be reset remotely to observe (use the console output) how MCUboot swaps the images, +check the documentation in the tool of your choice. Upon reset MCUboot will swap slot-0 and +slot-1. Confirm new image ================= -The new image is now loaded into slot-0, but it will be swapped back into slot-1 -on the next reset unless the image is confirmed. To confirm the new image: - -.. code-block:: console - - sudo mcumgr image confirm +The new image is now loaded into slot-0, but it will be swapped back into slot-1 on the next +reset unless the image is confirmed. Confirm the image using the tool of your choice. Note that if you try to send the very same image that is already flashed in slot-0 then the procedure will not complete successfully since the hash values @@ -372,9 +288,4 @@ Download file from File System SMP server supports downloading files from File System on device via :file:`mcumgr`. This is useful with FS log backend, when files are stored in non-volatile memory. Build and flash both MCUboot and smp_svr applications and -then use :file:`mcumgr` with :file:`download` command, e.g.: - -.. code-block:: console - - mcumgr --conntype serial --connstring='dev=/dev/ttyACM0,baud=115200' \ - fs download /lfs/log.0000 ~/log.txt +then use the tool of your choice to download files from the file system. diff --git a/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c b/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c index a8662c04998708..97fd39f4d1fc84 100644 --- a/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c +++ b/samples/subsys/rtio/sensor_batch_processing/src/vnd_sensor.c @@ -20,6 +20,7 @@ struct vnd_sensor_config { struct vnd_sensor_data { struct rtio_iodev iodev; + struct mpsc io_q; struct k_timer timer; const struct device *dev; uint32_t sample_number; @@ -83,13 +84,13 @@ static void vnd_sensor_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) { struct vnd_sensor_data *data = (struct vnd_sensor_data *) iodev_sqe->sqe.iodev; - rtio_mpsc_push(&data->iodev.iodev_sq, &iodev_sqe->q); + mpsc_push(&data->io_q, &iodev_sqe->q); } static void vnd_sensor_handle_int(const struct device *dev) { struct vnd_sensor_data *data = dev->data; - struct rtio_mpsc_node *node = rtio_mpsc_pop(&data->iodev.iodev_sq); + struct mpsc_node *node = mpsc_pop(&data->io_q); if (node != NULL) { struct rtio_iodev_sqe *iodev_sqe = CONTAINER_OF(node, struct rtio_iodev_sqe, q); @@ -116,7 +117,7 @@ static int vnd_sensor_init(const struct device *dev) data->dev = dev; - rtio_mpsc_init(&data->iodev.iodev_sq); + mpsc_init(&data->io_q); k_timer_init(&data->timer, vnd_sensor_timer_expiry, NULL); diff --git a/samples/subsys/shell/shell_module/overlay-usb.conf b/samples/subsys/shell/shell_module/overlay-usb.conf index 692287e23a1205..b92529f9cc612e 100644 --- a/samples/subsys/shell/shell_module/overlay-usb.conf +++ b/samples/subsys/shell/shell_module/overlay-usb.conf @@ -4,8 +4,9 @@ CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR=y CONFIG_UART_LINE_CTRL=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n -# POSIX_CLOCK requires an embedded C library while the native USB driver is incompatible with it. +# POSIX_TIMERS requires an embedded C library while the native USB driver is incompatible with it. # So let's disable it. Once USB_NATIVE_POSIX supports embedded C libraries this can be removed. -CONFIG_POSIX_CLOCK=n -# DATE_SHELL requires POSIX_CLOCK +CONFIG_POSIX_API=n +CONFIG_POSIX_TIMERS=n +# DATE_SHELL requires POSIX_TIMERS CONFIG_DATE_SHELL=n diff --git a/samples/subsys/shell/shell_module/prj.conf b/samples/subsys/shell/shell_module/prj.conf index 41d51f8e22a7f1..ff7c665b38155f 100644 --- a/samples/subsys/shell/shell_module/prj.conf +++ b/samples/subsys/shell/shell_module/prj.conf @@ -9,7 +9,8 @@ CONFIG_THREAD_MONITOR=y CONFIG_BOOT_BANNER=n CONFIG_THREAD_NAME=y CONFIG_DEVICE_SHELL=y -CONFIG_POSIX_CLOCK=y +CONFIG_POSIX_API=y +CONFIG_POSIX_TIMERS=y CONFIG_DATE_SHELL=y CONFIG_THREAD_RUNTIME_STATS=y CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y diff --git a/samples/subsys/shell/shell_module/prj_getopt.conf b/samples/subsys/shell/shell_module/prj_getopt.conf index 6bfeb3dec41e2e..8f04ab27d7c627 100644 --- a/samples/subsys/shell/shell_module/prj_getopt.conf +++ b/samples/subsys/shell/shell_module/prj_getopt.conf @@ -9,6 +9,7 @@ CONFIG_THREAD_MONITOR=y CONFIG_BOOT_BANNER=n CONFIG_THREAD_NAME=y CONFIG_DEVICE_SHELL=y -CONFIG_POSIX_CLOCK=y +CONFIG_POSIX_API=y +CONFIG_POSIX_TIMERS=y CONFIG_DATE_SHELL=y CONFIG_THREAD_RUNTIME_STATS=y diff --git a/samples/subsys/shell/shell_module/prj_login.conf b/samples/subsys/shell/shell_module/prj_login.conf index d84acc15622ab8..470a41044f82f2 100644 --- a/samples/subsys/shell/shell_module/prj_login.conf +++ b/samples/subsys/shell/shell_module/prj_login.conf @@ -8,7 +8,8 @@ CONFIG_THREAD_MONITOR=y CONFIG_BOOT_BANNER=n CONFIG_THREAD_NAME=y CONFIG_DEVICE_SHELL=y -CONFIG_POSIX_CLOCK=y +CONFIG_POSIX_API=y +CONFIG_POSIX_TIMERS=y CONFIG_DATE_SHELL=y CONFIG_THREAD_RUNTIME_STATS=y diff --git a/samples/subsys/shell/shell_module/sample.yaml b/samples/subsys/shell/shell_module/sample.yaml index cfd6adb80de64f..482e4a37875fa0 100644 --- a/samples/subsys/shell/shell_module/sample.yaml +++ b/samples/subsys/shell/shell_module/sample.yaml @@ -1,5 +1,10 @@ sample: name: Shell Sample +common: + filter: not CONFIG_NATIVE_LIBC + platform_exclude: + - native_posix + - native_posix/native/64 tests: sample.shell.shell_module: filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") diff --git a/samples/subsys/tracing/README.rst b/samples/subsys/tracing/README.rst index 89c3ac1eb5f358..c7ee095a90c438 100644 --- a/samples/subsys/tracing/README.rst +++ b/samples/subsys/tracing/README.rst @@ -33,7 +33,9 @@ or: :goals: build :compact: -.. note:: You may need to set "zephyr,tracing-uart" property under the chosen node in your devicetree. See :zephyr_file:`boards/mps2_an521.overlay` for an example. +.. note:: + You may need to set "zephyr,tracing-uart" property under the chosen node in your devicetree. + See :zephyr_file:`samples/subsys/tracing/boards/mps2_an521_cpu0.overlay` for an example. After the application has run for a while, check the trace output file. diff --git a/samples/subsys/usb/cdc_acm/sample.yaml b/samples/subsys/usb/cdc_acm/sample.yaml index 82365c1f245980..78d02840b85000 100644 --- a/samples/subsys/usb/cdc_acm/sample.yaml +++ b/samples/subsys/usb/cdc_acm/sample.yaml @@ -11,7 +11,7 @@ tests: regex: - "Wait for DTR" sample.usb_device_next.cdc-acm: - depends_on: usb_device + depends_on: usbd tags: usb extra_args: CONF_FILE="usbd_next_prj.conf" platform_allow: diff --git a/samples/subsys/usb/hid-keyboard/app.overlay b/samples/subsys/usb/hid-keyboard/app.overlay index 6433abbe7061b6..0d3d2ee7bd8553 100644 --- a/samples/subsys/usb/hid-keyboard/app.overlay +++ b/samples/subsys/usb/hid-keyboard/app.overlay @@ -10,6 +10,6 @@ interface-name = "HID0"; protocol-code = "keyboard"; in-report-size = <64>; - in-polling-rate = <1000>; + in-polling-period-us = <1000>; }; }; diff --git a/samples/subsys/usb/hid-keyboard/large_in_report.overlay b/samples/subsys/usb/hid-keyboard/large_in_report.overlay index 2eb82c5df619ce..93b47691a77f3c 100644 --- a/samples/subsys/usb/hid-keyboard/large_in_report.overlay +++ b/samples/subsys/usb/hid-keyboard/large_in_report.overlay @@ -9,6 +9,6 @@ compatible = "zephyr,hid-device"; interface-name = "HID0"; in-report-size = <256>; - in-polling-rate = <1000>; + in-polling-period-us = <1000>; }; }; diff --git a/samples/subsys/usb/hid-keyboard/large_out_report.overlay b/samples/subsys/usb/hid-keyboard/large_out_report.overlay index 16b02a9efb0593..e5348743d29a34 100644 --- a/samples/subsys/usb/hid-keyboard/large_out_report.overlay +++ b/samples/subsys/usb/hid-keyboard/large_out_report.overlay @@ -10,6 +10,6 @@ hid_dev_0: hid_dev_0 { compatible = "zephyr,hid-device"; out-report-size = <128>; - out-polling-rate = <16000>; + out-polling-period-us = <16000>; }; }; diff --git a/samples/subsys/usb/hid-keyboard/out_report.overlay b/samples/subsys/usb/hid-keyboard/out_report.overlay index bcd776622e843d..215cc9300dd0f9 100644 --- a/samples/subsys/usb/hid-keyboard/out_report.overlay +++ b/samples/subsys/usb/hid-keyboard/out_report.overlay @@ -10,6 +10,6 @@ hid_dev_0: hid_dev_0 { compatible = "zephyr,hid-device"; out-report-size = <64>; - out-polling-rate = <16000>; + out-polling-period-us = <16000>; }; }; diff --git a/samples/subsys/usb/hid-keyboard/sample.yaml b/samples/subsys/usb/hid-keyboard/sample.yaml index 726608009bad3c..09efcc05608718 100644 --- a/samples/subsys/usb/hid-keyboard/sample.yaml +++ b/samples/subsys/usb/hid-keyboard/sample.yaml @@ -4,7 +4,7 @@ common: harness: button filter: dt_alias_exists("sw0") and dt_alias_exists("led0") depends_on: - - usb_device + - usbd - gpio platform_allow: - nrf52840dk/nrf52840 diff --git a/samples/subsys/usb/hid-mouse/sample.yaml b/samples/subsys/usb/hid-mouse/sample.yaml index 77ede76aeb42d3..aaa6a01dea0479 100644 --- a/samples/subsys/usb/hid-mouse/sample.yaml +++ b/samples/subsys/usb/hid-mouse/sample.yaml @@ -4,14 +4,17 @@ common: harness: button filter: dt_alias_exists("sw0") and dt_alias_exists("led0") depends_on: - - usb_device - gpio tests: sample.usb.hid-mouse: + depends_on: + - usb_device platform_exclude: - frdm_mcxn947/mcxn947/cpu0 tags: usb sample.usb_device_next.hid-mouse: + depends_on: + - usbd platform_allow: - nrf52840dk/nrf52840 - nrf54h20dk/nrf54h20/cpuapp diff --git a/samples/subsys/usb/hid-mouse/usbd_next.overlay b/samples/subsys/usb/hid-mouse/usbd_next.overlay index 8b7b5c5182139c..ce74aa51879651 100644 --- a/samples/subsys/usb/hid-mouse/usbd_next.overlay +++ b/samples/subsys/usb/hid-mouse/usbd_next.overlay @@ -9,7 +9,7 @@ compatible = "zephyr,hid-device"; interface-name = "HID0"; protocol-code = "none"; - in-polling-rate = <1000>; + in-polling-period-us = <1000>; in-report-size = <64>; }; }; diff --git a/samples/subsys/usb/mass/sample.yaml b/samples/subsys/usb/mass/sample.yaml index f2459019ce7fe1..dca20363d89913 100644 --- a/samples/subsys/usb/mass/sample.yaml +++ b/samples/subsys/usb/mass/sample.yaml @@ -21,7 +21,7 @@ tests: - "The device is put in USB mass storage mode." sample.usb_device_next.mass_ram_none: min_ram: 128 - depends_on: usb_device + depends_on: usbd platform_allow: - nrf52840dk/nrf52840 - nrf54h20dk/nrf54h20/cpuapp @@ -89,7 +89,7 @@ tests: min_ram: 32 modules: - fatfs - depends_on: usb_device + depends_on: usbd filter: dt_compat_enabled("nordic,qspi-nor") platform_allow: - nrf52840dk/nrf52840 diff --git a/samples/subsys/usb/mass/src/main.c b/samples/subsys/usb/mass/src/main.c index 51718a9dc85957..733f6f90ea86fb 100644 --- a/samples/subsys/usb/mass/src/main.c +++ b/samples/subsys/usb/mass/src/main.c @@ -89,7 +89,7 @@ static int setup_flash(struct fs_mount_t *mnt) if (rc < 0 && IS_ENABLED(CONFIG_APP_WIPE_STORAGE)) { printk("Erasing flash area ... "); - rc = flash_area_erase(pfa, 0, pfa->fa_size); + rc = flash_area_flatten(pfa, 0, pfa->fa_size); printk("%d\n", rc); } diff --git a/samples/subsys/usb/shell/sample.yaml b/samples/subsys/usb/shell/sample.yaml index 246b6133a02a08..e2525238da25f9 100644 --- a/samples/subsys/usb/shell/sample.yaml +++ b/samples/subsys/usb/shell/sample.yaml @@ -1,16 +1,17 @@ sample: name: USB support shell sample +common: + depends_on: + - usbd tests: sample.usbd.shell: platform_allow: - nrf52840dk/nrf52840 - nrf54h20dk/nrf54h20/cpuapp - frdm_k64f - depends_on: usb_device harness: keyboard tags: usb sample.usbh.shell: - depends_on: usb_device tags: - usb - shield diff --git a/samples/subsys/usb/uac2_explicit_feedback/sample.yaml b/samples/subsys/usb/uac2_explicit_feedback/sample.yaml index c9d5457470168a..a94996f9f1063e 100644 --- a/samples/subsys/usb/uac2_explicit_feedback/sample.yaml +++ b/samples/subsys/usb/uac2_explicit_feedback/sample.yaml @@ -3,7 +3,7 @@ sample: tests: sample.subsys.usb.uac2_explicit_feedback: depends_on: - - usb_device + - usbd - i2s tags: usb i2s platform_allow: nrf5340dk/nrf5340/cpuapp diff --git a/samples/subsys/video/tcpserversink/README.rst b/samples/subsys/video/tcpserversink/README.rst index 6c7fc89afde4e1..83e9a62d9534df 100644 --- a/samples/subsys/video/tcpserversink/README.rst +++ b/samples/subsys/video/tcpserversink/README.rst @@ -29,11 +29,13 @@ interface. Ethernet cable must be connected to RJ45 connector. Building and Running ******************** -For :ref:`mimxrt1064_evk`, build this sample application with the following commands: +For :ref:`mimxrt1064_evk`, the sample can be built with the following command. +If a mt9m114 camera shield is missing, video software generator will be used instead. .. zephyr-app-commands:: :zephyr-app: samples/subsys/video/tcpserversink :board: mimxrt1064_evk + :shield: [dvp_fpc24_mt9m114] :goals: build :compact: @@ -42,7 +44,7 @@ Sample Output .. code-block:: console - Video device detected, format: RGBP 640x480 + Video device detected, format: RGBP 480x272 TCP: Waiting for client... Then from a peer on the same network you can connect and grab frames. @@ -52,11 +54,12 @@ Example with gstreamer: .. code-block:: console gst-launch-1.0 tcpclientsrc host=192.0.2.1 port=5000 \ - ! videoparse format=rgb16 width=640 height=480 \ + ! videoparse format=rgb16 width=480 height=272 \ ! queue \ ! videoconvert \ ! fpsdisplaysink sync=false +For video software generator, the default resolution should be width=320 and height=160. References ********** diff --git a/samples/subsys/video/tcpserversink/prj.conf b/samples/subsys/video/tcpserversink/prj.conf index 43ddea77f51d2a..824c424b2fa8aa 100644 --- a/samples/subsys/video/tcpserversink/prj.conf +++ b/samples/subsys/video/tcpserversink/prj.conf @@ -3,7 +3,7 @@ CONFIG_NETWORKING=y CONFIG_NET_TCP=y CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y -CONFIG_POSIX_MAX_FDS=6 +CONFIG_ZVFS_OPEN_MAX=6 CONFIG_POSIX_API=y # Kernel options diff --git a/samples/subsys/video/tcpserversink/sample.yaml b/samples/subsys/video/tcpserversink/sample.yaml index 6019ce0341ed7c..717923a6fa1998 100644 --- a/samples/subsys/video/tcpserversink/sample.yaml +++ b/samples/subsys/video/tcpserversink/sample.yaml @@ -7,9 +7,12 @@ tests: - video - net - socket + - shield platform_allow: mimxrt1064_evk depends_on: - video - netif integration_platforms: - mimxrt1064_evk + extra_args: + - platform:mimxrt1064_evk:SHIELD=dvp_fpc24_mt9m114 diff --git a/samples/subsys/video/tcpserversink/src/main.c b/samples/subsys/video/tcpserversink/src/main.c index 3b4cf3ba223aef..90946be44bd88a 100644 --- a/samples/subsys/video/tcpserversink/src/main.c +++ b/samples/subsys/video/tcpserversink/src/main.c @@ -15,7 +15,8 @@ #include LOG_MODULE_REGISTER(main); -#define MY_PORT 5000 +#define VIDEO_DEV_SW "VIDEO_SW_GENERATOR" +#define MY_PORT 5000 #define MAX_CLIENT_QUEUE 1 static ssize_t sendall(int sock, const void *buf, size_t len) @@ -40,8 +41,21 @@ int main(void) struct video_buffer *buffers[2], *vbuf; int i, ret, sock, client; struct video_format fmt; - const struct device *const video = DEVICE_DT_GET_ANY(nxp_imx_csi); +#if DT_HAS_CHOSEN(zephyr_camera) + const struct device *const video = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera)); + if (!device_is_ready(video)) { + LOG_ERR("%s: video device not ready.", video->name); + return 0; + } +#else + const struct device *const video = device_get_binding(VIDEO_DEV_SW); + + if (video == NULL) { + LOG_ERR("%s: video device not found or failed to initialized.", VIDEO_DEV_SW); + return 0; + } +#endif /* Prepare Network */ (void)memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -67,21 +81,15 @@ int main(void) return 0; } - if (!device_is_ready(video)) { - LOG_ERR("%s: device not ready.\n", video->name); - return 0; - } - /* Get default/native format */ if (video_get_format(video, VIDEO_EP_OUT, &fmt)) { LOG_ERR("Unable to retrieve video format"); return 0; } - printk("Video device detected, format: %c%c%c%c %ux%u\n", - (char)fmt.pixelformat, (char)(fmt.pixelformat >> 8), - (char)(fmt.pixelformat >> 16), (char)(fmt.pixelformat >> 24), - fmt.width, fmt.height); + printk("Video device detected, format: %c%c%c%c %ux%u\n", (char)fmt.pixelformat, + (char)(fmt.pixelformat >> 8), (char)(fmt.pixelformat >> 16), + (char)(fmt.pixelformat >> 24), fmt.width, fmt.height); /* Alloc Buffers */ for (i = 0; i < ARRAY_SIZE(buffers); i++) { @@ -96,8 +104,7 @@ int main(void) do { printk("TCP: Waiting for client...\n"); - client = accept(sock, (struct sockaddr *)&client_addr, - &client_addr_len); + client = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len); if (client < 0) { printk("Failed to accept: %d\n", errno); return 0; @@ -121,14 +128,13 @@ int main(void) /* Capture loop */ i = 0; do { - ret = video_dequeue(video, VIDEO_EP_OUT, &vbuf, - K_FOREVER); + ret = video_dequeue(video, VIDEO_EP_OUT, &vbuf, K_FOREVER); if (ret) { LOG_ERR("Unable to dequeue video buf"); return 0; } - printk("\rSending frame %d", i++); + printk("\rSending frame %d\n", i++); /* Send video buffer to TCP client */ ret = sendall(client, vbuf->buffer, vbuf->bytesused); @@ -149,8 +155,7 @@ int main(void) /* Flush remaining buffers */ do { - ret = video_dequeue(video, VIDEO_EP_OUT, - &vbuf, K_NO_WAIT); + ret = video_dequeue(video, VIDEO_EP_OUT, &vbuf, K_NO_WAIT); } while (!ret); } while (1); diff --git a/samples/tfm_integration/psa_crypto/prj.conf b/samples/tfm_integration/psa_crypto/prj.conf index dde93b26bd28f8..0abda9534232f7 100644 --- a/samples/tfm_integration/psa_crypto/prj.conf +++ b/samples/tfm_integration/psa_crypto/prj.conf @@ -29,6 +29,11 @@ CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y CONFIG_MBEDTLS_USER_CONFIG_FILE="config_mbedtls.h" CONFIG_MBEDTLS_PSA_CRYPTO_C=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC=y +CONFIG_PSA_WANT_ECC_SECP_R1_256=y +CONFIG_PSA_WANT_ALG_ECDSA=y +CONFIG_PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY=y CONFIG_MBEDTLS_ENTROPY_ENABLED=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y diff --git a/samples/userspace/prod_consumer/boards/frdm_rw612.overlay b/samples/userspace/prod_consumer/boards/frdm_rw612.overlay new file mode 100644 index 00000000000000..5df8d83c40b872 --- /dev/null +++ b/samples/userspace/prod_consumer/boards/frdm_rw612.overlay @@ -0,0 +1,17 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&smu1 { + smu1_data: memory@0 { + /delete-property/ zephyr,memory-attr; + }; +}; + +&smu2 { + smu2_data: memory@0 { + /delete-property/ zephyr,memory-attr; + }; +}; diff --git a/samples/userspace/shared_mem/boards/frdm_rw612.overlay b/samples/userspace/shared_mem/boards/frdm_rw612.overlay new file mode 100644 index 00000000000000..5df8d83c40b872 --- /dev/null +++ b/samples/userspace/shared_mem/boards/frdm_rw612.overlay @@ -0,0 +1,17 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&smu1 { + smu1_data: memory@0 { + /delete-property/ zephyr,memory-attr; + }; +}; + +&smu2 { + smu2_data: memory@0 { + /delete-property/ zephyr,memory-attr; + }; +}; diff --git a/scripts/build/llext_inject_slids.py b/scripts/build/llext_inject_slids.py new file mode 100755 index 00000000000000..19e87edba93385 --- /dev/null +++ b/scripts/build/llext_inject_slids.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +"""Injects SLIDs in LLEXT ELFs' symbol tables. + +When Kconfig option CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID is enabled, +all imports from the Zephyr kernel & application are resolved using +SLIDs instead of symbol names. This script stores the SLID of all +imported symbols in their associated entry in the ELF symbol table +to allow the LLEXT subsystem to link it properly at runtime. + +Note that this script is idempotent in theory. However, to prevent +any catastrophic problem, the script will abort if the 'st_value' +field of the `ElfX_Sym` structure is found to be non-zero, which is +the case after one invocation. For this reason, in practice, the script +cannot actually be executed twice on the same ELF file. +""" + +import argparse +import logging +import shutil +import sys + +from elftools.elf.elffile import ELFFile +from elftools.elf.sections import SymbolTableSection + +import llext_slidlib + +class LLEXTSymtabPreparator(): + def __init__(self, elf_path, log): + self.log = log + self.elf_path = elf_path + self.elf_fd = open(elf_path, "rb+") + self.elf = ELFFile(self.elf_fd) + + def _find_symtab(self): + supported_symtab_sections = [ + ".symtab", + ".dynsym", + ] + + symtab = None + for section_name in supported_symtab_sections: + symtab = self.elf.get_section_by_name(section_name) + if not isinstance(symtab, SymbolTableSection): + self.log.debug(f"section {section_name} not found.") + else: + self.log.info(f"processing '{section_name}' symbol table...") + self.log.debug(f"(symbol table is at file offset 0x{symtab['sh_offset']:X})") + break + return symtab + + def _find_imports_in_symtab(self, symtab): + i = 0 + imports = [] + for sym in symtab.iter_symbols(): + #Check if symbol is an import + if sym.entry['st_info']['type'] == 'STT_NOTYPE' and \ + sym.entry['st_info']['bind'] == 'STB_GLOBAL' and \ + sym.entry['st_shndx'] == 'SHN_UNDEF': + + self.log.debug(f"found imported symbol '{sym.name}' at index {i}") + imports.append((i, sym)) + + i += 1 + return imports + + def _prepare_inner(self): + #1) Locate the symbol table + symtab = self._find_symtab() + if symtab is None: + self.log.error("no symbol table found in file") + return 1 + + #2) Find imported symbols in symbol table + imports = self._find_imports_in_symtab(symtab) + self.log.info(f"LLEXT has {len(imports)} import(s)") + + #3) Write SLIDs in each symbol's 'st_value' field + def make_stvalue_reader_writer(): + byteorder = "little" if self.elf.little_endian else "big" + if self.elf.elfclass == 32: + sizeof_Elf_Sym = 0x10 #sizeof(Elf32_Sym) + offsetof_st_value = 0x4 #offsetof(Elf32_Sym, st_value) + sizeof_st_value = 0x4 #sizeof(Elf32_Sym.st_value) + else: + sizeof_Elf_Sym = 0x18 + offsetof_st_value = 0x8 + sizeof_st_value = 0x8 + + def seek(symidx): + self.elf_fd.seek( + symtab['sh_offset'] + + symidx * sizeof_Elf_Sym + + offsetof_st_value) + + def reader(symbol_index): + seek(symbol_index) + return int.from_bytes(self.elf_fd.read(sizeof_st_value), byteorder) + + def writer(symbol_index, st_value): + seek(symbol_index) + self.elf_fd.write(int.to_bytes(st_value, sizeof_st_value, byteorder)) + + return reader, writer + + rd_st_val, wr_st_val = make_stvalue_reader_writer() + slid_size = self.elf.elfclass // 8 + + for (index, symbol) in imports: + slid = llext_slidlib.generate_slid(symbol.name, slid_size) + slid_as_str = llext_slidlib.format_slid(slid, slid_size) + msg = f"{symbol.name} -> {slid_as_str}" + + self.log.info(msg) + + # Make sure we're not overwriting something actually important + original_st_value = rd_st_val(index) + if original_st_value != 0: + self.log.error(f"unexpected non-zero st_value for symbol {symbol.name}") + return 1 + + wr_st_val(index, slid) + + return 0 + + def prepare_llext(self): + res = self._prepare_inner() + self.elf_fd.close() + return res + +# Disable duplicate code warning for the code that follows, +# as it is expected for these functions to be similar. +# pylint: disable=duplicate-code +def _parse_args(argv): + """Parse the command line arguments.""" + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + allow_abbrev=False) + + parser.add_argument("-f", "--elf-file", required=True, + help="LLEXT ELF file to process") + parser.add_argument("-o", "--output-file", + help=("Additional output file where processed ELF " + "will be copied")) + parser.add_argument("-sl", "--slid-listing", + help="write the SLID listing to a file") + parser.add_argument("-v", "--verbose", action="count", + help=("enable verbose output, can be used multiple times " + "to increase verbosity level")) + parser.add_argument("--always-succeed", action="store_true", + help="always exit with a return code of 0, used for testing") + + return parser.parse_args(argv) + +def _init_log(verbose): + """Initialize a logger object.""" + log = logging.getLogger(__file__) + + console = logging.StreamHandler() + console.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) + log.addHandler(console) + + if verbose and verbose > 1: + log.setLevel(logging.DEBUG) + elif verbose and verbose > 0: + log.setLevel(logging.INFO) + else: + log.setLevel(logging.WARNING) + + return log + +def main(argv=None): + args = _parse_args(argv) + + log = _init_log(args.verbose) + + log.info(f"inject_slids_in_llext: {args.elf_file}") + + preparator = LLEXTSymtabPreparator(args.elf_file, log) + + res = preparator.prepare_llext() + + if args.always_succeed: + return 0 + + if res == 0 and args.output_file: + shutil.copy(args.elf_file, args.output_file) + + return res + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/scripts/build/llext_prepare_exptab.py b/scripts/build/llext_prepare_exptab.py new file mode 100755 index 00000000000000..c659709af17e6b --- /dev/null +++ b/scripts/build/llext_prepare_exptab.py @@ -0,0 +1,377 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +""" +Script to prepare the LLEXT exports table of a Zephyr ELF + +This script performs compile-time processing of the LLEXT exports +table for usage at runtime by the LLEXT subsystem code. The table +is a special section filled with 'llext_const_symbol' structures +generated by the EXPORT_SYMBOL macro. + +Currently, the preparatory work consists mostly of sorting the +exports table to allow usage of binary search algorithms at runtime. +If CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID option is enabled, SLIDs +of all exported functions are also injected in the export table by +this script. (In this case, the preparation process is destructive) +""" + +import llext_slidlib + +from elftools.elf.elffile import ELFFile +from elftools.elf.sections import Section + +import argparse +import logging +import pathlib +import struct +import sys + +#!!!!! WARNING !!!!! +# +#These constants MUST be kept in sync with the linker scripts +#and the EXPORT_SYMBOL macro located in 'subsys/llext/llext.h'. +#Otherwise, the LLEXT subsystem will be broken! +# +#!!!!! WARNING !!!!! + +LLEXT_EXPORT_TABLE_SECTION_NAME = "llext_const_symbol_area" +LLEXT_EXPORT_NAMES_SECTION_NAME = "llext_exports_strtab" + +def _llext_const_symbol_struct(ptr_size: int, endianness: str): + """ + ptr_size -- Platform pointer size in bytes + endianness -- Platform endianness ('little'/'big') + """ + endspec = "<" if endianness == 'little' else ">" + if ptr_size == 4: + ptrspec = "I" + elif ptr_size == 8: + ptrspec = "Q" + + # struct llext_const_symbol + # contains just two pointers. + lcs_spec = endspec + 2 * ptrspec + return struct.Struct(lcs_spec) + +#ELF Shdr flag applied to the export table section, to indicate +#the section has already been prepared by this script. This is +#mostly a security measure to prevent the script from running +#twice on the same ELF file, which can result in catastrophic +#failures if SLID-based linking is enabled (in this case, the +#preparation process is destructive). +# +#This flag is part of the SHF_MASKOS mask, of which all bits +#are "reserved for operating system-specific semantics". +#See: https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html +SHF_LLEXT_PREPARATION_DONE = 0x08000000 + +class SectionDescriptor(): + """ELF Section descriptor + + This is a wrapper class around pyelftools' "Section" object. + """ + def __init__(self, elffile, section_name): + self.name = section_name + self.section = elffile.get_section_by_name(section_name) + if not isinstance(self.section, Section): + raise KeyError(f"section {section_name} not found") + + self.shdr_index = elffile.get_section_index(section_name) + self.shdr_offset = elffile['e_shoff'] + \ + self.shdr_index * elffile['e_shentsize'] + self.size = self.section['sh_size'] + self.flags = self.section['sh_flags'] + self.offset = self.section['sh_offset'] + +class LLEXTExptabManipulator(): + """Class used to wrap the LLEXT export table manipulation.""" + def __init__(self, elf_fd, exptab_file_offset, lcs_struct, exports_count): + self.fd = elf_fd + self.exports_count = exports_count + self.base_offset = exptab_file_offset + self.lcs_struct = lcs_struct + + def _seek_to_sym(self, index): + self.fd.seek(self.base_offset + index * self.lcs_struct.size) + + def __getitem__(self, index): + if not isinstance(index, int): + raise TypeError(f"invalid type {type(index)} for index") + + if index >= self.exports_count: + raise IndexError(f"index {index} is out of bounds (max {self.exports_count})") + + self._seek_to_sym(index) + return self.lcs_struct.unpack(self.fd.read(self.lcs_struct.size)) + + def __setitem__(self, index, item): + if not isinstance(index, int): + raise TypeError(f"invalid type {type(index)} for index") + + if index >= self.exports_count: + raise IndexError(f"index {index} is out of bounds (max {self.exports_count})") + + (addr_or_slid, sym_addr) = item + + self._seek_to_sym(index) + self.fd.write(self.lcs_struct.pack(addr_or_slid, sym_addr)) + +class ZephyrElfExptabPreparator(): + """Prepares the LLEXT export table of a Zephyr ELF. + + Attributes: + elf_path: path to the Zephyr ELF to prepare + log: a logging.Logger object + slid_listing_path: path to the file where SLID listing should be saved + """ + def __init__(self, elf_path: str, log: logging.Logger, slid_listing_path: str | None): + self.elf_path = elf_path + self.elf_fd = open(self.elf_path, 'rb+') + self.elf = ELFFile(self.elf_fd) + self.log = log + + # Lazy-open the SLID listing file to ensure it is only created when necessary + self.slid_listing_path = slid_listing_path + self.slid_listing_fd = None + + def _prepare_exptab_for_slid_linking(self): + """ + IMPLEMENTATION NOTES: + In the linker script, we declare the export names table + as starting at address 0. Thanks to this, all "pointers" + to that section are equal to the offset inside the section. + Also note that symbol names are always NUL-terminated. + + The export table is sorted by SLID in ASCENDING order. + """ + def read_symbol_name(name_ptr): + raw_name = b'' + self.elf_fd.seek(self.expstrtab_section.offset + name_ptr) + + c = self.elf_fd.read(1) + while c != b'\0': + raw_name += c + c = self.elf_fd.read(1) + + return raw_name.decode("utf-8") + + #1) Load the export table + exports_list = [] + for (name_ptr, export_address) in self.exptab_manipulator: + export_name = read_symbol_name(name_ptr) + exports_list.append((export_name, export_address)) + + #2) Generate the SLID for all exports + collided = False + sorted_exptab = dict() + for export_name, export_addr in exports_list: + slid = llext_slidlib.generate_slid(export_name, self.ptrsize) + + collision = sorted_exptab.get(slid) + if collision: + #Don't abort immediately on collision: if there are others, we want to log them all. + self.log.error(f"SLID collision: {export_name} and {collision[0]} have the same SLID 0x{slid:X}") + collided = True + else: + sorted_exptab[slid] = (export_name, export_addr) + + if collided: + return 1 + + #3) Sort the export table (order specified above) + sorted_exptab = dict(sorted(sorted_exptab.items())) + + #4) Write the updated export table to ELF, and dump + #to SLID listing if requested by caller + if self.slid_listing_path: + self.slid_listing_fd = open(self.slid_listing_path, "w") + + def slidlist_write(msg): + if self.slid_listing_fd: + self.slid_listing_fd.write(msg + "\n") + + slidlist_write(f"/* SLID listing generated by {__file__} */") + slidlist_write("//") + slidlist_write("// This file contains the 'SLID -> name' mapping for all") + slidlist_write("// symbols exported to LLEXT by this Zephyr executable.") + slidlist_write("") + + self.log.info("SLID -> export name mapping:") + + i = 0 + for (slid, name_and_symaddr) in sorted_exptab.items(): + slid_as_str = llext_slidlib.format_slid(slid, self.ptrsize) + msg = f"{slid_as_str} -> {name_and_symaddr[0]}" + self.log.info(msg) + slidlist_write(msg) + + self.exptab_manipulator[i] = (slid, name_and_symaddr[1]) + i += 1 + + if self.slid_listing_fd: + self.slid_listing_fd.close() + + return 0 + + def _prepare_exptab_for_str_linking(self): + #TODO: sort the export table by symbol + # name to allow binary search too + # + # Plan of action: + # 1) Locate in which section the names are located + # 2) Load the export table and resolve names + # 3) Sort the exports by name + # WARN: THIS MUST USE THE SAME SORTING RULES + # AS LLEXT CODE OR DICHOTOMIC SEARCH WILL BREAK + # Using a custom sorting function might be required. + # 4) Write back the updated export table + # + # N.B.: reusing part of the code in _prepare_elf_for_slid_linking + # might be possible and desireable. + # + # As of writing, this function will never be called as this script + # is only called if CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID is enabled, + # which makes _prepare_exptab_for_slid_linking be called instead. + # + self.log.warn(f"_prepare_exptab_for_str_linking: do nothing") + return 0 + + def _set_prep_done_shdr_flag(self): + #Offset and size of the 'sh_flags' member of + #the Elf_Shdr structure. The offset does not + #change between ELF32 and ELF64. Size in both + #is equal to pointer size (4 bytes for ELF32, + #8 bytes for ELF64). + SHF_OFFSET = 8 + SHF_SIZE = self.ptrsize + + off = self.exptab_section.shdr_offset + SHF_OFFSET + + #Read existing sh_flags, set the PREPARATION_DONE flag + #and write back the new value. + self.elf_fd.seek(off) + sh_flags = int.from_bytes(self.elf_fd.read(SHF_SIZE), self.endianness) + + sh_flags |= SHF_LLEXT_PREPARATION_DONE + + self.elf_fd.seek(off) + self.elf_fd.write(int.to_bytes(sh_flags, self.ptrsize, self.endianness)) + + def _prepare_inner(self): + # Locate the export table section + try: + self.exptab_section = SectionDescriptor( + self.elf, LLEXT_EXPORT_TABLE_SECTION_NAME) + except KeyError as e: + self.log.error(e.args[0]) + return 1 + + # Abort if the ELF has already been processed + if (self.exptab_section.flags & SHF_LLEXT_PREPARATION_DONE) != 0: + self.log.warning("exptab section flagged with LLEXT_PREPARATION_DONE " + "- not preparing again") + return 0 + + # Get the struct.Struct for export table entry + self.ptrsize = self.elf.elfclass // 8 + self.endianness = 'little' if self.elf.little_endian else 'big' + self.lcs_struct = _llext_const_symbol_struct(self.ptrsize, self.endianness) + + # Verify that the export table size is coherent + if (self.exptab_section.size % self.lcs_struct.size) != 0: + self.log.error(f"export table size (0x{self.exptab_section.size:X}) " + f"not aligned to 'llext_const_symbol' size (0x{self.lcs_struct.size:X})") + return 1 + + # Create the export table manipulator + num_exports = self.exptab_section.size // self.lcs_struct.size + self.exptab_manipulator = LLEXTExptabManipulator( + self.elf_fd, self.exptab_section.offset, self.lcs_struct, num_exports) + + # Attempt to locate the export names section + try: + self.expstrtab_section = SectionDescriptor( + self.elf, LLEXT_EXPORT_NAMES_SECTION_NAME) + except KeyError: + self.expstrtab_section = None + + self.log.debug(f"exports table section at file offset 0x{self.exptab_section.offset:X}") + if self.expstrtab_section: + self.log.debug(f"exports strtab section at file offset 0x{self.expstrtab_section.offset:X}") + else: + self.log.debug("no exports strtab section in ELF") + self.log.info(f"{num_exports} symbols are exported to LLEXTs by this ELF") + + # Perform the export table preparation + if self.expstrtab_section: + res = self._prepare_exptab_for_slid_linking() + else: + res = self._prepare_exptab_for_str_linking() + + if res == 0: # Add the "prepared" flag to export table section + self._set_prep_done_shdr_flag() + + def prepare_elf(self): + res = self._prepare_inner() + self.elf_fd.close() + return res + +# pylint: disable=duplicate-code +def _parse_args(argv): + """Parse the command line arguments.""" + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + allow_abbrev=False) + + parser.add_argument("-f", "--elf-file", default=pathlib.Path("build", "zephyr", "zephyr.elf"), + help="ELF file to process") + parser.add_argument("-sl", "--slid-listing", + help=("write the SLID listing to a file (only useful" + "when CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID is enabled) ")) + parser.add_argument("-v", "--verbose", action="count", + help=("enable verbose output, can be used multiple times " + "to increase verbosity level")) + parser.add_argument("--always-succeed", action="store_true", + help="always exit with a return code of 0, used for testing") + + return parser.parse_args(argv) + +def _init_log(verbose): + """Initialize a logger object.""" + log = logging.getLogger(__file__) + + console = logging.StreamHandler() + console.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) + log.addHandler(console) + + if verbose and verbose > 1: + log.setLevel(logging.DEBUG) + elif verbose and verbose > 0: + log.setLevel(logging.INFO) + else: + log.setLevel(logging.WARNING) + + return log + +def main(argv=None): + args = _parse_args(argv) + + log = _init_log(args.verbose) + + log.info(f"prepare_llext_exptab: {args.elf_file}") + + preparator = ZephyrElfExptabPreparator(args.elf_file, log, args.slid_listing) + + res = preparator.prepare_elf() + + if args.always_succeed: + return 0 + + return res + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/scripts/build/llext_slidlib.py b/scripts/build/llext_slidlib.py new file mode 100755 index 00000000000000..99157c526dcc3f --- /dev/null +++ b/scripts/build/llext_slidlib.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +""" +This file implements the Symbol Link Identifer (SLID) +generation code, for use by the LLEXT subsystem. +SLID-based linking is enabled by the Kconfig +option 'CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID'. + +When executed as a script, this file can be used as +an interactive prompt to calculate the SLID of arbitrary +symbols, which can be useful for debugging purposes. + +IMPLEMENTATION NOTES: + Currently, SLIDs are generated by taking the first + [pointer size] bytes of the symbol name's SHA-256 + hash, taken in big-endian order. + + This ordering provides one advantage: the 32-bit + SLID for an export is present in the top 32 bits of + the 64-bit SLID for the same export. +""" + +from hashlib import sha256 + +def generate_slid(symbol_name: str, slid_size: int) -> int: + """ + Generates the Symbol Link Identifier (SLID) for a symbol. + + symbol_name: Name of the symbol for which to generate a SLID + slid_side: Size of the SLID in bytes (4/8) + """ + if slid_size not in (4, 8): + raise AssertionError(f"Invalid SLID size {slid_size}") + + m = sha256() + m.update(symbol_name.encode("utf-8")) + hash = m.digest() + return int.from_bytes(hash[0:slid_size], byteorder='big', signed=False) + +def format_slid(slid: int, slid_size: int) -> str: + if slid_size == 4: + fmt = f"0x{slid:08X}" + elif slid_size == 8: + fmt = f"0x{slid:016X}" + return fmt + +def repl(): + while True: + sym_name = input("Symbol name? ") + slid32 = generate_slid(sym_name, 4) + slid64 = generate_slid(sym_name, 8) + print(f" 32-bit SLID for '{sym_name}': {format_slid(slid32, 4)}") + print(f" 64-bit SLID for '{sym_name}': {format_slid(slid64, 8)}") + print() + +if __name__ == "__main__": + print("LLEXT SLID calculation REPL") + print("Press ^C to exit.") + try: + repl() + except KeyboardInterrupt: + print() diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 090559e2049238..5ae142f033239f 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -943,6 +943,9 @@ def check_no_undef_outside_kconfig(self, kconf): "ZEPHYR_TRY_MASS_ERASE", # MCUBoot setting described in sysbuild # documentation "ZTEST_FAIL_TEST_", # regex in tests/ztest/fail/CMakeLists.txt + "SUIT_MPI_GENERATE", # Used by nRF runners to program provisioning data, based on build configuration + "SUIT_MPI_APP_AREA_PATH", # Used by nRF runners to program provisioning data, based on build configuration + "SUIT_MPI_RAD_AREA_PATH", # Used by nRF runners to program provisioning data, based on build configuration } diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index edbbbf2d923be2..54ead528195947 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -17,6 +17,11 @@ from git import Repo from west.manifest import Manifest +try: + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeLoader + if "ZEPHYR_BASE" not in os.environ: exit("$ZEPHYR_BASE environment variable undefined.") @@ -26,13 +31,13 @@ repository_path = zephyr_base repo_to_scan = Repo(zephyr_base) args = None - - logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) +logging.getLogger("pykwalify.core").setLevel(50) sys.path.append(os.path.join(zephyr_base, 'scripts')) import list_boards + def _get_match_fn(globs, regexes): # Constructs a single regex that tests for matches against the globs in # 'globs' and the regexes in 'regexes'. Parts are joined with '|' (OR). @@ -214,45 +219,50 @@ def find_archs(self): self.get_plan(_options, True) def find_boards(self): - boards = set() - all_boards = set() - resolved = [] + changed_boards = set() + matched_boards = {} + resolved_files = [] - for f in self.modified_files: - if f.endswith(".rst") or f.endswith(".png") or f.endswith(".jpg"): + for file in self.modified_files: + if file.endswith(".rst") or file.endswith(".png") or file.endswith(".jpg"): continue - p = re.match(r"^boards\/[^/]+\/([^/]+)\/", f) - if p and p.groups(): - boards.add(p.group(1)) - resolved.append(f) + if file.startswith("boards/"): + changed_boards.add(file) + resolved_files.append(file) roots = [zephyr_base] if repository_path != zephyr_base: roots.append(repository_path) # Look for boards in monitored repositories - lb_args = argparse.Namespace(**{'arch_roots': roots, 'board_roots': roots, 'board': None, + lb_args = argparse.Namespace(**{'arch_roots': roots, 'board_roots': roots, 'board': None, 'soc_roots':roots, 'board_dir': None}) - known_boards = list_boards.find_boards(lb_args) - for b in boards: - name_re = re.compile(b) - for kb in known_boards: - if name_re.search(kb.name): - all_boards.add(kb.name) - - # If modified file is catched by "find_boards" workflow (change in "boards" dir AND board recognized) + known_boards = list_boards.find_v2_boards(lb_args) + + for changed in changed_boards: + for board in known_boards: + c = (zephyr_base / changed).resolve() + if c.is_relative_to(board.dir.resolve()): + for file in glob.glob(os.path.join(board.dir, f"{board.name}*.yaml")): + with open(file, 'r') as f: + b = yaml.load(f.read(), Loader=SafeLoader) + matched_boards[b['identifier']] = board + + + logging.info(f"found boards: {','.join(matched_boards.keys())}") + # If modified file is caught by "find_boards" workflow (change in "boards" dir AND board recognized) # it means a proper testing scope for this file was found and this file can be removed # from further consideration - for board in all_boards: - self.resolved_files.extend(list(filter(lambda f: board in f, resolved))) + for _, board in matched_boards.items(): + self.resolved_files.extend(list(filter(lambda f: str(board.dir.relative_to(zephyr_base)) in f, resolved_files))) _options = [] - if len(all_boards) > 20: - logging.warning(f"{len(boards)} boards changed, this looks like a global change, skipping test handling, revert to default.") + if len(matched_boards) > 20: + logging.warning(f"{len(matched_boards)} boards changed, this looks like a global change, skipping test handling, revert to default.") self.full_twister = True return - for board in all_boards: + for board in matched_boards: _options.extend(["-p", board ]) if _options: diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index 8db6878be3ae80..329a26d4d1e079 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -31,6 +31,8 @@ doc/* # GH action have no impact on code .github/* *.rst +*.jpg +*.png *.md # if we change this file or associated script, it should not trigger a full # twister. diff --git a/scripts/coredump/gdbstubs/arch/arm64.py b/scripts/coredump/gdbstubs/arch/arm64.py index 008fb88c1b963a..7f4c03eb375ea9 100644 --- a/scripts/coredump/gdbstubs/arch/arm64.py +++ b/scripts/coredump/gdbstubs/arch/arm64.py @@ -95,7 +95,7 @@ def parse_arch_data_block(self): self.registers[RegNum.X17] = tu[17] self.registers[RegNum.X18] = tu[18] - # Callee saved registers are not provided in __esf structure + # Callee saved registers are not provided in arch_esf structure # So they will be omitted (set to undefined) when stub generates the # packet in handle_register_group_read_packet. diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index eb350b0483b70f..a9d02dcd4d75d4 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -132,6 +132,13 @@ def main(): out_dt_define(f"{node.z_path_id}_CHILD_IDX", node.parent.child_index(node)) + out_comment("Helpers for dealing with node labels:") + out_dt_define(f"{node.z_path_id}_NODELABEL_NUM", len(node.labels)) + out_dt_define(f"{node.z_path_id}_FOREACH_NODELABEL(fn)", + " ".join(f"fn({nodelabel})" for nodelabel in node.labels)) + out_dt_define(f"{node.z_path_id}_FOREACH_NODELABEL_VARGS(fn, ...)", + " ".join(f"fn({nodelabel}, __VA_ARGS__)" for nodelabel in node.labels)) + write_children(node) write_dep_info(node) write_idents_and_existence(node) @@ -416,6 +423,7 @@ def write_regs(node): idx_vals.append((idx_macro, f"{reg.addr} /* {hex(reg.addr)} */")) if reg.name: + name_vals.append((f"{path_id}_REG_NAME_{reg.name}_EXISTS", 1)) name_macro = f"{path_id}_REG_NAME_{reg.name}_VAL_ADDRESS" name_vals.append((name_macro, f"DT_{idx_macro}")) diff --git a/scripts/dts/python-devicetree/src/devicetree/dtlib.py b/scripts/dts/python-devicetree/src/devicetree/dtlib.py index d74fbc67d37d49..cc510ced403568 100644 --- a/scripts/dts/python-devicetree/src/devicetree/dtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/dtlib.py @@ -166,7 +166,13 @@ def _get_prop(self, name: str) -> 'Property': return prop def _del(self) -> None: - # Removes the node from the tree + # Removes the node from the tree. When called on the root node, + # this method will leave it empty but still part of the tree. + + if self.parent is None: + self.nodes.clear() + self.props.clear() + return self.parent.nodes.pop(self.name) # type: ignore def __str__(self): diff --git a/scripts/dts/python-devicetree/tests/test_dtlib.py b/scripts/dts/python-devicetree/tests/test_dtlib.py index b1b6ce33fd5a28..f7c8a31cc673c6 100644 --- a/scripts/dts/python-devicetree/tests/test_dtlib.py +++ b/scripts/dts/python-devicetree/tests/test_dtlib.py @@ -911,6 +911,15 @@ def test_deletion(): verify_parse(""" /dts-v1/; +/ { + x = "foo"; + sub0 { + x = "bar"; + }; +}; + +/delete-node/ &{/}; + / { sub1 { x = < 1 >; @@ -940,6 +949,29 @@ def test_deletion(): x = < 0x1 >; }; }; +""") + + verify_parse(""" +/dts-v1/; + +/ { + x: x = < &sub >, ⊂ + + sub1 { + x = < &sub >, ⊂ + }; + sub2: sub2 { + x = < &sub >, ⊂ + }; +}; + +/delete-node/ &{/}; +""", +""" +/dts-v1/; + +/ { +}; """) verify_error_endswith(""" diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 58fcf9c6a18860..35699e96cb608f 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -29,6 +29,7 @@ edtlib = inspect.getmodule(edt) else: edt = None + edtlib = None def _warn(kconf, msg): @@ -657,6 +658,32 @@ def dt_node_ph_array_prop(kconf, name, path, prop, index, cell, unit=None): if name == "dt_node_ph_array_prop_hex": return hex(_node_ph_array_prop(node, prop, index, cell, unit)) +def dt_node_ph_prop_path(kconf, name, path, prop): + """ + This function takes a 'path' and a property name ('prop') and + looks for an EDT node at that path. If it finds an EDT node, + it will look to see if that node has a property called 'prop' + and if that 'prop' is an phandle type. Then it will return the + path to the pointed-to node, or an empty string if there is + no such node. + """ + if doc_mode or edt is None: + return "" + + try: + node = edt.get_node(path) + except edtlib.EDTError: + return "" + + if prop not in node.props: + return "" + if node.props[prop].type != "phandle": + return "" + + phandle = node.props[prop].val + + return phandle.path if phandle else "" + def dt_node_str_prop_equals(kconf, _, path, prop, val): """ This function takes a 'path' and property name ('prop') looks for an EDT @@ -722,6 +749,21 @@ def dt_compat_on_bus(kconf, _, compat, bus): return "n" +def dt_compat_any_has_prop(kconf, _, compat, prop): + """ + This function takes a 'compat' and a 'prop' and returns "y" if any + node with compatible 'compat' also has a valid property 'prop'. + It returns "n" otherwise. + """ + if doc_mode or edt is None: + return "n" + + if compat in edt.compat2okay: + for node in edt.compat2okay[compat]: + if prop in node.props: + return "y" + + return "n" def dt_nodelabel_has_compat(kconf, _, label, compat): """ @@ -889,6 +931,7 @@ def substring(kconf, _, string, start, stop=None): "dt_has_compat": (dt_has_compat, 1, 1), "dt_compat_enabled": (dt_compat_enabled, 1, 1), "dt_compat_on_bus": (dt_compat_on_bus, 2, 2), + "dt_compat_any_has_prop": (dt_compat_any_has_prop, 2, 2), "dt_chosen_label": (dt_chosen_label, 1, 1), "dt_chosen_enabled": (dt_chosen_enabled, 1, 1), "dt_chosen_path": (dt_chosen_path, 1, 1), @@ -920,6 +963,7 @@ def substring(kconf, _, string, start, stop=None): "dt_node_array_prop_hex": (dt_node_array_prop, 3, 4), "dt_node_ph_array_prop_int": (dt_node_ph_array_prop, 4, 5), "dt_node_ph_array_prop_hex": (dt_node_ph_array_prop, 4, 5), + "dt_node_ph_prop_path": (dt_node_ph_prop_path, 2, 2), "dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3), "dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2), "dt_node_has_compat": (dt_node_has_compat, 2, 2), diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index 60537608357a10..e484cb8bb43ca4 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -117,6 +117,10 @@ def pytest_addoption(parser: pytest.Parser): choices=('function', 'class', 'module', 'package', 'session'), help='The scope for which `dut` and `shell` fixtures are shared.' ) + twister_harness_group.addoption( + '--twister-fixture', action='append', dest='fixtures', metavar='FIXTURE', default=[], + help='Twister fixture supported by this platform. May be given multiple times.' + ) def pytest_configure(config: pytest.Config): diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py index 08087a97387c12..a4b0b7497775d1 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py @@ -33,6 +33,7 @@ class DeviceConfig: pre_script: Path | None = None post_script: Path | None = None post_flash_script: Path | None = None + fixtures: list[str] = None app_build_dir: Path | None = None def __post_init__(self): @@ -77,6 +78,7 @@ def create(cls, config: pytest.Config) -> TwisterHarnessConfig: pre_script=_cast_to_path(config.option.pre_script), post_script=_cast_to_path(config.option.post_script), post_flash_script=_cast_to_path(config.option.post_flash_script), + fixtures=config.option.fixtures, ) devices.append(device_from_cli) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 85b7cdb371e102..01b415ad820f12 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -257,7 +257,7 @@ def add_parse_arguments(parser = None): "-A", "--board-root", action="append", default=board_root_list, help="""Directory to search for board configuration files. All .yaml files in the directory will be processed. The directory should have the same -structure in the main Zephyr tree: boards///""") +structure in the main Zephyr tree: boards///""") parser.add_argument( "--allow-installed-plugin", action="store_true", default=None, @@ -385,6 +385,18 @@ def add_parse_arguments(parser = None): help="Generate detailed json reports with ROM/RAM symbol sizes for each test image built " "using additional build option `--target footprint`.") + footprint_group.add_argument( + "--footprint-report", + nargs="?", + default=None, + choices=['all', 'ROM', 'RAM'], + const="all", + help="Select which memory area symbols' data to collect as 'footprint' property " + "of each test suite built, and report in 'twister_footprint.json' together " + "with the relevant execution metadata the same way as in `twister.json`. " + "Implies '--create-rom-ram-report' to generate the footprint data files. " + "No value means '%(const)s'. Default: %(default)s""") + footprint_group.add_argument( "--enable-size-report", action="store_true", @@ -547,6 +559,8 @@ def add_parse_arguments(parser = None): parser.add_argument("--overflow-as-errors", action="store_true", help="Treat RAM/SRAM overflows as errors.") + parser.add_argument("--report-filtered", action="store_true", + help="Include filtered tests in the reports.") parser.add_argument("-P", "--exclude-platform", action="append", default=[], help="""Exclude platforms and do not build or run any tests @@ -788,6 +802,9 @@ def parse_arguments(parser, args, options = None, on_init=True): if options.last_metrics or options.compare_report: options.enable_size_report = True + if options.footprint_report: + options.create_rom_ram_report = True + if options.aggressive_no_clean: options.no_clean = True diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 3a3c8de4cb37ef..8655dc0d54fccd 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -456,7 +456,7 @@ def device_is_available(self, instance): dut_found = False for d in self.duts: - if fixture and fixture not in d.fixtures: + if fixture and fixture not in map(lambda f: f.split(sep=':')[0], d.fixtures): continue if d.platform != device or (d.serial is None and d.serial_pty is None): continue @@ -569,6 +569,16 @@ def _update_instance_info(self, harness_state, handler_time, flash_error): if self.instance.status in ["error", "failed"]: self.instance.add_missing_case_status("blocked", self.instance.reason) + def _terminate_pty(self, ser_pty, ser_pty_process): + logger.debug(f"Terminating serial-pty:'{ser_pty}'") + terminate_process(ser_pty_process) + try: + (stdout, stderr) = ser_pty_process.communicate(timeout=self.get_test_timeout()) + logger.debug(f"Terminated serial-pty:'{ser_pty}', stdout:'{stdout}', stderr:'{stderr}'") + except subprocess.TimeoutExpired: + logger.debug(f"Terminated serial-pty:'{ser_pty}'") + # + def _create_serial_connection(self, serial_device, hardware_baud, flash_timeout, serial_pty, ser_pty_process): try: @@ -588,9 +598,7 @@ def _create_serial_connection(self, serial_device, hardware_baud, self.instance.add_missing_case_status("blocked", "Serial Device Error") if serial_pty and ser_pty_process: - ser_pty_process.terminate() - outs, errs = ser_pty_process.communicate() - logger.debug("Process {} terminated outs: {} errs {}".format(serial_pty, outs, errs)) + self._terminate_pty(serial_pty, ser_pty_process) if serial_pty: self.make_device_available(serial_pty) @@ -754,9 +762,7 @@ def handle(self, harness): ser.close() if serial_pty: - ser_pty_process.terminate() - outs, errs = ser_pty_process.communicate() - logger.debug("Process {} terminated outs: {} errs {}".format(serial_pty, outs, errs)) + self._terminate_pty(serial_pty, ser_pty_process) handler_time = time.time() - start_time @@ -793,6 +799,10 @@ def __init__(self, instance, type_str): self.pid_fn = os.path.join(instance.build_dir, "qemu.pid") + self.stdout_fn = os.path.join(instance.build_dir, "qemu.stdout") + + self.stderr_fn = os.path.join(instance.build_dir, "qemu.stderr") + if instance.testsuite.ignore_qemu_crash: self.ignore_qemu_crash = True self.ignore_unexpected_eof = True @@ -856,19 +866,12 @@ def _thread_close_files(fifo_in, fifo_out, pid, out_fp, in_fp, log_out_fp): os.unlink(fifo_out) @staticmethod - def _thread_update_instance_info(handler, handler_time, out_state): + def _thread_update_instance_info(handler, handler_time, status, reason): handler.instance.execution_time = handler_time - if out_state == "timeout": - handler.instance.status = "failed" - handler.instance.reason = "Timeout" - elif out_state == "failed": - handler.instance.status = "failed" - handler.instance.reason = "Failed" - elif out_state in ['unexpected eof', 'unexpected byte']: - handler.instance.status = "failed" - handler.instance.reason = out_state + handler.instance.status = status + if reason: + handler.instance.reason = reason else: - handler.instance.status = out_state handler.instance.reason = "Unknown" @staticmethod @@ -886,7 +889,8 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, timeout_time = start_time + timeout p = select.poll() p.register(in_fp, select.POLLIN) - out_state = None + _status = None + _reason = None line = "" timeout_extended = False @@ -907,17 +911,19 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, # of not enough CPU time scheduled by host for # QEMU process during p.poll(this_timeout) cpu_time = QEMUHandler._get_cpu_time(pid) - if cpu_time < timeout and not out_state: + if cpu_time < timeout and not _status: timeout_time = time.time() + (timeout - cpu_time) continue except psutil.NoSuchProcess: pass except ProcessLookupError: - out_state = "failed" + _status = "failed" + _reason = "Execution error" break - if not out_state: - out_state = "timeout" + if not _status: + _status = "failed" + _reason = "timeout" break if pid == 0 and os.path.exists(pid_fn): @@ -927,13 +933,15 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, c = in_fp.read(1).decode("utf-8") except UnicodeDecodeError: # Test is writing something weird, fail - out_state = "unexpected byte" + _status = "failed" + _reason = "unexpected byte" break if c == "": # EOF, this shouldn't happen unless QEMU crashes if not ignore_unexpected_eof: - out_state = "unexpected eof" + _status = "failed" + _reason = "unexpected eof" break line = line + c if c != "\n": @@ -947,13 +955,14 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, harness.handle(line) if harness.state: - # if we have registered a fail make sure the state is not + # if we have registered a fail make sure the status is not # overridden by a false success message coming from the # testsuite - if out_state not in ['failed', 'unexpected eof', 'unexpected byte']: - out_state = harness.state + if _status != 'failed': + _status = harness.state + _reason = harness.reason - # if we get some state, that means test is doing well, we reset + # if we get some status, that means test is doing well, we reset # the timeout and wait for 2 more seconds to catch anything # printed late. We wait much longer if code # coverage is enabled since dumping this information can @@ -967,9 +976,9 @@ def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, line = "" handler_time = time.time() - start_time - logger.debug(f"QEMU ({pid}) complete ({out_state}) after {handler_time} seconds") + logger.debug(f"QEMU ({pid}) complete with {_status} ({_reason}) after {handler_time} seconds") - QEMUHandler._thread_update_instance_info(handler, handler_time, out_state) + QEMUHandler._thread_update_instance_info(handler, handler_time, _status, _reason) QEMUHandler._thread_close_files(fifo_in, fifo_out, pid, out_fp, in_fp, log_out_fp) @@ -1028,7 +1037,7 @@ def handle(self, harness): is_timeout = False qemu_pid = None - with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.build_dir) as proc: + with subprocess.Popen(command, stdout=open(self.stdout_fn, "wt"), stderr=open(self.stderr_fn, "wt"), cwd=self.build_dir) as proc: logger.debug("Spawning QEMUHandler Thread for %s" % self.name) try: @@ -1133,19 +1142,12 @@ def _stop_qemu_process(pid): pass @staticmethod - def _monitor_update_instance_info(handler, handler_time, out_state): + def _monitor_update_instance_info(handler, handler_time, status, reason): handler.instance.execution_time = handler_time - if out_state == "timeout": - handler.instance.status = "failed" - handler.instance.reason = "Timeout" - elif out_state == "failed": - handler.instance.status = "failed" - handler.instance.reason = "Failed" - elif out_state in ['unexpected eof', 'unexpected byte']: - handler.instance.status = "failed" - handler.instance.reason = out_state + handler.instance.status = status + if reason: + handler.instance.reason = reason else: - handler.instance.status = out_state handler.instance.reason = "Unknown" def _set_qemu_filenames(self, sysbuild_build_dir): @@ -1193,7 +1195,8 @@ def _enqueue_char(self, queue): def _monitor_output(self, queue, timeout, logfile, pid_fn, harness, ignore_unexpected_eof=False): start_time = time.time() timeout_time = start_time + timeout - out_state = None + _status = None + _reason = None line = "" timeout_extended = False self.pid = 0 @@ -1209,17 +1212,19 @@ def _monitor_output(self, queue, timeout, logfile, pid_fn, harness, ignore_unexp # of not enough CPU time scheduled by host for # QEMU process during p.poll(this_timeout) cpu_time = self._get_cpu_time(self.pid) - if cpu_time < timeout and not out_state: + if cpu_time < timeout and not _status: timeout_time = time.time() + (timeout - cpu_time) continue except psutil.NoSuchProcess: pass except ProcessLookupError: - out_state = "failed" + _status = "failed" + _reason = "Execution error" break - if not out_state: - out_state = "timeout" + if not _status: + _status = "failed" + _reason = "timeout" break if self.pid == 0 and os.path.exists(pid_fn): @@ -1237,13 +1242,15 @@ def _monitor_output(self, queue, timeout, logfile, pid_fn, harness, ignore_unexp c = c.decode("utf-8") except UnicodeDecodeError: # Test is writing something weird, fail - out_state = "unexpected byte" + _status = "failed" + _reason = "unexpected byte" break if c == "": # EOF, this shouldn't happen unless QEMU crashes if not ignore_unexpected_eof: - out_state = "unexpected eof" + _status = "failed" + _reason = "unexpected eof" break line = line + c if c != "\n": @@ -1260,8 +1267,9 @@ def _monitor_output(self, queue, timeout, logfile, pid_fn, harness, ignore_unexp # if we have registered a fail make sure the state is not # overridden by a false success message coming from the # testsuite - if out_state not in ['failed', 'unexpected eof', 'unexpected byte']: - out_state = harness.state + if _status != 'failed': + _status = harness.state + _reason = harness.reason # if we get some state, that means test is doing well, we reset # the timeout and wait for 2 more seconds to catch anything @@ -1279,8 +1287,8 @@ def _monitor_output(self, queue, timeout, logfile, pid_fn, harness, ignore_unexp self.stop_thread = True handler_time = time.time() - start_time - logger.debug(f"QEMU ({self.pid}) complete ({out_state}) after {handler_time} seconds") - self._monitor_update_instance_info(self, handler_time, out_state) + logger.debug(f"QEMU ({self.pid}) complete with {_status} ({_reason}) after {handler_time} seconds") + self._monitor_update_instance_info(self, handler_time, _status, _reason) self._close_log_file(log_out_fp) self._stop_qemu_process(self.pid) diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index e60ba35dd56223..c07e777ca75456 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -288,8 +288,11 @@ def scan(self, persistent=False): def readlink(link): return str((by_id / link).resolve()) - persistent_map = {readlink(link): str(link) - for link in by_id.iterdir()} + if by_id.exists(): + persistent_map = {readlink(link): str(link) + for link in by_id.iterdir()} + else: + persistent_map = {} else: persistent_map = {} diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 8f4f47a7f082db..6108703c22f92c 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -45,6 +45,7 @@ class Harness: def __init__(self): self.state = None + self.reason = None self.type = None self.regex = [] self.matches = OrderedDict() @@ -114,11 +115,13 @@ def process_test(self, line): if self.RUN_PASSED in line: if self.fault: self.state = "failed" + self.reason = "Fault detected while running test" else: self.state = "passed" if self.RUN_FAILED in line: self.state = "failed" + self.reason = "Testsuite failed" if self.fail_on_fault: if self.FAULT == line: @@ -273,11 +276,13 @@ def handle(self, line): f" {self.next_pattern} of {self.patterns_expected}" f" expected ordered patterns.") self.state = "failed" + self.reason = "patterns did not match (ordered)" if self.state == "passed" and not self.ordered and len(self.matches) < self.patterns_expected: logger.error(f"HARNESS:{self.__class__.__name__}: failed with" f" {len(self.matches)} of {self.patterns_expected}" f" expected unordered patterns.") self.state = "failed" + self.reason = "patterns did not match (unordered)" tc = self.instance.get_case_or_create(self.get_testcase_name()) if self.state == "passed": @@ -353,6 +358,10 @@ def generate_command(self): else: raise PytestHarnessException(f'Support for handler {handler.type_str} not implemented yet') + if handler.type_str != 'device': + for fixture in handler.options.fixture: + command.append(f'--twister-fixture={fixture}') + if handler.options.pytest_args: command.extend(handler.options.pytest_args) if pytest_args_yaml: @@ -410,6 +419,9 @@ def _generate_parameters_for_hardware(self, handler: Handler): if hardware.flash_before: command.append(f'--flash-before={hardware.flash_before}') + for fixture in hardware.fixtures: + command.append(f'--twister-fixture={fixture}') + return command def run_command(self, cmd, timeout): @@ -679,12 +691,13 @@ def handle(self, line): self.process_test(line) if not self.ztest and self.state: - logger.debug(f"not a ztest and no state for {self.id}") + logger.debug(f"not a ztest and no state for {self.id}") tc = self.instance.get_case_or_create(self.id) if self.state == "passed": tc.status = "passed" else: tc.status = "failed" + tc.reason = "Test failure" class Ztest(Test): diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index 48c9df082c486f..c6885420803648 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -18,6 +18,16 @@ class Reporting: + json_filters = { + 'twister.json': { + 'deny_suite': ['footprint'] + }, + 'footprint.json': { + 'deny_status': ['filtered'], + 'deny_suite': ['testcases', 'execution_time', 'recording', 'retries', 'runnable'] + } + } + def __init__(self, plan, env) -> None: self.plan = plan #FIXME self.instances = plan.instances @@ -28,6 +38,7 @@ def __init__(self, plan, env) -> None: self.timestamp = datetime.now().isoformat() self.outdir = os.path.abspath(env.options.outdir) self.instance_fail_count = plan.instance_fail_count + self.footprint = None @staticmethod def process_log(log_file): @@ -234,7 +245,7 @@ def xunit_report(self, json_file, filename, selected_platform=None, full_report= with open(filename, 'wb') as report: report.write(result) - def json_report(self, filename, version="NA", platform=None): + def json_report(self, filename, version="NA", platform=None, filters=None): logger.info(f"Writing JSON report {filename}") if self.env.options.report_all_options: @@ -259,6 +270,16 @@ def json_report(self, filename, version="NA", platform=None): for instance in self.instances.values(): if platform and platform != instance.platform.name: continue + if instance.status == "filtered" and not self.env.options.report_filtered: + continue + if (filters and 'allow_status' in filters and instance.status not in filters['allow_status']): + logger.debug(f"Skip test suite '{instance.testsuite.name}' status '{instance.status}' " + f"not allowed for {filename}") + continue + if (filters and 'deny_status' in filters and instance.status in filters['deny_status']): + logger.debug(f"Skip test suite '{instance.testsuite.name}' status '{instance.status}' " + f"denied for {filename}") + continue suite = {} handler_log = os.path.join(instance.build_dir, "handler.log") pytest_log = os.path.join(instance.build_dir, "twister_harness.log") @@ -364,6 +385,36 @@ def json_report(self, filename, version="NA", platform=None): if instance.recording is not None: suite['recording'] = instance.recording + if (instance.status + and instance.status not in ["error", "filtered"] + and self.env.options.create_rom_ram_report + and self.env.options.footprint_report is not None): + # Init as empty data preparing for filtering properties. + suite['footprint'] = {} + + # Pass suite properties through the context filters. + if filters and 'allow_suite' in filters: + suite = {k:v for k,v in suite.items() if k in filters['allow_suite']} + + if filters and 'deny_suite' in filters: + suite = {k:v for k,v in suite.items() if k not in filters['deny_suite']} + + # Compose external data only to these properties which pass filtering. + if 'footprint' in suite: + do_all = 'all' in self.env.options.footprint_report + footprint_files = { 'ROM': 'rom.json', 'RAM': 'ram.json' } + for k,v in footprint_files.items(): + if do_all or k in self.env.options.footprint_report: + footprint_fname = os.path.join(instance.build_dir, v) + try: + with open(footprint_fname, "rt") as footprint_json: + logger.debug(f"Collect footprint.{k} for '{instance.name}'") + suite['footprint'][k] = json.load(footprint_json) + except FileNotFoundError: + logger.error(f"Missing footprint.{k} for '{instance.name}'") + # + # + suites.append(suite) report["testsuites"] = suites @@ -568,7 +619,11 @@ def save_reports(self, name, suffix, report_dir, no_update, platform_reports): if not no_update: json_file = filename + ".json" - self.json_report(json_file, version=self.env.version) + self.json_report(json_file, version=self.env.version, + filters=self.json_filters['twister.json']) + if self.env.options.footprint_report is not None: + self.json_report(filename + "_footprint.json", version=self.env.version, + filters=self.json_filters['footprint.json']) self.xunit_report(json_file, filename + ".xml", full_report=False) self.xunit_report(json_file, filename + "_report.xml", full_report=True) self.xunit_report_suites(json_file, filename + "_suite_report.xml") @@ -582,9 +637,15 @@ def target_report(self, json_file, outdir, suffix): for platform in platforms.values(): if suffix: filename = os.path.join(outdir,"{}_{}.xml".format(platform.normalized_name, suffix)) - json_platform_file = os.path.join(outdir,"{}_{}.json".format(platform.normalized_name, suffix)) + json_platform_file = os.path.join(outdir,"{}_{}".format(platform.normalized_name, suffix)) else: filename = os.path.join(outdir,"{}.xml".format(platform.normalized_name)) - json_platform_file = os.path.join(outdir,"{}.json".format(platform.normalized_name)) + json_platform_file = os.path.join(outdir, platform.normalized_name) self.xunit_report(json_file, filename, platform.name, full_report=True) - self.json_report(json_platform_file, version=self.env.version, platform=platform.name) + self.json_report(json_platform_file + ".json", + version=self.env.version, platform=platform.name, + filters=self.json_filters['twister.json']) + if self.env.options.footprint_report is not None: + self.json_report(json_platform_file + "_footprint.json", + version=self.env.version, platform=platform.name, + filters=self.json_filters['footprint.json']) diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 7251f3f733ceba..6f723ca477c52d 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -553,6 +553,13 @@ def log_info(self, filename, inline_logs, log_testcases=False): except Exception as e: data = "Unable to read log data (%s)\n" % (str(e)) + # Remove any coverage data from the dumped logs + data = re.sub( + r"GCOV_COVERAGE_DUMP_START.*GCOV_COVERAGE_DUMP_END", + "GCOV_COVERAGE_DUMP_START\n...\nGCOV_COVERAGE_DUMP_END", + data, + flags=re.DOTALL, + ) logger.error(data) logger.info("{:-^100}".format(filename)) @@ -764,6 +771,8 @@ def cleanup_artifacts(self, additional_keep: List[str] = []): 'build.log', 'device.log', 'recording.csv', + 'rom.json', + 'ram.json', # below ones are needed to make --test-only work as well 'Makefile', 'CMakeCache.txt', @@ -1315,8 +1324,22 @@ def add_tasks_to_queue(self, pipeline, build_only=False, test_only=False, retry_ def pipeline_mgr(self, pipeline, done_queue, lock, results): - if sys.platform == 'linux': - with self.jobserver.get_job(): + try: + if sys.platform == 'linux': + with self.jobserver.get_job(): + while True: + try: + task = pipeline.get_nowait() + except queue.Empty: + break + else: + instance = task['test'] + pb = ProjectBuilder(instance, self.env, self.jobserver) + pb.duts = self.duts + pb.process(pipeline, done_queue, task, lock, results) + + return True + else: while True: try: task = pipeline.get_nowait() @@ -1327,20 +1350,10 @@ def pipeline_mgr(self, pipeline, done_queue, lock, results): pb = ProjectBuilder(instance, self.env, self.jobserver) pb.duts = self.duts pb.process(pipeline, done_queue, task, lock, results) - return True - else: - while True: - try: - task = pipeline.get_nowait() - except queue.Empty: - break - else: - instance = task['test'] - pb = ProjectBuilder(instance, self.env, self.jobserver) - pb.duts = self.duts - pb.process(pipeline, done_queue, task, lock, results) - return True + except Exception as e: + logger.error(f"General exception: {e}") + sys.exit(1) def execute(self, pipeline, done): lock = Lock() @@ -1360,6 +1373,11 @@ def execute(self, pipeline, done): try: for p in processes: p.join() + if p.exitcode != 0: + logger.error(f"Process {p.pid} failed, aborting execution") + for proc in processes: + proc.terminate() + sys.exit(1) except KeyboardInterrupt: logger.info("Execution interrupted") for p in processes: diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index fb0fc1d909b483..b7a46fd5008ac4 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -180,7 +180,7 @@ def testsuite_runnable(testsuite, fixtures): # command-line, then we need to run the test, not just build it. fixture = testsuite.harness_config.get('fixture') if fixture: - can_run = fixture in fixtures + can_run = fixture in map(lambda f: f.split(sep=':')[0], fixtures) return can_run diff --git a/scripts/set_assignees.py b/scripts/set_assignees.py index d2091931585921..679735414c3ed5 100755 --- a/scripts/set_assignees.py +++ b/scripts/set_assignees.py @@ -70,15 +70,12 @@ def process_pr(gh, maintainer_file, number): all_areas = set() fn = list(pr.get_files()) - manifest_change = False for changed_file in fn: if changed_file.filename in ['west.yml','submanifests/optional.yaml']: - manifest_change = True break - # one liner PRs should be trivial - if pr.commits == 1 and (pr.additions <= 1 and pr.deletions <= 1) and not manifest_change: - labels = {'Trivial'} + if pr.commits == 1 and (pr.additions <= 1 and pr.deletions <= 1): + labels = {'size: XS'} if len(fn) > 500: log(f"Too many files changed ({len(fn)}), skipping....") diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index befd384be37b14..898f7e5ababdeb 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.fixture = ['fixture1:option1', 'fixture2'] testinstance.handler.options.pytest_args = None testinstance.handler.type_str = 'native' return testinstance @@ -41,7 +42,9 @@ def test_pytest_command(testinstance: TestInstance, device_type): 'samples/hello/pytest', f'--build-dir={testinstance.build_dir}', f'--junit-xml={testinstance.build_dir}/report.xml', - f'--device-type={device_type}' + f'--device-type={device_type}', + '--twister-fixture=fixture1:option1', + '--twister-fixture=fixture2' ] command = pytest_harness.generate_command() diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py index 2aa6aa92fcb114..79825c4784639b 100644 --- a/scripts/tests/twister/test_handlers.py +++ b/scripts/tests/twister/test_handlers.py @@ -1169,6 +1169,7 @@ def mock_serial(*args, **kwargs): available_mock = mock.Mock() handler.make_device_available = available_mock handler.options = mock.Mock(timeout_multiplier=1) + twisterlib.handlers.terminate_process = mock.Mock() hardware_baud = 14400 flash_timeout = 60 @@ -1191,7 +1192,7 @@ def mock_serial(*args, **kwargs): missing_mock.assert_called_once_with('blocked', 'Serial Device Error') if terminate_ser_pty_process: - ser_pty_process.terminate.assert_called_once() + twisterlib.handlers.terminate_process.assert_called_once() ser_pty_process.communicate.assert_called_once() if make_available: @@ -1252,7 +1253,8 @@ def mock_popen(command, *args, **kwargs): (True, False, False, False, 0, True, False, None, None, ['Timed out while monitoring serial output on IPName']), (True, False, False, False, 0, False, True, - None, None, ['Process Serial PTY terminated outs: errs ']), + None, None, ["Terminating serial-pty:'Serial PTY'", + "Terminated serial-pty:'Serial PTY', stdout:'', stderr:''"]), ] @pytest.mark.parametrize( @@ -1351,6 +1353,7 @@ def mock_popen(command, *args, **kwargs): handler._update_instance_info = mock.Mock() handler._final_handle_actions = mock.Mock() handler.make_device_available = mock.Mock() + twisterlib.handlers.terminate_process = mock.Mock() handler.instance.platform.name = 'IPName' harness = mock.Mock() @@ -1728,28 +1731,29 @@ def mock_kill(pid, sig): TESTDATA_24 = [ - ('timeout', 'failed', 'Timeout'), - ('failed', 'failed', 'Failed'), - ('unexpected eof', 'failed', 'unexpected eof'), - ('unexpected byte', 'failed', 'unexpected byte'), - (None, None, 'Unknown'), + ('failed', 'timeout', 'failed', 'timeout'), + ('failed', 'Execution error', 'failed', 'Execution error'), + ('failed', 'unexpected eof', 'failed', 'unexpected eof'), + ('failed', 'unexpected byte', 'failed', 'unexpected byte'), + (None, None, None, 'Unknown'), ] @pytest.mark.parametrize( - 'out_state, expected_status, expected_reason', + '_status, _reason, expected_status, expected_reason', TESTDATA_24, ids=['timeout', 'failed', 'unexpected eof', 'unexpected byte', 'unknown'] ) def test_qemuhandler_thread_update_instance_info( mocked_instance, - out_state, + _status, + _reason, expected_status, expected_reason ): handler = QEMUHandler(mocked_instance, 'build') handler_time = 59 - QEMUHandler._thread_update_instance_info(handler, handler_time, out_state) + QEMUHandler._thread_update_instance_info(handler, handler_time, _status, _reason) assert handler.instance.execution_time == handler_time @@ -1765,6 +1769,7 @@ def test_qemuhandler_thread_update_instance_info( [None] * 60 + ['success'] * 6, 1000, False, + 'failed', 'timeout', [mock.call('1\n'), mock.call('1\n')] ), @@ -1776,6 +1781,7 @@ def test_qemuhandler_thread_update_instance_info( 100, False, 'failed', + None, [mock.call('1\n'), mock.call('1\n')] ), ( @@ -1785,6 +1791,7 @@ def test_qemuhandler_thread_update_instance_info( ['success'] * 3, 100, False, + 'failed', 'unexpected eof', [] ), @@ -1795,6 +1802,7 @@ def test_qemuhandler_thread_update_instance_info( ['success'] * 3, 100, False, + 'failed', 'unexpected byte', [] ), @@ -1806,6 +1814,7 @@ def test_qemuhandler_thread_update_instance_info( 100, False, 'success', + None, [mock.call('1\n'), mock.call('2\n'), mock.call('3\n'), mock.call('4\n')] ), ( @@ -1815,6 +1824,7 @@ def test_qemuhandler_thread_update_instance_info( [None] * 3 + ['success'] * 7, 100, False, + 'failed', 'timeout', [mock.call('1\n'), mock.call('2\n')] ), @@ -1826,13 +1836,14 @@ def test_qemuhandler_thread_update_instance_info( (n for n in [100, 100, 10000]), True, 'success', + None, [mock.call('1\n'), mock.call('2\n'), mock.call('3\n'), mock.call('4\n')] ), ] @pytest.mark.parametrize( 'content, timeout, pid, harness_states, cputime, capture_coverage,' \ - ' expected_out_state, expected_log_calls', + ' expected_status, expected_reason, expected_log_calls', TESTDATA_25, ids=[ 'timeout', @@ -1853,7 +1864,8 @@ def test_qemuhandler_thread( harness_states, cputime, capture_coverage, - expected_out_state, + expected_status, + expected_reason, expected_log_calls ): def mock_cputime(pid): @@ -1930,7 +1942,8 @@ def mocked_open(filename, *args, **kwargs): mock_thread_update_instance_info.assert_called_once_with( handler, mock.ANY, - expected_out_state + expected_status, + mock.ANY ) log_fp_mock.write.assert_has_calls(expected_log_calls) diff --git a/scripts/tests/twister/test_hardwaremap.py b/scripts/tests/twister/test_hardwaremap.py index 57c028bfea69af..65440362f69718 100644 --- a/scripts/tests/twister/test_hardwaremap.py +++ b/scripts/tests/twister/test_hardwaremap.py @@ -383,6 +383,9 @@ def mock_iterdir(path): Path(path / 'basic-file2-link') ] + def mock_exists(path): + return True + mocked_hm.manufacturer = ['dummy manufacturer', 'Texas Instruments'] mocked_hm.runner_mapping = { 'dummy runner': ['product[0-9]+',], @@ -433,7 +436,9 @@ def mock_iterdir(path): mock.patch('twisterlib.hardwaremap.Path.resolve', autospec=True, side_effect=mock_resolve), \ mock.patch('twisterlib.hardwaremap.Path.iterdir', - autospec=True, side_effect=mock_iterdir): + autospec=True, side_effect=mock_iterdir), \ + mock.patch('twisterlib.hardwaremap.Path.exists', + autospec=True, side_effect=mock_exists): mocked_hm.scan(persistent) assert sorted([d.__repr__() for d in mocked_hm.detected]) == \ diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 6a92a4ffba0c10..ddebb2c5b2e9ff 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -345,6 +345,7 @@ def test_pytest__generate_parameters_for_hardware(tmp_path, pty_value, hardware_ hardware.baud = 115200 hardware.runner = "runner" hardware.runner_params = ["--runner-param1", "runner-param2"] + hardware.fixtures = ['fixture1:option1', 'fixture2'] options = handler.options options.west_flash = "args" @@ -386,6 +387,8 @@ def test_pytest__generate_parameters_for_hardware(tmp_path, pty_value, hardware_ assert '--pre-script=pre_script' in command assert '--post-flash-script=post_flash_script' in command assert '--post-script=post_script' in command + assert '--twister-fixture=fixture1:option1' in command + assert '--twister-fixture=fixture2' in command def test__update_command_with_env_dependencies(): @@ -464,8 +467,8 @@ def test_get_harness(name): ("", "PASS - test_example in 0 seconds", [], "passed", True, None), ("", "SKIP - test_example in 0 seconds", [], "skipped", True, None), ("", "FAIL - test_example in 0 seconds", [], "failed", True, None), - ("not a ztest and no state for test_id", "START - test_testcase", [], "passed", False, "passed"), - ("not a ztest and no state for test_id", "START - test_testcase", [], "failed", False, "failed")] + ("not a ztest and no state for test_id", "START - test_testcase", [], "passed", False, "passed"), + ("not a ztest and no state for test_id", "START - test_testcase", [], "failed", False, "failed")] @pytest.mark.parametrize( "exp_out, line, exp_suite_name, exp_status, ztest, state", TEST_DATA_7, diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 592d2c63042086..88ed43a87fef8b 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -2691,6 +2691,7 @@ def mock_join(): process_mock = mock.Mock() process_mock().join = mock.Mock(side_effect=mock_join) + process_mock().exitcode = 0 pipeline_mock = mock.Mock() done_mock = mock.Mock() diff --git a/scripts/tests/twister_blackbox/test_report.py b/scripts/tests/twister_blackbox/test_report.py index e116bea3da1eb5..d7aa016212777b 100644 --- a/scripts/tests/twister_blackbox/test_report.py +++ b/scripts/tests/twister_blackbox/test_report.py @@ -112,7 +112,7 @@ class TestReport: ( os.path.join(TEST_DATA, 'tests', 'one_fail_two_error_one_pass'), ['qemu_x86'], - [r'one_fail_two_error_one_pass.agnostic.group1.subgroup2 on qemu_x86 FAILED \(Failed\)', + [r'one_fail_two_error_one_pass.agnostic.group1.subgroup2 on qemu_x86 FAILED \(.*\)', r'one_fail_two_error_one_pass.agnostic.group1.subgroup3 on qemu_x86 ERROR \(Build failure\)', r'one_fail_two_error_one_pass.agnostic.group1.subgroup4 on qemu_x86 ERROR \(Build failure\)'], ) @@ -344,14 +344,25 @@ def test_log_file(self, capfd, test_path, test_platforms, out_path, file_name): assert str(sys_exit.value) == '0' @pytest.mark.parametrize( - 'test_path, expected_testcase_count', - [(os.path.join(TEST_DATA, 'tests', 'dummy'), 6),], - ids=['dummy tests'] + 'test_path, flags, expected_testcase_counts', + [ + ( + os.path.join(TEST_DATA, 'tests', 'dummy'), + ['--detailed-skipped-report'], + {'qemu_x86': 5, 'frdm_k64f': 1} + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy'), + ['--detailed-skipped-report', '--report-filtered'], + {'qemu_x86': 6, 'frdm_k64f': 6} + ), + ], + ids=['dummy tests', 'dummy tests with filtered'] ) - def test_detailed_skipped_report(self, out_path, test_path, expected_testcase_count): + def test_detailed_skipped_report(self, out_path, test_path, flags, expected_testcase_counts): test_platforms = ['qemu_x86', 'frdm_k64f'] args = ['-i', '--outdir', out_path, '-T', test_path] + \ - ['--detailed-skipped-report'] + \ + flags + \ [val for pair in zip( ['-p'] * len(test_platforms), test_platforms ) for val in pair] @@ -367,12 +378,47 @@ def test_detailed_skipped_report(self, out_path, test_path, expected_testcase_co for ts in xml_data.iter('testsuite'): testsuite_counter += 1 # Without the tested flag, filtered testcases would be missing from the report - assert len(list(ts.iter('testcase'))) == expected_testcase_count, \ - 'Not all expected testcases appear in the report.' + testcase_count = len(list(ts.iter('testcase'))) + expected_tc_count = expected_testcase_counts[ts.get('name')] + assert testcase_count == expected_tc_count, \ + f'Not all expected testcases appear in the report.' \ + f' (In {ts.get("name")}, expected {expected_tc_count}, got {testcase_count}.)' assert testsuite_counter == len(test_platforms), \ 'Some platforms are missing from the XML report.' + @pytest.mark.parametrize( + 'test_path, report_filtered, expected_filtered_count', + [ + (os.path.join(TEST_DATA, 'tests', 'dummy'), False, 0), + (os.path.join(TEST_DATA, 'tests', 'dummy'), True, 4), + ], + ids=['no filtered', 'with filtered'] + ) + def test_report_filtered(self, out_path, test_path, report_filtered, expected_filtered_count): + test_platforms = ['qemu_x86', 'frdm_k64f'] + args = ['-i', '--outdir', out_path, '-T', test_path] + \ + (['--report-filtered'] if report_filtered else []) + \ + [val for pair in zip( + ['-p'] * len(test_platforms), test_platforms + ) for val in pair] + + with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ + pytest.raises(SystemExit) as sys_exit: + self.loader.exec_module(self.twister_module) + + assert str(sys_exit.value) == '0' + + with open(os.path.join(out_path, 'twister.json')) as f: + j = json.load(f) + + testsuites = j.get('testsuites') + assert testsuites, 'No testsuites found.' + statuses = [testsuite.get('status') for testsuite in testsuites] + filtered_status_count = statuses.count("filtered") + assert filtered_status_count == expected_filtered_count, \ + f'Expected {expected_filtered_count} filtered statuses, got {filtered_status_count}.' + def test_enable_size_report(self, out_path): test_platforms = ['qemu_x86', 'frdm_k64f'] path = os.path.join(TEST_DATA, 'tests', 'dummy', 'device', 'group') diff --git a/scripts/tests/twister_blackbox/test_runner.py b/scripts/tests/twister_blackbox/test_runner.py index 97e36d8b8a633c..1e5f10683153d0 100644 --- a/scripts/tests/twister_blackbox/test_runner.py +++ b/scripts/tests/twister_blackbox/test_runner.py @@ -45,15 +45,15 @@ class TestRunner: ['qemu_x86', 'qemu_x86_64', 'frdm_k64f'], { 'selected_test_scenarios': 3, - 'selected_test_instances': 9, - 'skipped_configurations': 3, - 'skipped_by_static_filter': 3, + 'selected_test_instances': 6, + 'skipped_configurations': 0, + 'skipped_by_static_filter': 0, 'skipped_at_runtime': 0, 'passed_configurations': 4, 'failed_configurations': 0, 'errored_configurations': 0, 'executed_test_cases': 8, - 'skipped_test_cases': 5, + 'skipped_test_cases': 0, 'platform_count': 0, 'executed_on_platform': 4, 'only_built': 2 @@ -622,7 +622,7 @@ def test_only_failed(self, capfd, out_path, test_path, test_platforms, expected) assert re.search( - r'one_fail_one_pass.agnostic.group1.subgroup2 on qemu_x86 failed \(Failed\)', err) + r'one_fail_one_pass.agnostic.group1.subgroup2 on qemu_x86 failed \(.*\)', err) pass_search = re.search(pass_regex, err, re.MULTILINE) diff --git a/scripts/utils/migrate_posix_kconfigs.py b/scripts/utils/migrate_posix_kconfigs.py new file mode 100644 index 00000000000000..ea8eed2d2f8e50 --- /dev/null +++ b/scripts/utils/migrate_posix_kconfigs.py @@ -0,0 +1,137 @@ +""" +Utility script to migrate Zephyr-based projects to normative POSIX Kconfig options. + +This script should be used for migrating from versions of Zephyr older than v3.7.0 to Zephyr +version v3.7.0 or later. + +Usage:: + + python $ZEPHYR_BASE/scripts/utils/migrate_posix_kconfigs.py -r root_path + +The utility will process c, cpp, h, hpp, rst, conf, CMakeLists.txt, +yml, yaml and Kconfig files. + + +Copyright (c) 2022 Nordic Semiconductor ASA +Copyright (c) 2024 Tenstorrent AI ULC +SPDX-License-Identifier: Apache-2.0 +""" + +import argparse +from pathlib import Path +import re +import sys + + +ZEPHYR_BASE = Path(__file__).parents[2] + +FILE_PATTERNS = ( + r".+\.c", r".+\.cpp", r".+\.hpp", r".+\.h", r".+\.rst", r".+\.conf", + r".+\.yml", r".+\.yaml", r"CMakeLists.txt", r"Kconfig(\..+)?" +) + +REPLACEMENTS = { + "EVENTFD_MAX": "ZVFS_EVENTFD_MAX", + "FNMATCH": "POSIX_C_LIB_EXT", + "GETENTROPY": "POSIX_C_LIB_EXT", + "GETOPT": "POSIX_C_LIB_EXT", + "MAX_PTHREAD_COUNT": "POSIX_THREAD_THREADS_MAX", + "MAX_PTHREAD_KEY_COUNT": "POSIX_THREAD_KEYS_MAX", + "MAX_TIMER_COUNT": "POSIX_TIMER_MAX", + "MSG_COUNT_MAX": "POSIX_MQ_OPEN_MAX", + "POSIX_CLOCK": "POSIX_TIMERS", + "POSIX_CONFSTR": "POSIX_SINGLE_PROCESS", + "POSIX_ENV": "POSIX_SINGLE_PROCESS", + "POSIX_FS": "POSIX_FILE_SYSTEM", + "POSIX_LIMITS_RTSIG_MAX": "POSIX_RTSIG_MAX", + "POSIX_MAX_FDS": "ZVFS_OPEN_MAX", + "POSIX_MAX_OPEN_FILES": "ZVFS_OPEN_MAX", + "POSIX_MQUEUE": "POSIX_MESSAGE_PASSING", + "POSIX_PUTMSG": "XOPEN_STREAMS", + "POSIX_SIGNAL": "POSIX_SIGNALS", + "POSIX_SYSCONF": "POSIX_SINGLE_PROCESS", + "POSIX_SYSLOG": "XSI_SYSTEM_LOGGING", + "POSIX_UNAME": "POSIX_SINGLE_PROCESS", + "PTHREAD": "POSIX_THREADS", + "PTHREAD_BARRIER": "POSIX_BARRIERS", + "PTHREAD_COND": "POSIX_THREADS", + "PTHREAD_IPC": "POSIX_THREADS", + "PTHREAD_KEY": "POSIX_THREADS", + "PTHREAD_MUTEX": "POSIX_THREADS", + "PTHREAD_RWLOCK": "POSIX_READER_WRITER_LOCKS", + "PTHREAD_SPINLOCK": "POSIX_SPIN_LOCKS", + "TIMER": "POSIX_TIMERS", + "TIMER_DELAYTIMER_MAX": "POSIX_DELAYTIMER_MAX", + "SEM_NAMELEN_MAX": "POSIX_SEM_NAME_MAX", + "SEM_VALUE_MAX": "POSIX_SEM_VALUE_MAX", +} + +MESSAGES = { + "POSIX_CLOCK": + "POSIX_CLOCK is a one-to-many replacement. If this simple substitution is not " + "sufficient, it's best to try a combination of POSIX_CLOCK_SELECTION, POSIX_CPUTIME, " + "POSIX_MONOTONIC_CLOCK, POSIX_TIMERS, and POSIX_TIMEOUTS.", + "POSIX_MAX_FDS": + "A read-only version of this symbol is POSIX_OPEN_MAX, which is of course, the standard " + "symbol. ZVFS_OPEN_MAX may be set by the user. Consider using POSIX_MAX_FDS if the " + "use-case is read-only.", +} + + +def process_file(path): + modified = False + output = [] + + try: + with open(path) as f: + lines = f.readlines() + + for line in lines: + longest = "" + length = 0 + for m in REPLACEMENTS: + if re.match(".*" + m + ".*", line) and len(m) > length: + length = len(m) + longest = m + + if length != 0: + modified = True + line = line.replace(longest, REPLACEMENTS[longest]) + msg = MESSAGES.get(longest) + if msg: + print( + f"Notice: {longest} -> {REPLACEMENTS[longest]}: {msg}") + + output.append(line) + + if modified is False: + return + + with open(path, "w") as f: + f.writelines(output) + + except UnicodeDecodeError: + print(f"Unable to read lines from {path}", file=sys.stderr) + except Exception as e: + print(f"Failed with exception {e}", e) + + +def process_tree(project): + for p in project.glob("**/*"): + for fp in FILE_PATTERNS: + cfp = re.compile(".+/" + fp + "$") + if re.match(cfp, str(p)) is not None: + process_file(p) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument( + "-r", + "--root", + type=Path, + required=True, + help="Zephyr-based project path") + args = parser.parse_args() + + process_tree(args.root) diff --git a/scripts/west_commands/blobs.py b/scripts/west_commands/blobs.py index d501416f54014f..d23729c9d90fc5 100644 --- a/scripts/west_commands/blobs.py +++ b/scripts/west_commands/blobs.py @@ -81,7 +81,15 @@ def do_add_parser(self, parser_adder): def get_blobs(self, args): blobs = [] modules = args.modules - for module in zephyr_module.parse_modules(ZEPHYR_BASE, self.manifest): + all_modules = zephyr_module.parse_modules(ZEPHYR_BASE, self.manifest) + all_names = [m.meta.get('name', None) for m in all_modules] + + unknown = set(modules) - set(all_names) + + if len(unknown): + log.die(f'Unknown module(s): {unknown}') + + for module in all_modules: # Filter by module module_name = module.meta.get('name', None) if len(modules) and module_name not in modules: diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index f411f56cad3ed4..10e740a4230f8b 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -130,6 +130,8 @@ class BuildConfiguration: Kconfig configuration values are available (parsed from .config).''' + config_prefix = 'CONFIG' + def __init__(self, build_dir: str): self.build_dir = build_dir self.options: Dict[str, Union[str, int]] = {} @@ -153,8 +155,9 @@ def getboolean(self, option): def _parse(self): filename = self.path - opt_value = re.compile('^(?P